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