001package org.hl7.fhir.utilities.i18n; 002 003import java.text.MessageFormat; 004import java.util.Locale; 005import java.util.Objects; 006import java.util.ResourceBundle; 007 008 009/** 010 * Handles the locale, ResourceBundle and String formatting for i18n 011 * This abstract class should be extended when implementing a IWorkerContext Interface. 012 */ 013public abstract class I18nBase { 014 015 private Locale locale; 016 private ResourceBundle i18nMessages; 017 private boolean warnAboutMissingMessages = true; 018 019 public Locale getLocale() { 020 if (Objects.nonNull(locale)) { 021 return locale; 022 } else { 023 return Locale.US; 024 } 025 } 026 027 public void setLocale(Locale locale) { 028 this.locale = locale; 029 setValidationMessageLanguage(getLocale()); 030 } 031 032 /** 033 * Verifies if a {@link ResourceBundle} has been loaded for the current {@link Locale}. If not, it triggers a load. 034 */ 035 private void checkResourceBundleIsLoaded() { 036 if (i18nMessages == null) { 037 setValidationMessageLanguage(getLocale()); 038 } 039 } 040 041 /** 042 * Checks the loaded {@link ResourceBundle} to see if the passed in message exists with the current loaded {@link Locale}. 043 * If no {@link Locale} is currently loaded, it will load the {@link Locale} (default {@link Locale#US} is none is 044 * specified), and search. 045 * @param message The {@link String} message to search for within the current {@link Locale} 046 * @return {@link Boolean#TRUE} if the message exists within the loaded {@link Locale}. 047 */ 048 private boolean messageExistsForLocale(String message, boolean hasArgs) { 049 checkResourceBundleIsLoaded(); 050 if (!i18nMessages.containsKey(message)) { 051 if (warnAboutMissingMessages && (hasArgs || !message.contains(" "))) { 052 System.out.println("Attempting to localize message " + message + ", but no such equivalent message exists for" + 053 " the local " + getLocale()); 054 } 055 } 056 return i18nMessages.containsKey(message); 057 } 058 059 /** 060 * Formats the given message, if needed, with the passed in message arguments. 061 * @param theMessage Base message to format. 062 * @param theMessageArguments Placeholder arguments, if needed. 063 * @return The formatted, internationalized, {@link String} 064 */ 065 public String formatMessage(String theMessage, Object... theMessageArguments) { 066 String message = theMessage; 067 if (messageExistsForLocale(theMessage, (theMessageArguments != null && theMessageArguments.length > 0))) { 068 if (Objects.nonNull(theMessageArguments) && theMessageArguments.length > 0) { 069 message = MessageFormat.format(i18nMessages.getString(theMessage), theMessageArguments); 070 } else { 071 message = i18nMessages.getString(theMessage); 072 } 073 } 074 return message; 075 } 076 077 /** 078 * Loads the corresponding {@link ResourceBundle} for the passed in {@link Locale}. 079 * @param locale {@link Locale} to load resources for. 080 */ 081 public void setValidationMessageLanguage(Locale locale) { 082 i18nMessages = ResourceBundle.getBundle("Messages", locale); 083 } 084 085 public boolean isWarnAboutMissingMessages() { 086 return warnAboutMissingMessages; 087 } 088 089 public void setWarnAboutMissingMessages(boolean warnAboutMissingMessages) { 090 this.warnAboutMissingMessages = warnAboutMissingMessages; 091 } 092 093 094}