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