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 return languageId;
423 }
424
425 Locale locale = PortalUtil.getLocale(request);
426
427 return getLanguageId(locale);
428 }
429
430 public String getLanguageId(Locale locale) {
431 return LocaleUtil.toLanguageId(locale);
432 }
433
434 public Locale getLocale(String languageCode) {
435 return _getInstance()._getLocale(languageCode);
436 }
437
438 public String getTimeDescription(
439 PageContext pageContext, Long milliseconds) {
440
441 return getTimeDescription(pageContext, milliseconds.longValue());
442 }
443
444 public String getTimeDescription(
445 PageContext pageContext, long milliseconds) {
446
447 String desc = Time.getDescription(milliseconds);
448
449 String value = null;
450
451 try {
452 int pos = desc.indexOf(StringPool.SPACE);
453
454 int x = GetterUtil.getInteger(desc.substring(0, pos));
455
456 value =
457 x + " " +
458 get(
459 pageContext,
460 desc.substring(pos + 1, desc.length()).toLowerCase());
461 }
462 catch (Exception e) {
463 if (_log.isWarnEnabled()) {
464 _log.warn(e, e);
465 }
466 }
467
468 return value;
469 }
470
471 public boolean isAvailableLocale(Locale locale) {
472 return _getInstance()._localesSet.contains(locale);
473 }
474
475 public boolean isDuplicateLanguageCode(String languageCode) {
476 return _getInstance()._duplicateLanguageCodes.contains(languageCode);
477 }
478
479 public void resetAvailableLocales(long companyId) {
480 _resetAvailableLocales(companyId);
481 }
482
483 public void updateCookie(
484 HttpServletRequest request, HttpServletResponse response,
485 Locale locale) {
486
487 String languageId = LocaleUtil.toLanguageId(locale);
488
489 Cookie languageIdCookie = new Cookie(
490 CookieKeys.GUEST_LANGUAGE_ID, languageId);
491
492 languageIdCookie.setPath(StringPool.SLASH);
493 languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
494
495 CookieKeys.addCookie(request, response, languageIdCookie);
496 }
497
498 private static LanguageImpl _getInstance() {
499 long companyId = CompanyThreadLocal.getCompanyId();
500
501 LanguageImpl instance = _instances.get(companyId);
502
503 if (instance == null) {
504 instance = new LanguageImpl(companyId);
505
506 _instances.put(companyId, instance);
507 }
508
509 return instance;
510 }
511
512 private LanguageImpl() {
513 this(CompanyConstants.SYSTEM);
514 }
515
516 private LanguageImpl(long companyId) {
517 String[] localesArray = PropsValues.LOCALES;
518
519 if (companyId != CompanyConstants.SYSTEM) {
520 try {
521 localesArray = PrefsPropsUtil.getStringArray(
522 companyId, PropsKeys.LOCALES, StringPool.COMMA,
523 PropsValues.LOCALES);
524 }
525 catch (SystemException se) {
526 localesArray = PropsValues.LOCALES;
527 }
528 }
529
530 _charEncodings = new HashMap<String, String>();
531 _duplicateLanguageCodes = new HashSet<String>();
532 _locales = new Locale[localesArray.length];
533 _localesMap = new HashMap<String, Locale>(localesArray.length);
534 _localesSet = new HashSet<Locale>(localesArray.length);
535
536 for (int i = 0; i < localesArray.length; i++) {
537 String languageId = localesArray[i];
538
539 int pos = languageId.indexOf(StringPool.UNDERLINE);
540
541 String language = languageId.substring(0, pos);
542
544 Locale locale = LocaleUtil.fromLanguageId(languageId);
545
546 _charEncodings.put(locale.toString(), StringPool.UTF8);
547
548 if (_localesMap.containsKey(language)) {
549 _duplicateLanguageCodes.add(language);
550 }
551
552 _locales[i] = locale;
553
554 if (!_localesMap.containsKey(language)) {
555 _localesMap.put(language, locale);
556 }
557
558 _localesSet.add(locale);
559 }
560 }
561
562 private String _escapePattern(String pattern) {
563 return StringUtil.replace(
564 pattern, StringPool.APOSTROPHE, StringPool.DOUBLE_APOSTROPHE);
565 }
566
567 private String _getCharset(Locale locale) {
568 return StringPool.UTF8;
569 }
570
571 private Locale _getLocale(String languageCode) {
572 return _localesMap.get(languageCode);
573 }
574
575 private String _getPortletConfigurationValue(
576 PageContext pageContext, String key) {
577
578 String value = null;
579
580 try {
581 HttpServletRequest request =
582 (HttpServletRequest)pageContext.getRequest();
583
584 String portletResource = ParamUtil.getString(
585 request, "portletResource");
586
587 long companyId = PortalUtil.getCompanyId(request);
588
589 Portlet portlet = PortletLocalServiceUtil.getPortletById(
590 companyId, portletResource);
591
592 PortletConfig portletConfig = PortletConfigFactory.create(
593 portlet, pageContext.getServletContext());
594
595 Locale locale = request.getLocale();
596
597 ResourceBundle bundle = portletConfig.getResourceBundle(locale);
598
599 value = bundle.getString(key);
600 }
601 catch (Exception e) {
602 if (_log.isWarnEnabled()) {
603 _log.warn(e, e);
604 }
605 }
606
607 return value;
608 }
609
610 private void _resetAvailableLocales(long companyId) {
611 _instances.remove(companyId);
612 }
613
614 private static Log _log = LogFactoryUtil.getLog(LanguageImpl.class);
615
616 private static Map<Long, LanguageImpl> _instances =
617 new ConcurrentHashMap<Long, LanguageImpl>();
618
619 private Map<String, String> _charEncodings;
620 private Set<String> _duplicateLanguageCodes;
621 private Locale[] _locales;
622 private Map<String, Locale> _localesMap;
623 private Set<Locale> _localesSet;
624
625 }