1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.language;
24  
25  import com.liferay.portal.kernel.language.Language;
26  import com.liferay.portal.kernel.language.LanguageWrapper;
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.Validator;
33  import com.liferay.portal.security.auth.CompanyThreadLocal;
34  import com.liferay.portal.util.CookieKeys;
35  import com.liferay.portal.util.PortalUtil;
36  import com.liferay.portal.util.PropsValues;
37  import com.liferay.portal.util.WebAppPool;
38  import com.liferay.util.CollectionFactory;
39  import com.liferay.util.CookieUtil;
40  import com.liferay.util.Time;
41  
42  import java.text.MessageFormat;
43  
44  import java.util.Locale;
45  import java.util.Map;
46  import java.util.MissingResourceException;
47  import java.util.ResourceBundle;
48  
49  import javax.portlet.ActionRequest;
50  import javax.portlet.PortletConfig;
51  import javax.portlet.RenderRequest;
52  
53  import javax.servlet.http.Cookie;
54  import javax.servlet.http.HttpServletRequest;
55  import javax.servlet.http.HttpServletResponse;
56  import javax.servlet.jsp.PageContext;
57  
58  import org.apache.commons.logging.Log;
59  import org.apache.commons.logging.LogFactory;
60  import org.apache.struts.Globals;
61  import org.apache.struts.taglib.TagUtils;
62  import org.apache.struts.util.MessageResources;
63  
64  /**
65   * <a href="LanguageImpl.java.html"><b><i>View Source</i></b></a>
66   *
67   * @author Brian Wing Shun Chan
68   * @author Andrius Vitkauskas
69   *
70   */
71  public class LanguageImpl implements Language {
72  
73      public static final String DEFAULT_ENCODING = "UTF-8";
74  
75      public String format(Locale locale, String pattern, Object argument) {
76          long companyId = CompanyThreadLocal.getCompanyId();
77  
78          return format(companyId, locale, pattern, new Object[] {argument});
79      }
80  
81      public String format(Locale locale, String pattern, Object[] arguments) {
82          long companyId = CompanyThreadLocal.getCompanyId();
83  
84          return format(companyId, locale, pattern, arguments);
85      }
86  
87      public String format(
88          long companyId, Locale locale, String pattern, Object argument) {
89  
90          return format(companyId, locale, pattern, new Object[] {argument});
91      }
92  
93      public String format(
94          long companyId, Locale locale, String pattern, Object[] arguments) {
95  
96          String value = null;
97  
98          try {
99              pattern = get(companyId, locale, pattern);
100 
101             if (arguments != null) {
102                 Object[] formattedArguments = new Object[arguments.length];
103 
104                 for (int i = 0; i < arguments.length; i++) {
105                     formattedArguments[i] = get(
106                         companyId, locale, arguments[i].toString());
107                 }
108 
109                 value = MessageFormat.format(pattern, formattedArguments);
110             }
111             else {
112                 value = pattern;
113             }
114         }
115         catch (Exception e) {
116             if (_log.isWarnEnabled()) {
117                 _log.warn(e.getMessage());
118             }
119         }
120 
121         return value;
122     }
123 
124     public String format(
125         PageContext pageContext, String pattern, Object argument) {
126 
127         return format(pageContext, pattern, new Object[] {argument}, true);
128     }
129 
130     public String format(
131         PageContext pageContext, String pattern, Object argument,
132         boolean translateArguments) {
133 
134         return format(
135             pageContext, pattern, new Object[] {argument}, translateArguments);
136     }
137 
138     public String format(
139         PageContext pageContext, String pattern, Object[] arguments) {
140 
141         return format(pageContext, pattern, arguments, true);
142     }
143 
144     public String format(
145         PageContext pageContext, String pattern, Object[] arguments,
146         boolean translateArguments) {
147 
148         String value = null;
149 
150         try {
151             pattern = get(pageContext, pattern);
152 
153             if (arguments != null) {
154                 Object[] formattedArguments = new Object[arguments.length];
155 
156                 for (int i = 0; i < arguments.length; i++) {
157                     if (translateArguments) {
158                         formattedArguments[i] =
159                             get(pageContext, arguments[i].toString());
160                     }
161                     else {
162                         formattedArguments[i] = arguments[i];
163                     }
164                 }
165 
166                 value = MessageFormat.format(pattern, formattedArguments);
167             }
168             else {
169                 value = pattern;
170             }
171         }
172         catch (Exception e) {
173             if (_log.isWarnEnabled()) {
174                 _log.warn(e.getMessage());
175             }
176         }
177 
178         return value;
179     }
180 
181     public String format(
182         PageContext pageContext, String pattern, LanguageWrapper argument) {
183 
184         return format(
185             pageContext, pattern, new LanguageWrapper[] {argument}, true);
186     }
187 
188     public String format(
189         PageContext pageContext, String pattern, LanguageWrapper argument,
190         boolean translateArguments) {
191 
192         return format(
193             pageContext, pattern, new LanguageWrapper[] {argument},
194             translateArguments);
195     }
196 
197     public String format(
198         PageContext pageContext, String pattern, LanguageWrapper[] arguments) {
199 
200         return format(pageContext, pattern, arguments, true);
201     }
202 
203     public String format(
204         PageContext pageContext, String pattern, LanguageWrapper[] arguments,
205         boolean translateArguments) {
206 
207         String value = null;
208 
209         try {
210             pattern = get(pageContext, pattern);
211 
212             if (arguments != null) {
213                 Object[] formattedArguments = new Object[arguments.length];
214 
215                 for (int i = 0; i < arguments.length; i++) {
216                     if (translateArguments) {
217                         formattedArguments[i] =
218                             arguments[i].getBefore() +
219                             get(pageContext, arguments[i].getText()) +
220                             arguments[i].getAfter();
221                     }
222                     else {
223                         formattedArguments[i] =
224                             arguments[i].getBefore() +
225                             arguments[i].getText() +
226                             arguments[i].getAfter();
227                     }
228                 }
229 
230                 value = MessageFormat.format(pattern, formattedArguments);
231             }
232             else {
233                 value = pattern;
234             }
235         }
236         catch (Exception e) {
237             if (_log.isWarnEnabled()) {
238                 _log.warn(e.getMessage());
239             }
240         }
241 
242         return value;
243     }
244 
245     public String get(Locale locale, String key) {
246         long companyId = CompanyThreadLocal.getCompanyId();
247 
248         return get(companyId, locale, key, key);
249     }
250 
251     public String get(long companyId, Locale locale, String key) {
252         return get(companyId, locale, key, key);
253     }
254 
255     public String get(
256         long companyId, Locale locale, String key, String defaultValue) {
257 
258         if (key == null) {
259             return null;
260         }
261 
262         String value = null;
263 
264         try {
265             MessageResources resources = (MessageResources)WebAppPool.get(
266                 String.valueOf(companyId), Globals.MESSAGES_KEY);
267 
268             if (resources == null) {
269 
270                 // LEP-4505
271 
272                 ResourceBundle bundle = ResourceBundle.getBundle(
273                     "content/Language", locale);
274 
275                 value = bundle.getString(key);
276             }
277             else {
278                 value = resources.getMessage(locale, key);
279             }
280         }
281         catch (Exception e) {
282             if (_log.isWarnEnabled()) {
283                 _log.warn(e.getMessage());
284             }
285         }
286 
287         if (value == null) {
288             value = defaultValue;
289         }
290 
291         return value;
292     }
293 
294     public String get(PageContext pageContext, String key) {
295         return get(pageContext, key, key);
296     }
297 
298     public String get(
299         PageContext pageContext, String key, String defaultValue) {
300 
301         if (key == null) {
302             return null;
303         }
304 
305         String value = null;
306 
307         try {
308             value = TagUtils.getInstance().message(
309                 pageContext, null, null, key);
310         }
311         catch (Exception e) {
312             _log.error(e);
313         }
314 
315         if (value == null) {
316 
317             // LEP-2849
318 
319             HttpServletRequest req =
320                 (HttpServletRequest)pageContext.getRequest();
321 
322             PortletConfig portletConfig = (PortletConfig)req.getAttribute(
323                 JavaConstants.JAVAX_PORTLET_CONFIG);
324 
325             if (portletConfig != null) {
326                 Locale locale = req.getLocale();
327 
328                 ResourceBundle bundle = portletConfig.getResourceBundle(locale);
329 
330                 try {
331                     value = bundle.getString(key);
332                 }
333                 catch (MissingResourceException mre) {
334                 }
335             }
336         }
337 
338         if (value == null) {
339             value = defaultValue;
340         }
341 
342         return value;
343     }
344 
345     public Locale[] getAvailableLocales() {
346         return _getInstance()._locales;
347     }
348 
349     public String getCharset(Locale locale) {
350         return _getInstance()._getCharset(locale);
351     }
352 
353     public String getLanguageId(ActionRequest req) {
354         HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
355 
356         return getLanguageId(httpReq);
357     }
358 
359     public String getLanguageId(RenderRequest req) {
360         HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
361 
362         return getLanguageId(httpReq);
363     }
364 
365     public String getLanguageId(HttpServletRequest req) {
366         String languageId = ParamUtil.getString(req, "languageId");
367 
368         if (Validator.isNotNull(languageId)) {
369             return languageId;
370         }
371 
372         Locale locale =
373             (Locale)req.getSession().getAttribute(Globals.LOCALE_KEY);
374 
375         if (locale == null) {
376             languageId = CookieUtil.get(
377                 req.getCookies(), CookieKeys.GUEST_LANGUAGE_ID);
378 
379             if (Validator.isNotNull(languageId)) {
380                 locale = LocaleUtil.fromLanguageId(languageId);
381             }
382         }
383 
384         return getLanguageId(locale);
385     }
386 
387     public String getLanguageId(Locale locale) {
388         return LocaleUtil.toLanguageId(locale);
389     }
390 
391     public Locale getLocale(String languageCode) {
392         return _getInstance()._getLocale(languageCode);
393     }
394 
395     public String getTimeDescription(
396         PageContext pageContext, Long milliseconds) {
397 
398         return getTimeDescription(pageContext, milliseconds.longValue());
399     }
400 
401     public String getTimeDescription(
402         PageContext pageContext, long milliseconds) {
403 
404         String desc = Time.getDescription(milliseconds);
405 
406         String value = null;
407 
408         try {
409             int pos = desc.indexOf(StringPool.SPACE);
410 
411             int x = GetterUtil.getInteger(desc.substring(0, pos));
412 
413             value =
414                 x + " " +
415                 get(
416                     pageContext,
417                     desc.substring(pos + 1, desc.length()).toLowerCase());
418         }
419         catch (Exception e) {
420             if (_log.isWarnEnabled()) {
421                 _log.warn(e.getMessage());
422             }
423         }
424 
425         return value;
426     }
427 
428     public void updateCookie(HttpServletResponse res, Locale locale) {
429         String languageId = LocaleUtil.toLanguageId(locale);
430 
431         Cookie languageIdCookie = new Cookie(
432             CookieKeys.GUEST_LANGUAGE_ID, languageId);
433 
434         languageIdCookie.setPath(StringPool.SLASH);
435         languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
436 
437         CookieKeys.addCookie(res, languageIdCookie);
438     }
439 
440     private static LanguageImpl _getInstance() {
441         Long companyIdObj = new Long(CompanyThreadLocal.getCompanyId());
442 
443         LanguageImpl instance = (LanguageImpl)_instances.get(companyIdObj);
444 
445         if (instance == null) {
446             instance = new LanguageImpl();
447 
448             _instances.put(companyIdObj, instance);
449         }
450 
451         return instance;
452     }
453 
454     private LanguageImpl() {
455         String[] localesArray = PropsValues.LOCALES;
456 
457         _locales = new Locale[localesArray.length];
458         _localesByLanguageCode = CollectionFactory.getHashMap();
459         _charEncodings = CollectionFactory.getHashMap();
460 
461         for (int i = 0; i < localesArray.length; i++) {
462             String languageId = localesArray[i];
463 
464             int x = languageId.indexOf(StringPool.UNDERLINE);
465 
466             String language = languageId.substring(0, x);
467             //String country = languageId.substring(x + 1, languageId.length());
468 
469             Locale locale = LocaleUtil.fromLanguageId(languageId);
470 
471             _locales[i] = locale;
472             _localesByLanguageCode.put(language, locale);
473             _charEncodings.put(locale.toString(), DEFAULT_ENCODING);
474         }
475     }
476 
477     private String _getCharset(Locale locale) {
478         return DEFAULT_ENCODING;
479     }
480 
481     private Locale _getLocale(String languageCode) {
482         return (Locale)_localesByLanguageCode.get(languageCode);
483     }
484 
485     private static Log _log = LogFactory.getLog(LanguageImpl.class);
486 
487     private static Map _instances = CollectionFactory.getSyncHashMap();
488 
489     private Locale[] _locales;
490     private Map _localesByLanguageCode;
491     private Map _charEncodings;
492 
493 }