1
14
15 package com.liferay.portal.language;
16
17 import com.liferay.portal.kernel.exception.SystemException;
18 import com.liferay.portal.kernel.language.Language;
19 import com.liferay.portal.kernel.language.LanguageWrapper;
20 import com.liferay.portal.kernel.log.Log;
21 import com.liferay.portal.kernel.log.LogFactoryUtil;
22 import com.liferay.portal.kernel.util.GetterUtil;
23 import com.liferay.portal.kernel.util.JavaConstants;
24 import com.liferay.portal.kernel.util.LocaleUtil;
25 import com.liferay.portal.kernel.util.ParamUtil;
26 import com.liferay.portal.kernel.util.PropsKeys;
27 import com.liferay.portal.kernel.util.StringPool;
28 import com.liferay.portal.kernel.util.StringUtil;
29 import com.liferay.portal.kernel.util.Time;
30 import com.liferay.portal.kernel.util.Validator;
31 import com.liferay.portal.model.CompanyConstants;
32 import com.liferay.portal.model.Portlet;
33 import com.liferay.portal.security.auth.CompanyThreadLocal;
34 import com.liferay.portal.service.PortletLocalServiceUtil;
35 import com.liferay.portal.theme.ThemeDisplay;
36 import com.liferay.portal.util.CookieKeys;
37 import com.liferay.portal.util.PortalUtil;
38 import com.liferay.portal.util.PortletKeys;
39 import com.liferay.portal.util.PrefsPropsUtil;
40 import com.liferay.portal.util.PropsValues;
41 import com.liferay.portal.util.WebKeys;
42 import com.liferay.portlet.PortletConfigFactory;
43
44 import java.text.MessageFormat;
45
46 import java.util.HashMap;
47 import java.util.HashSet;
48 import java.util.Locale;
49 import java.util.Map;
50 import java.util.MissingResourceException;
51 import java.util.ResourceBundle;
52 import java.util.Set;
53 import java.util.concurrent.ConcurrentHashMap;
54
55 import javax.portlet.PortletConfig;
56 import javax.portlet.PortletRequest;
57
58 import javax.servlet.http.Cookie;
59 import javax.servlet.http.HttpServletRequest;
60 import javax.servlet.http.HttpServletResponse;
61 import javax.servlet.jsp.PageContext;
62
63
69 public class LanguageImpl implements Language {
70
71 public String format(Locale locale, String pattern, Object argument) {
72 return format(locale, pattern, new Object[] {argument}, true);
73 }
74
75 public String format(
76 Locale locale, String pattern, Object argument,
77 boolean translateArguments) {
78
79 return format(
80 locale, pattern, new Object[] {argument}, translateArguments);
81 }
82
83 public String format(Locale locale, String pattern, Object[] arguments) {
84 return format(locale, pattern, arguments, true);
85 }
86
87 public String format(
88 Locale locale, String pattern, Object[] arguments,
89 boolean translateArguments) {
90
91 String value = null;
92
93 try {
94 pattern = get(locale, pattern);
95
96 if (arguments != null) {
97 pattern = _escapePattern(pattern);
98
99 Object[] formattedArguments = new Object[arguments.length];
100
101 for (int i = 0; i < arguments.length; i++) {
102 if (translateArguments) {
103 formattedArguments[i] = get(
104 locale, arguments[i].toString());
105 }
106 else {
107 formattedArguments[i] = arguments[i];
108 }
109 }
110
111 value = MessageFormat.format(pattern, formattedArguments);
112 }
113 else {
114 value = pattern;
115 }
116 }
117 catch (Exception e) {
118 if (_log.isWarnEnabled()) {
119 _log.warn(e, e);
120 }
121 }
122
123 return value;
124 }
125
126 public String format(
127 PageContext pageContext, String pattern, Object argument) {
128
129 return format(pageContext, pattern, new Object[] {argument}, true);
130 }
131
132 public String format(
133 PageContext pageContext, String pattern, Object argument,
134 boolean translateArguments) {
135
136 return format(
137 pageContext, pattern, new Object[] {argument}, translateArguments);
138 }
139
140 public String format(
141 PageContext pageContext, String pattern, Object[] arguments) {
142
143 return format(pageContext, pattern, arguments, true);
144 }
145
146 public String format(
147 PageContext pageContext, String pattern, Object[] arguments,
148 boolean translateArguments) {
149
150 String value = null;
151
152 try {
153 pattern = get(pageContext, pattern);
154
155 if (arguments != null) {
156 pattern = _escapePattern(pattern);
157
158 Object[] formattedArguments = new Object[arguments.length];
159
160 for (int i = 0; i < arguments.length; i++) {
161 if (translateArguments) {
162 formattedArguments[i] =
163 get(pageContext, arguments[i].toString());
164 }
165 else {
166 formattedArguments[i] = arguments[i];
167 }
168 }
169
170 value = MessageFormat.format(pattern, formattedArguments);
171 }
172 else {
173 value = pattern;
174 }
175 }
176 catch (Exception e) {
177 if (_log.isWarnEnabled()) {
178 _log.warn(e, e);
179 }
180 }
181
182 return value;
183 }
184
185 public String format(
186 PageContext pageContext, String pattern, LanguageWrapper argument) {
187
188 return format(
189 pageContext, pattern, new LanguageWrapper[] {argument}, true);
190 }
191
192 public String format(
193 PageContext pageContext, String pattern, LanguageWrapper argument,
194 boolean translateArguments) {
195
196 return format(
197 pageContext, pattern, new LanguageWrapper[] {argument},
198 translateArguments);
199 }
200
201 public String format(
202 PageContext pageContext, String pattern, LanguageWrapper[] arguments) {
203
204 return format(pageContext, pattern, arguments, true);
205 }
206
207 public String format(
208 PageContext pageContext, String pattern, LanguageWrapper[] arguments,
209 boolean translateArguments) {
210
211 String value = null;
212
213 try {
214 pattern = get(pageContext, pattern);
215
216 if (arguments != null) {
217 pattern = _escapePattern(pattern);
218
219 Object[] formattedArguments = new Object[arguments.length];
220
221 for (int i = 0; i < arguments.length; i++) {
222 if (translateArguments) {
223 formattedArguments[i] =
224 arguments[i].getBefore() +
225 get(pageContext, arguments[i].getText()) +
226 arguments[i].getAfter();
227 }
228 else {
229 formattedArguments[i] =
230 arguments[i].getBefore() +
231 arguments[i].getText() +
232 arguments[i].getAfter();
233 }
234 }
235
236 value = MessageFormat.format(pattern, formattedArguments);
237 }
238 else {
239 value = pattern;
240 }
241 }
242 catch (Exception e) {
243 if (_log.isWarnEnabled()) {
244 _log.warn(e, e);
245 }
246 }
247
248 return value;
249 }
250
251 public void init() {
252 _instances.clear();
253 }
254
255 public String get(Locale locale, String key) {
256 return get(locale, key, key);
257 }
258
259 public String get(Locale locale, String key, String defaultValue) {
260 try {
261 return _get(null, locale, key, defaultValue);
262 }
263 catch (Exception e) {
264 if (_log.isWarnEnabled()) {
265 _log.warn(e, e);
266 }
267
268 return defaultValue;
269 }
270 }
271
272 public String get(PageContext pageContext, String key) {
273 return get(pageContext, key, key);
274 }
275
276 public String get(
277 PageContext pageContext, String key, String defaultValue) {
278
279 try {
280 return _get(pageContext, null, key, defaultValue);
281 }
282 catch (Exception e) {
283 if (_log.isWarnEnabled()) {
284 _log.warn(e, e);
285 }
286
287 return defaultValue;
288 }
289 }
290
291 public Locale[] getAvailableLocales() {
292 return _getInstance()._locales;
293 }
294
295 public String getCharset(Locale locale) {
296 return _getInstance()._getCharset(locale);
297 }
298
299 public String getLanguageId(PortletRequest portletRequest) {
300 HttpServletRequest request = PortalUtil.getHttpServletRequest(
301 portletRequest);
302
303 return getLanguageId(request);
304 }
305
306 public String getLanguageId(HttpServletRequest request) {
307 String languageId = ParamUtil.getString(request, "languageId");
308
309 if (Validator.isNotNull(languageId)) {
310 if (_localesMap.containsKey(languageId) ||
311 _charEncodings.containsKey(languageId)) {
312
313 return languageId;
314 }
315 }
316
317 Locale locale = PortalUtil.getLocale(request);
318
319 return getLanguageId(locale);
320 }
321
322 public String getLanguageId(Locale locale) {
323 return LocaleUtil.toLanguageId(locale);
324 }
325
326 public Locale getLocale(String languageCode) {
327 return _getInstance()._getLocale(languageCode);
328 }
329
330 public String getTimeDescription(
331 PageContext pageContext, Long milliseconds) {
332
333 return getTimeDescription(pageContext, milliseconds.longValue());
334 }
335
336 public String getTimeDescription(
337 PageContext pageContext, long milliseconds) {
338
339 String desc = Time.getDescription(milliseconds);
340
341 String value = null;
342
343 try {
344 int pos = desc.indexOf(StringPool.SPACE);
345
346 int x = GetterUtil.getInteger(desc.substring(0, pos));
347
348 value =
349 x + " " +
350 get(
351 pageContext,
352 desc.substring(pos + 1, desc.length()).toLowerCase());
353 }
354 catch (Exception e) {
355 if (_log.isWarnEnabled()) {
356 _log.warn(e, e);
357 }
358 }
359
360 return value;
361 }
362
363 public boolean isAvailableLocale(Locale locale) {
364 return _getInstance()._localesSet.contains(locale);
365 }
366
367 public boolean isDuplicateLanguageCode(String languageCode) {
368 return _getInstance()._duplicateLanguageCodes.contains(languageCode);
369 }
370
371 public void resetAvailableLocales(long companyId) {
372 _resetAvailableLocales(companyId);
373 }
374
375 public void updateCookie(
376 HttpServletRequest request, HttpServletResponse response,
377 Locale locale) {
378
379 String languageId = LocaleUtil.toLanguageId(locale);
380
381 Cookie languageIdCookie = new Cookie(
382 CookieKeys.GUEST_LANGUAGE_ID, languageId);
383
384 languageIdCookie.setPath(StringPool.SLASH);
385 languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
386
387 CookieKeys.addCookie(request, response, languageIdCookie);
388 }
389
390 private static LanguageImpl _getInstance() {
391 long companyId = CompanyThreadLocal.getCompanyId();
392
393 LanguageImpl instance = _instances.get(companyId);
394
395 if (instance == null) {
396 instance = new LanguageImpl(companyId);
397
398 _instances.put(companyId, instance);
399 }
400
401 return instance;
402 }
403
404 private LanguageImpl() {
405 this(CompanyConstants.SYSTEM);
406 }
407
408 private LanguageImpl(long companyId) {
409 String[] localesArray = PropsValues.LOCALES;
410
411 if (companyId != CompanyConstants.SYSTEM) {
412 try {
413 localesArray = PrefsPropsUtil.getStringArray(
414 companyId, PropsKeys.LOCALES, StringPool.COMMA,
415 PropsValues.LOCALES);
416 }
417 catch (SystemException se) {
418 localesArray = PropsValues.LOCALES;
419 }
420 }
421
422 _charEncodings = new HashMap<String, String>();
423 _duplicateLanguageCodes = new HashSet<String>();
424 _locales = new Locale[localesArray.length];
425 _localesMap = new HashMap<String, Locale>(localesArray.length);
426 _localesSet = new HashSet<Locale>(localesArray.length);
427
428 for (int i = 0; i < localesArray.length; i++) {
429 String languageId = localesArray[i];
430
431 int pos = languageId.indexOf(StringPool.UNDERLINE);
432
433 String language = languageId.substring(0, pos);
434
436 Locale locale = LocaleUtil.fromLanguageId(languageId);
437
438 _charEncodings.put(locale.toString(), StringPool.UTF8);
439
440 if (_localesMap.containsKey(language)) {
441 _duplicateLanguageCodes.add(language);
442 }
443
444 _locales[i] = locale;
445
446 if (!_localesMap.containsKey(language)) {
447 _localesMap.put(language, locale);
448 }
449
450 _localesSet.add(locale);
451 }
452 }
453
454 private String _escapePattern(String pattern) {
455 return StringUtil.replace(
456 pattern, StringPool.APOSTROPHE, StringPool.DOUBLE_APOSTROPHE);
457 }
458
459 private String _get(
460 PageContext pageContext, Locale locale, String key,
461 String defaultValue)
462 throws Exception {
463
464 if (key == null) {
465 return null;
466 }
467
468 String value = null;
469
470 if (pageContext != null) {
471 HttpServletRequest request =
472 (HttpServletRequest)pageContext.getRequest();
473
474 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
475 WebKeys.THEME_DISPLAY);
476
477 locale = themeDisplay.getLocale();
478
479 PortletConfig portletConfig = (PortletConfig)request.getAttribute(
480 JavaConstants.JAVAX_PORTLET_CONFIG);
481
482 if (portletConfig != null) {
483 ResourceBundle resourceBundle = portletConfig.getResourceBundle(
484 locale);
485
486 try {
487 value = resourceBundle.getString(key);
488 }
489 catch (MissingResourceException mre) {
490 }
491
492
494 if (((value == null) || (value.equals(defaultValue))) &&
495 (portletConfig.getPortletName().equals(
496 PortletKeys.PORTLET_CONFIGURATION))) {
497
498 try {
499 value = _getPortletConfigurationValue(
500 pageContext, locale, key);
501 }
502 catch (MissingResourceException mre) {
503 }
504 }
505 }
506 }
507
508 if ((value == null) || value.equals(defaultValue)) {
509 value = LanguageResources.getMessage(locale, key);
510 }
511
512 if ((value == null) || value.equals(defaultValue)) {
513 if (key.endsWith(StringPool.CLOSE_BRACKET)) {
514 int pos = key.lastIndexOf(StringPool.OPEN_BRACKET);
515
516 if (pos != -1) {
517 key = key.substring(0, pos);
518
519 return _get(pageContext, locale, key, defaultValue);
520 }
521 }
522 }
523
524 if (value == null) {
525 value = defaultValue;
526 }
527
528 return value;
529 }
530
531 private String _getCharset(Locale locale) {
532 return StringPool.UTF8;
533 }
534
535 private Locale _getLocale(String languageCode) {
536 return _localesMap.get(languageCode);
537 }
538
539 private String _getPortletConfigurationValue(
540 PageContext pageContext, Locale locale, String key)
541 throws Exception {
542
543 HttpServletRequest request =
544 (HttpServletRequest)pageContext.getRequest();
545
546 String portletResource = ParamUtil.getString(
547 request, "portletResource");
548
549 long companyId = PortalUtil.getCompanyId(request);
550
551 Portlet portlet = PortletLocalServiceUtil.getPortletById(
552 companyId, portletResource);
553
554 PortletConfig portletConfig = PortletConfigFactory.create(
555 portlet, pageContext.getServletContext());
556
557 ResourceBundle resourceBundle = portletConfig.getResourceBundle(
558 locale);
559
560 return resourceBundle.getString(key);
561 }
562
563 private void _resetAvailableLocales(long companyId) {
564 _instances.remove(companyId);
565 }
566
567 private static Log _log = LogFactoryUtil.getLog(LanguageImpl.class);
568
569 private static Map<Long, LanguageImpl> _instances =
570 new ConcurrentHashMap<Long, LanguageImpl>();
571
572 private Map<String, String> _charEncodings;
573 private Set<String> _duplicateLanguageCodes;
574 private Locale[] _locales;
575 private Map<String, Locale> _localesMap;
576 private Set<Locale> _localesSet;
577
578 }