001
014
015 package com.liferay.portal.language;
016
017 import com.liferay.portal.kernel.exception.SystemException;
018 import com.liferay.portal.kernel.language.Language;
019 import com.liferay.portal.kernel.language.LanguageWrapper;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.JavaConstants;
024 import com.liferay.portal.kernel.util.LocaleUtil;
025 import com.liferay.portal.kernel.util.ParamUtil;
026 import com.liferay.portal.kernel.util.PropsKeys;
027 import com.liferay.portal.kernel.util.StringPool;
028 import com.liferay.portal.kernel.util.StringUtil;
029 import com.liferay.portal.kernel.util.Time;
030 import com.liferay.portal.kernel.util.Validator;
031 import com.liferay.portal.model.CompanyConstants;
032 import com.liferay.portal.model.Portlet;
033 import com.liferay.portal.security.auth.CompanyThreadLocal;
034 import com.liferay.portal.service.PortletLocalServiceUtil;
035 import com.liferay.portal.theme.ThemeDisplay;
036 import com.liferay.portal.util.CookieKeys;
037 import com.liferay.portal.util.PortalUtil;
038 import com.liferay.portal.util.PortletKeys;
039 import com.liferay.portal.util.PrefsPropsUtil;
040 import com.liferay.portal.util.PropsValues;
041 import com.liferay.portal.util.WebKeys;
042 import com.liferay.portlet.PortletConfigFactoryUtil;
043
044 import java.text.MessageFormat;
045
046 import java.util.HashMap;
047 import java.util.HashSet;
048 import java.util.Locale;
049 import java.util.Map;
050 import java.util.MissingResourceException;
051 import java.util.ResourceBundle;
052 import java.util.Set;
053 import java.util.concurrent.ConcurrentHashMap;
054
055 import javax.portlet.PortletConfig;
056 import javax.portlet.PortletRequest;
057
058 import javax.servlet.http.Cookie;
059 import javax.servlet.http.HttpServletRequest;
060 import javax.servlet.http.HttpServletResponse;
061 import javax.servlet.jsp.PageContext;
062
063
067 public class LanguageImpl implements Language {
068
069 public String format(Locale locale, String pattern, Object argument) {
070 return format(locale, pattern, new Object[] {argument}, true);
071 }
072
073 public String format(
074 Locale locale, String pattern, Object argument,
075 boolean translateArguments) {
076
077 return format(
078 locale, pattern, new Object[] {argument}, translateArguments);
079 }
080
081 public String format(Locale locale, String pattern, Object[] arguments) {
082 return format(locale, pattern, arguments, true);
083 }
084
085 public String format(
086 Locale locale, String pattern, Object[] arguments,
087 boolean translateArguments) {
088
089 String value = null;
090
091 try {
092 pattern = get(locale, pattern);
093
094 if (arguments != null) {
095 pattern = _escapePattern(pattern);
096
097 Object[] formattedArguments = new Object[arguments.length];
098
099 for (int i = 0; i < arguments.length; i++) {
100 if (translateArguments) {
101 formattedArguments[i] = get(
102 locale, arguments[i].toString());
103 }
104 else {
105 formattedArguments[i] = arguments[i];
106 }
107 }
108
109 value = MessageFormat.format(pattern, formattedArguments);
110 }
111 else {
112 value = pattern;
113 }
114 }
115 catch (Exception e) {
116 if (_log.isWarnEnabled()) {
117 _log.warn(e, e);
118 }
119 }
120
121 return value;
122 }
123
124 public String format(
125 PageContext pageContext, String pattern, Object argument) {
126
127 return format(pageContext, pattern, new Object[] {argument}, true);
128 }
129
130 public String format(
131 PageContext pageContext, String pattern, Object argument,
132 boolean translateArguments) {
133
134 return format(
135 pageContext, pattern, new Object[] {argument}, translateArguments);
136 }
137
138 public String format(
139 PageContext pageContext, String pattern, Object[] arguments) {
140
141 return format(pageContext, pattern, arguments, true);
142 }
143
144 public String format(
145 PageContext pageContext, String pattern, Object[] arguments,
146 boolean translateArguments) {
147
148 String value = null;
149
150 try {
151 pattern = get(pageContext, pattern);
152
153 if (arguments != null) {
154 pattern = _escapePattern(pattern);
155
156 Object[] formattedArguments = new Object[arguments.length];
157
158 for (int i = 0; i < arguments.length; i++) {
159 if (translateArguments) {
160 formattedArguments[i] =
161 get(pageContext, arguments[i].toString());
162 }
163 else {
164 formattedArguments[i] = arguments[i];
165 }
166 }
167
168 value = MessageFormat.format(pattern, formattedArguments);
169 }
170 else {
171 value = pattern;
172 }
173 }
174 catch (Exception e) {
175 if (_log.isWarnEnabled()) {
176 _log.warn(e, e);
177 }
178 }
179
180 return value;
181 }
182
183 public String format(
184 PageContext pageContext, String pattern, LanguageWrapper argument) {
185
186 return format(
187 pageContext, pattern, new LanguageWrapper[] {argument}, true);
188 }
189
190 public String format(
191 PageContext pageContext, String pattern, LanguageWrapper argument,
192 boolean translateArguments) {
193
194 return format(
195 pageContext, pattern, new LanguageWrapper[] {argument},
196 translateArguments);
197 }
198
199 public String format(
200 PageContext pageContext, String pattern, LanguageWrapper[] arguments) {
201
202 return format(pageContext, pattern, arguments, true);
203 }
204
205 public String format(
206 PageContext pageContext, String pattern, LanguageWrapper[] arguments,
207 boolean translateArguments) {
208
209 String value = null;
210
211 try {
212 pattern = get(pageContext, pattern);
213
214 if (arguments != null) {
215 pattern = _escapePattern(pattern);
216
217 Object[] formattedArguments = new Object[arguments.length];
218
219 for (int i = 0; i < arguments.length; i++) {
220 if (translateArguments) {
221 formattedArguments[i] =
222 arguments[i].getBefore() +
223 get(pageContext, arguments[i].getText()) +
224 arguments[i].getAfter();
225 }
226 else {
227 formattedArguments[i] =
228 arguments[i].getBefore() +
229 arguments[i].getText() +
230 arguments[i].getAfter();
231 }
232 }
233
234 value = MessageFormat.format(pattern, formattedArguments);
235 }
236 else {
237 value = pattern;
238 }
239 }
240 catch (Exception e) {
241 if (_log.isWarnEnabled()) {
242 _log.warn(e, e);
243 }
244 }
245
246 return value;
247 }
248
249 public String format(
250 PortletConfig portletConfig, Locale locale, String pattern,
251 Object argument) {
252
253 return format(
254 portletConfig, locale, pattern, new Object[] {argument}, true);
255 }
256
257 public String format(
258 PortletConfig portletConfig, Locale locale, String pattern,
259 Object argument, boolean translateArguments) {
260
261 return format(
262 portletConfig, locale, pattern, new Object[] {argument},
263 translateArguments);
264 }
265
266 public String format(
267 PortletConfig portletConfig, Locale locale, String pattern,
268 Object[] arguments) {
269
270 return format(portletConfig, locale, pattern, arguments, true);
271 }
272
273 public String format(
274 PortletConfig portletConfig, Locale locale, String pattern,
275 Object[] arguments, boolean translateArguments) {
276
277 String value = null;
278
279 try {
280 pattern = get(portletConfig, locale, pattern);
281
282 if (arguments != null) {
283 pattern = _escapePattern(pattern);
284
285 Object[] formattedArguments = new Object[arguments.length];
286
287 for (int i = 0; i < arguments.length; i++) {
288 if (translateArguments) {
289 formattedArguments[i] = get(
290 locale, arguments[i].toString());
291 }
292 else {
293 formattedArguments[i] = arguments[i];
294 }
295 }
296
297 value = MessageFormat.format(pattern, formattedArguments);
298 }
299 else {
300 value = pattern;
301 }
302 }
303 catch (Exception e) {
304 if (_log.isWarnEnabled()) {
305 _log.warn(e, e);
306 }
307 }
308
309 return value;
310 }
311
312 public void init() {
313 _instances.clear();
314 }
315
316 public String get(Locale locale, String key) {
317 return get(locale, key, key);
318 }
319
320 public String get(Locale locale, String key, String defaultValue) {
321 try {
322 return _get(null, null, locale, key, defaultValue);
323 }
324 catch (Exception e) {
325 if (_log.isWarnEnabled()) {
326 _log.warn(e, e);
327 }
328
329 return defaultValue;
330 }
331 }
332
333 public String get(PageContext pageContext, String key) {
334 return get(pageContext, key, key);
335 }
336
337 public String get(
338 PageContext pageContext, String key, String defaultValue) {
339
340 try {
341 return _get(pageContext, null, null, 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(PortletConfig portletConfig, Locale locale, String key) {
353 return get(portletConfig, locale, key, key);
354 }
355
356 public String get(
357 PortletConfig portletConfig, Locale locale, String key,
358 String defaultValue) {
359
360 try {
361 return _get(null, portletConfig, locale, key, defaultValue);
362 }
363 catch (Exception e) {
364 if (_log.isWarnEnabled()) {
365 _log.warn(e, e);
366 }
367
368 return defaultValue;
369 }
370 }
371
372 public Locale[] getAvailableLocales() {
373 return _getInstance()._locales;
374 }
375
376 public String getCharset(Locale locale) {
377 return _getInstance()._getCharset(locale);
378 }
379
380 public String getLanguageId(PortletRequest portletRequest) {
381 HttpServletRequest request = PortalUtil.getHttpServletRequest(
382 portletRequest);
383
384 return getLanguageId(request);
385 }
386
387 public String getLanguageId(HttpServletRequest request) {
388 String languageId = ParamUtil.getString(request, "languageId");
389
390 if (Validator.isNotNull(languageId)) {
391 if (_localesMap.containsKey(languageId) ||
392 _charEncodings.containsKey(languageId)) {
393
394 return languageId;
395 }
396 }
397
398 Locale locale = PortalUtil.getLocale(request);
399
400 return getLanguageId(locale);
401 }
402
403 public String getLanguageId(Locale locale) {
404 return LocaleUtil.toLanguageId(locale);
405 }
406
407 public Locale getLocale(String languageCode) {
408 return _getInstance()._getLocale(languageCode);
409 }
410
411 public String getTimeDescription(
412 PageContext pageContext, Long milliseconds) {
413
414 return getTimeDescription(pageContext, milliseconds.longValue());
415 }
416
417 public String getTimeDescription(
418 PageContext pageContext, long milliseconds) {
419
420 String desc = Time.getDescription(milliseconds);
421
422 String value = null;
423
424 try {
425 int pos = desc.indexOf(StringPool.SPACE);
426
427 int x = GetterUtil.getInteger(desc.substring(0, pos));
428
429 value =
430 x + " " +
431 get(
432 pageContext,
433 desc.substring(pos + 1, desc.length()).toLowerCase());
434 }
435 catch (Exception e) {
436 if (_log.isWarnEnabled()) {
437 _log.warn(e, e);
438 }
439 }
440
441 return value;
442 }
443
444 public boolean isAvailableLocale(Locale locale) {
445 return _getInstance()._localesSet.contains(locale);
446 }
447
448 public boolean isDuplicateLanguageCode(String languageCode) {
449 return _getInstance()._duplicateLanguageCodes.contains(languageCode);
450 }
451
452 public void resetAvailableLocales(long companyId) {
453 _resetAvailableLocales(companyId);
454 }
455
456 public void updateCookie(
457 HttpServletRequest request, HttpServletResponse response,
458 Locale locale) {
459
460 String languageId = LocaleUtil.toLanguageId(locale);
461
462 Cookie languageIdCookie = new Cookie(
463 CookieKeys.GUEST_LANGUAGE_ID, languageId);
464
465 languageIdCookie.setPath(StringPool.SLASH);
466 languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
467
468 CookieKeys.addCookie(request, response, languageIdCookie);
469 }
470
471 private static LanguageImpl _getInstance() {
472 long companyId = CompanyThreadLocal.getCompanyId();
473
474 LanguageImpl instance = _instances.get(companyId);
475
476 if (instance == null) {
477 instance = new LanguageImpl(companyId);
478
479 _instances.put(companyId, instance);
480 }
481
482 return instance;
483 }
484
485 private LanguageImpl() {
486 this(CompanyConstants.SYSTEM);
487 }
488
489 private LanguageImpl(long companyId) {
490 String[] localesArray = PropsValues.LOCALES;
491
492 if (companyId != CompanyConstants.SYSTEM) {
493 try {
494 localesArray = PrefsPropsUtil.getStringArray(
495 companyId, PropsKeys.LOCALES, StringPool.COMMA,
496 PropsValues.LOCALES);
497 }
498 catch (SystemException se) {
499 localesArray = PropsValues.LOCALES;
500 }
501 }
502
503 _charEncodings = new HashMap<String, String>();
504 _duplicateLanguageCodes = new HashSet<String>();
505 _locales = new Locale[localesArray.length];
506 _localesMap = new HashMap<String, Locale>(localesArray.length);
507 _localesSet = new HashSet<Locale>(localesArray.length);
508
509 for (int i = 0; i < localesArray.length; i++) {
510 String languageId = localesArray[i];
511
512 int pos = languageId.indexOf(StringPool.UNDERLINE);
513
514 String language = languageId.substring(0, pos);
515
516
517 Locale locale = LocaleUtil.fromLanguageId(languageId);
518
519 _charEncodings.put(locale.toString(), StringPool.UTF8);
520
521 if (_localesMap.containsKey(language)) {
522 _duplicateLanguageCodes.add(language);
523 }
524
525 _locales[i] = locale;
526
527 if (!_localesMap.containsKey(language)) {
528 _localesMap.put(language, locale);
529 }
530
531 _localesSet.add(locale);
532 }
533 }
534
535 private String _escapePattern(String pattern) {
536 return StringUtil.replace(
537 pattern, StringPool.APOSTROPHE, StringPool.DOUBLE_APOSTROPHE);
538 }
539
540 private String _get(
541 PageContext pageContext, PortletConfig portletConfig, Locale locale,
542 String key, String defaultValue)
543 throws Exception {
544
545 if (key == null) {
546 return null;
547 }
548
549 String value = null;
550
551 if (pageContext != null) {
552 HttpServletRequest request =
553 (HttpServletRequest)pageContext.getRequest();
554
555 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
556 WebKeys.THEME_DISPLAY);
557
558 locale = themeDisplay.getLocale();
559
560 portletConfig = (PortletConfig)request.getAttribute(
561 JavaConstants.JAVAX_PORTLET_CONFIG);
562 }
563
564 if (portletConfig != null) {
565 ResourceBundle resourceBundle = portletConfig.getResourceBundle(
566 locale);
567
568 try {
569 value = resourceBundle.getString(key);
570 }
571 catch (MissingResourceException mre) {
572 }
573
574
575
576 if (((value == null) || (value.equals(defaultValue))) &&
577 (portletConfig.getPortletName().equals(
578 PortletKeys.PORTLET_CONFIGURATION))) {
579
580 try {
581 value = _getPortletConfigurationValue(
582 pageContext, locale, key);
583 }
584 catch (MissingResourceException mre) {
585 }
586 }
587 }
588
589 if ((value == null) || value.equals(defaultValue)) {
590 value = LanguageResources.getMessage(locale, key);
591 }
592
593 if ((value == null) || value.equals(defaultValue)) {
594 if (key.endsWith(StringPool.CLOSE_BRACKET)) {
595 int pos = key.lastIndexOf(StringPool.OPEN_BRACKET);
596
597 if (pos != -1) {
598 key = key.substring(0, pos);
599
600 return _get(
601 pageContext, portletConfig, locale, key, defaultValue);
602 }
603 }
604 }
605
606 if (value == null) {
607 value = defaultValue;
608 }
609
610 return value;
611 }
612
613 private String _getCharset(Locale locale) {
614 return StringPool.UTF8;
615 }
616
617 private Locale _getLocale(String languageCode) {
618 return _localesMap.get(languageCode);
619 }
620
621 private String _getPortletConfigurationValue(
622 PageContext pageContext, Locale locale, String key)
623 throws Exception {
624
625 HttpServletRequest request =
626 (HttpServletRequest)pageContext.getRequest();
627
628 String portletResource = ParamUtil.getString(
629 request, "portletResource");
630
631 long companyId = PortalUtil.getCompanyId(request);
632
633 Portlet portlet = PortletLocalServiceUtil.getPortletById(
634 companyId, portletResource);
635
636 PortletConfig portletConfig = PortletConfigFactoryUtil.create(
637 portlet, pageContext.getServletContext());
638
639 ResourceBundle resourceBundle = portletConfig.getResourceBundle(
640 locale);
641
642 return resourceBundle.getString(key);
643 }
644
645 private void _resetAvailableLocales(long companyId) {
646 _instances.remove(companyId);
647 }
648
649 private static Log _log = LogFactoryUtil.getLog(LanguageImpl.class);
650
651 private static Map<Long, LanguageImpl> _instances =
652 new ConcurrentHashMap<Long, LanguageImpl>();
653
654 private Map<String, String> _charEncodings;
655 private Set<String> _duplicateLanguageCodes;
656 private Locale[] _locales;
657 private Map<String, Locale> _localesMap;
658 private Set<Locale> _localesSet;
659
660 }