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