/** * Returns a formatted message given a label identifier. Recognizes line continuation with * backslash characters. * * @param id A label identifier. * @param locale The locale. * @param args Optional replaceable parameters. * @return The formatted label. */ public static String getLabel(String id, Locale locale, Object... args) { if (id.startsWith("@")) { id = id.substring(1); } return Localizer.getMessage(id, locale, args); }
/** * Returns the user's time zone. * * @return The user's time zone. */ public static TimeZone getLocalTimeZone() { return Localizer.getTimeZone(); }
/** * Formats a message. If the message begins with "@", the remainder is assumed to be a label * name that is resolved. * * @param msg Message to format or, if starts with "@", a label reference. * @param locale Optional locale * @param args Optional replaceable parameters. * @return The formatted message. */ public static String formatMessage(String msg, Locale locale, Object... args) { if (msg == null || msg.isEmpty()) { return msg; } String message = msg.startsWith("@") ? getLabel(msg, locale, args) : null; if (message == null && args != null && args.length > 0) { message = String.format(locale == null ? Localizer.getDefaultLocale() : locale, msg, args); } return message == null ? msg : message; }
/** * The message source will search for "messages*.properties" files first in the WEB-INF folder, * then anywhere within the classpath. This means that entries in the former will take * precedence over similar entries found in the classpath. Thus, entries placed in any * "message*.properties" files under the WEB-INF folder will override entries declared * elsewhere. */ private ClasspathMessageSource() { super(); setBasenames("WEB-INF/messages", "classpath*:/**/messages"); setDefaultEncoding(StandardCharsets.UTF_8.name()); Localizer.registerMessageSource((id, locale, args) -> { return getMessage(id, args, locale); }); }
/** * Initialize the Localizer. */ public static void init() { Localizer.setLocaleResolver(() -> { return LocaleContextHolder.getLocale(); }); Localizer.setTimeZoneResolver(() -> { TimeZone tz = null; Page page = ExecutionContext.getPage(); Integer offset = page == null ? null : page.getBrowserInfo("timezoneOffset", Integer.class); if (offset != null) { String id = "GMT" + (offset < 0 ? "-" : "+") + "%02d:%02d"; offset = Math.abs(offset); id = String.format(id, offset / 60, offset % 60); tz = TimeZone.getTimeZone(id); } return tz == null ? TimeZone.getDefault() : tz; }); }
/** * Make <code>get</code> locale-aware. */ @Override public HelpModule get(String key) { key = HelpModule.getLocalizedId(key, Localizer.getDefaultLocale()); while (!key.isEmpty()) { HelpModule helpModule = super.get(key); if (helpModule != null) { return helpModule; } int i = key.lastIndexOf('_'); key = i < 0 ? "" : key.substring(0, i); } return null; }
@Test public void testBundle() { Localizer.registerMessageSource(new BundleMessageSource()); Locale locale1 = new Locale("en"); Locale locale2 = new Locale("fr"); assertEquals("keyboard", StrUtil.getLabel("message.test1", locale1)); assertEquals("clavier", StrUtil.getLabel("message.test1", locale2)); }
@Override public String resolveMessage(ITemplateContext context, Class<?> origin, String key, Object[] messageParameters) { return Localizer.getMessage(key, context.getLocale(), messageParameters); }
/** * Returns a formatted message given a label identifier. Recognizes line continuation with * backslash characters. * * @param id A label identifier. * @param locale The locale. If null, uses the default locale. * @param args Optional replaceable parameters. * @return The formatted label. */ public static String getMessage(String id, Locale locale, Object... args) { locale = locale == null ? getDefaultLocale() : locale; for (IMessageSource messageSource : messageSources) { try { return messageSource.getMessage(id, locale, args).replace("\\\n", ""); } catch (Exception e) { // Ignore and try next message source. } } // Failing resolution, just return null. log.warn(() -> "Label not found for identifier: " + id); return null; }
/** * Converts day, month, year and time parameters to a date. * * @param day Day of month. * @param month Month (1=January, etc.) * @param year Year (4 digit). * @param hr Hour of day. * @param min Minutes past the hour. * @param sec Seconds past the minute. * @return Date instance. */ public static Date toDate(int day, int month, int year, int hr, int min, int sec) { Calendar cal = Calendar.getInstance(Localizer.getTimeZone()); cal.set(year, month - 1, day, hr, min, sec); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); }
@Override protected Object handleGetObject(String key) { return Localizer.getMessage(key, getLocale()); }