View Javadoc
1   package top.infra.localization;
2   
3   import org.reflections.Reflections;
4   import org.springframework.context.i18n.LocaleContextHolder;
5   
6   import java.util.HashMap;
7   import java.util.Locale;
8   import java.util.Map;
9   import java.util.Set;
10  
11  import top.infra.core.ErrorMessage;
12  
13  /**
14   * Created by zhuowan on 2018/3/30 18:04.
15   * Description:
16   */
17  public class LocalizedMessages {
18  
19    private transient static final Map<MessageLocale, Map<String, String>> messageCache;
20    private static boolean initialized = false;
21  
22    static {
23      messageCache = new HashMap<>();
24      init();
25    }
26  
27    /**
28     * 1. 第一步加载所有的locales及所有的messages
29     * 2. 获取message优先级:
30     * priority 1: Forced 强制加载的类型message
31     * priority 2: 指定类型的message类型
32     * priority 3: 默认的message类型 (目前把US当作默认类型)
33     * priority 4: 抛出异常
34     */
35    public static String getMessageByLocale(final ErrorMessage message, final Locale locale) {
36      String resultMsg = getMessageByLocaleAndMessage(message, getLocale(locale));
37      if (resultMsg != null) {
38        return resultMsg;
39      }
40      throw new RuntimeException("Invalid common locale message usage");
41    }
42  
43    /**
44     * 初始化所有message信息
45     */
46    private static void init() {
47      if (!initialized) {
48        final Reflections reflections = new Reflections();
49        final Set<Class<?>> bundles = reflections.getTypesAnnotatedWith(LocalizedMessageBundle.class);
50        for (final MessageLocale locale : MessageLocale.values()) { // all locales
51          final Map<String, String> enumConstants = new HashMap<>();
52          for (final Class bundle : bundles) {
53            final LocalizedMessageBundle annotation = (LocalizedMessageBundle) bundle.getAnnotation(LocalizedMessageBundle.class);
54            final MessageLocale bundleLocale = annotation.value();
55            if (locale == bundleLocale) {
56              arrayToMap(enumConstants, bundle.getEnumConstants());
57            }
58          }
59          messageCache.putIfAbsent(locale, enumConstants);
60        }
61        initialized = true;
62      }
63    }
64  
65    private static void arrayToMap(final Map<String, String> map, final Object[] enums) {
66      if (map != null && enums != null) {
67        for (final Object enu : enums) {
68          final ErrorMessage message = (ErrorMessage) enu;
69          map.putIfAbsent(message.getName(), message.getText());
70        }
71      }
72    }
73  
74    private static MessageLocale getLocale(final Locale locale) {
75      final String country = locale != null ? locale.getCountry() : LocaleContextHolder.getLocale().getCountry();
76      return MessageLocale.of(country);
77    }
78  
79    private static String getMessageByLocaleAndMessage(ErrorMessage message, MessageLocale messageLocale) {
80      //priority 1 Forced messageLocale Message
81      String finalMessage = messageCache.get(MessageLocale.FORCED).get(message.getName());
82      if (finalMessage == null) {
83        //priority 2 Specific messageLocale message
84        finalMessage = messageCache.get(messageLocale).get(message.getName());
85        if (finalMessage == null) {
86          //priority 3 Default message
87          finalMessage = messageCache.get(MessageLocale.DEFAULT).get(message.getName());
88        }
89      }
90      return finalMessage;
91    }
92  }