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