1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.i18nsystem;
35
36 import info.magnolia.cms.i18n.MessagesManager;
37 import org.apache.commons.lang.StringUtils;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import javax.inject.Singleton;
41 import java.util.Locale;
42 import java.util.Properties;
43 import java.util.Arrays;
44
45
46
47
48
49
50
51
52
53
54 @Singleton
55 public class TranslationServiceImpl implements TranslationService {
56 private static final Logger log = LoggerFactory.getLogger(TranslationServiceImpl.class);
57 private final DefaultMessageBundlesLoader messageBundles;
58
59 public TranslationServiceImpl() {
60 this.messageBundles = setupMessageBundles();
61 }
62
63 protected DefaultMessageBundlesLoader setupMessageBundles() {
64 return new DefaultMessageBundlesLoader();
65 }
66
67 @Override
68 public String translate(LocaleProvider localeProvider, String[] keys) {
69 return translate(localeProvider, null, keys);
70 }
71
72 @Override
73 public String translate(LocaleProvider localeProvider, String basename, String[] keys) {
74 final Locale locale = localeProvider.getLocale();
75 if (locale == null) {
76 throw new IllegalArgumentException("Locale can't be null");
77 }
78 if (keys == null || keys.length < 1) {
79 throw new IllegalArgumentException("Keys can't be null or empty");
80 }
81
82 if (basename != null) {
83 log.debug("Got an explicit basename ({}) for keys {}", basename, Arrays.asList(keys));
84 }
85
86 final String message = lookUpKeyUntilFound(keys, locale, basename);
87 if (message != null) {
88 return message;
89 } else {
90 return handleUnknownKey(locale, basename, keys);
91 }
92 }
93
94 private String lookUpKeyUntilFound(final String[] keys, final Locale locale, final String basename) {
95 String message = null;
96
97 if (StringUtils.isNotBlank(basename)) {
98 log.debug("Looking up key [{}] with basename [{}] and Locale [{}] - legacy method", keys[0], basename, locale);
99 message = legacyLookup(locale, basename, keys[0]);
100 }
101
102 if (message == null) {
103 log.debug("Looking up in global i18n message bundle with key [{}] and Locale [{}]", Arrays.asList(keys), locale);
104 message = doGetMessage(keys, locale);
105 }
106
107 if (message == null) {
108 final String country = locale.getCountry();
109 if (country != null) {
110 final Locale newLocale = new Locale(locale.getLanguage(), country);
111 message = doGetMessage(keys, newLocale);
112 }
113 }
114
115 if (message == null) {
116 final Locale newLocale = new Locale(locale.getLanguage());
117 message = doGetMessage(keys, newLocale);
118 }
119
120 if (message == null) {
121 message = doGetMessage(keys, getFallbackLocale());
122 }
123
124 if (message == null) {
125 message = handleUnknownKey(locale, basename, keys);
126 }
127
128 return message;
129 }
130
131 protected String handleUnknownKey(Locale locale, String basename, String[] keys) {
132
133 if (log.isDebugEnabled()) {
134 log.debug("No translation found for any of {} with locale {} {}", Arrays.asList(keys), locale, (basename != null ? " and basename " + basename : ""));
135 }
136 return keys[0];
137 }
138
139
140
141
142 private String legacyLookup(Locale locale, String basename, String key) {
143
144 String message = MessagesManager.getMessages(basename, locale).get(key);
145 if (legacyMessageNotFound(message)) {
146 message = MessagesManager.getMessages(MessagesManager.DEFAULT_BASENAME, locale).get(key);
147 }
148 if (legacyMessageNotFound(message)) {
149
150 return null;
151 } else {
152 return message;
153 }
154 }
155
156 private boolean legacyMessageNotFound(final String message) {
157 return message == null || message.startsWith("???");
158 }
159
160 private String doGetMessage(String[] keys, Locale locale) {
161 final Properties properties = messageBundles.getMessages().get(locale);
162 if (properties != null) {
163 for (String key : keys) {
164 final String message = properties.getProperty(key);
165 if (message != null) {
166 return message;
167 }
168 }
169 }
170 return null;
171 }
172
173
174 private Locale getFallbackLocale() {
175 return MessagesManager.getInstance().getDefaultLocale();
176 }
177 }