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
15
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
29
30
31
32
33
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
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()) {
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
81 String finalMessage = messageCache.get(MessageLocale.FORCED).get(message.getName());
82 if (finalMessage == null) {
83
84 finalMessage = messageCache.get(messageLocale).get(message.getName());
85 if (finalMessage == null) {
86
87 finalMessage = messageCache.get(MessageLocale.DEFAULT).get(message.getName());
88 }
89 }
90 return finalMessage;
91 }
92 }