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