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