package ameba.i18n;
import ameba.Ameba;
import ameba.core.Requests;
import ameba.util.ClassUtils;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import java.text.MessageFormat;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* <p>Messages class.</p>
*
* @author icode
*/
public class Messages {
/**
* Constant <code>BUNDLE_DIR="conf/messages/"</code>
*/
public static final String BUNDLE_DIR = "conf/messages/";
/**
* Constant <code>BUNDLE_NAME="BUNDLE_DIR + message"</code>
*/
public static final String BUNDLE_NAME = BUNDLE_DIR + "message";
private static final Table<String, Locale, ResourceBundle> RESOURCE_BUNDLES = HashBasedTable.create();
private static final MultiResourceBundleControl BUNDLE_CONTROL = new MultiResourceBundleControl();
private Messages() {
}
/**
* <p>get.</p>
*
* @param key a {@link java.lang.String} object.
* @param args a {@link java.lang.Object} object.
* @return a {@link java.lang.String} object.
*/
public static String get(String key, Object... args) {
return get(BUNDLE_NAME, key, args);
}
/**
* <p>get.</p>
*
* @param locale a {@link java.util.Locale} object.
* @param key a {@link java.lang.String} object.
* @param args a {@link java.lang.Object} object.
* @return a {@link java.lang.String} object.
*/
public static String get(Locale locale, String key, Object... args) {
return get(BUNDLE_NAME, getLocale(locale), key, args);
}
/**
* <p>get.</p>
*
* @param bundleName a {@link java.lang.String} object.
* @param key a {@link java.lang.String} object.
* @param args an array of {@link java.lang.Object} objects.
* @return a {@link java.lang.String} object.
*/
public static String get(String bundleName, String key, Object[] args) {
return get(bundleName, getLocale(), key, args);
}
private static Locale getLocale(Locale locale) {
if (locale == null) {
return getLocale();
}
return locale;
}
private static Locale getLocale() {
Locale locale = null;
try {
List<Locale> acceptableLanguages = Requests.getAcceptableLanguages();
if (acceptableLanguages != null && acceptableLanguages.size() > 0) {
locale = acceptableLanguages.get(0);
}
} catch (Exception e) {
// no op
}
if (locale == null) {
locale = Locale.getDefault();
}
return locale;
}
/**
* <p>getResourceBundle.</p>
*
* @param bundleName a {@link java.lang.String} object.
* @param locale a {@link java.util.Locale} object.
* @return a {@link java.util.ResourceBundle} object.
*/
public static ResourceBundle getResourceBundle(String bundleName, Locale locale) {
ResourceBundle bundle = null;
boolean isDev = false;
if (Ameba.getApp() != null) {
isDev = Ameba.getApp().getMode().isDev();
BUNDLE_CONTROL.noCache = isDev;
}
if (!isDev) {
bundle = RESOURCE_BUNDLES.get(bundleName, locale);
}
if (bundle == null) {
try {
bundle = ResourceBundle.getBundle(
bundleName,
locale,
ClassUtils.getContextClassLoader(),
BUNDLE_CONTROL
);
} catch (MissingResourceException e) {
// no op
}
}
if (bundle != null && !isDev) {
RESOURCE_BUNDLES.put(bundleName, locale, bundle);
}
return bundle;
}
/**
* <p>get.</p>
*
* @param bundleName a {@link java.lang.String} object.
* @param locale a {@link java.util.Locale} object.
* @param key a {@link java.lang.String} object.
* @param args a {@link java.lang.Object} object.
* @return a {@link java.lang.String} object.
*/
public static String get(String bundleName, Locale locale, String key, Object... args) {
try {
ResourceBundle bundle = getResourceBundle(bundleName, locale);
if (bundle == null) {
return getDefaultMessage(key, args);
}
if (key == null) {
key = "undefined";
}
String msg;
try {
msg = bundle.getString(key);
} catch (MissingResourceException e) {
// notice that this may throw a MissingResourceException of its own (caught below)
try {
msg = bundle.getString("undefined");
} catch (MissingResourceException ex) {
return getDefaultMessage(key, args);
}
}
return MessageFormat.format(msg, args);
} catch (MissingResourceException e) {
return getDefaultMessage(key, args);
}
}
private static String getDefaultMessage(String key, Object... args) {
StringBuilder sb = new StringBuilder();
sb.append("[failed to localize] ");
sb.append(key);
if (args != null && args.length > 0) {
sb.append('(');
for (int i = 0; i < args.length; ++i) {
if (i != 0) {
sb.append(", ");
}
sb.append(String.valueOf(args[i]));
}
sb.append(')');
}
return sb.toString();
}
}