LocalizedMessages.java
package top.infra.localization;
import org.reflections.Reflections;
import org.springframework.context.i18n.LocaleContextHolder;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import top.infra.core.ErrorMessage;
/**
* Created by zhuowan on 2018/3/30 18:04.
* Description:
*/
public class LocalizedMessages {
private transient static final Map<MessageLocale, Map<String, String>> messageCache;
private static boolean initialized = false;
static {
messageCache = new HashMap<>();
init();
}
/**
* 1. 第一步加载所有的locales及所有的messages
* 2. 获取message优先级:
* priority 1: Forced 强制加载的类型message
* priority 2: 指定类型的message类型
* priority 3: 默认的message类型 (目前把US当作默认类型)
* priority 4: 抛出异常
*/
public static String getMessageByLocale(final ErrorMessage message, final Locale locale) {
String resultMsg = getMessageByLocaleAndMessage(message, getLocale(locale));
if (resultMsg != null) {
return resultMsg;
}
throw new RuntimeException("Invalid common locale message usage");
}
/**
* 初始化所有message信息
*/
private static void init() {
if (!initialized) {
final Reflections reflections = new Reflections();
final Set<Class<?>> bundles = reflections.getTypesAnnotatedWith(LocalizedMessageBundle.class);
for (final MessageLocale locale : MessageLocale.values()) { // all locales
final Map<String, String> enumConstants = new HashMap<>();
for (final Class bundle : bundles) {
final LocalizedMessageBundle annotation = (LocalizedMessageBundle) bundle.getAnnotation(LocalizedMessageBundle.class);
final MessageLocale bundleLocale = annotation.value();
if (locale == bundleLocale) {
arrayToMap(enumConstants, bundle.getEnumConstants());
}
}
messageCache.putIfAbsent(locale, enumConstants);
}
initialized = true;
}
}
private static void arrayToMap(final Map<String, String> map, final Object[] enums) {
if (map != null && enums != null) {
for (final Object enu : enums) {
final ErrorMessage message = (ErrorMessage) enu;
map.putIfAbsent(message.getName(), message.getText());
}
}
}
private static MessageLocale getLocale(final Locale locale) {
final String country = locale != null ? locale.getCountry() : LocaleContextHolder.getLocale().getCountry();
return MessageLocale.of(country);
}
private static String getMessageByLocaleAndMessage(ErrorMessage message, MessageLocale messageLocale) {
//priority 1 Forced messageLocale Message
String finalMessage = messageCache.get(MessageLocale.FORCED).get(message.getName());
if (finalMessage == null) {
//priority 2 Specific messageLocale message
finalMessage = messageCache.get(messageLocale).get(message.getName());
if (finalMessage == null) {
//priority 3 Default message
finalMessage = messageCache.get(MessageLocale.DEFAULT).get(message.getName());
}
}
return finalMessage;
}
}