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