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             value = resources.getMessage(locale, key);
270         }
271         catch (Exception e) {
272             if (_log.isWarnEnabled()) {
273                 _log.warn(e.getMessage());
274             }
275         }
276 
277         if (value == null) {
278             value = defaultValue;
279         }
280 
281         return value;
282     }
283 
284     public String get(PageContext pageContext, String key) {
285         return get(pageContext, key, key);
286     }
287 
288     public String get(
289         PageContext pageContext, String key, String defaultValue) {
290 
291         if (key == null) {
292             return null;
293         }
294 
295         String value = null;
296 
297         try {
298             value = TagUtils.getInstance().message(
299                 pageContext, null, null, key);
300         }
301         catch (Exception e) {
302             _log.error(e);
303         }
304 
305         if (value == null) {
306 
307             // LEP-2849
308 
309             HttpServletRequest req =
310                 (HttpServletRequest)pageContext.getRequest();
311 
312             PortletConfig portletConfig = (PortletConfig)req.getAttribute(
313                 JavaConstants.JAVAX_PORTLET_CONFIG);
314 
315             if (portletConfig != null) {
316                 Locale locale = req.getLocale();
317 
318                 ResourceBundle bundle = portletConfig.getResourceBundle(locale);
319 
320                 try {
321                     value = bundle.getString(key);
322                 }
323                 catch (MissingResourceException mre) {
324                 }
325             }
326         }
327 
328         if (value == null) {
329             value = defaultValue;
330         }
331 
332         return value;
333     }
334 
335     public Locale[] getAvailableLocales() {
336         return _getInstance()._locales;
337     }
338 
339     public String getCharset(Locale locale) {
340         return _getInstance()._getCharset(locale);
341     }
342 
343     public String getLanguageId(ActionRequest req) {
344         HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
345 
346         return getLanguageId(httpReq);
347     }
348 
349     public String getLanguageId(RenderRequest req) {
350         HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
351 
352         return getLanguageId(httpReq);
353     }
354 
355     public String getLanguageId(HttpServletRequest req) {
356         String languageId = ParamUtil.getString(req, "languageId");
357 
358         if (Validator.isNotNull(languageId)) {
359             return languageId;
360         }
361 
362         Locale locale =
363             (Locale)req.getSession().getAttribute(Globals.LOCALE_KEY);
364 
365         if (locale == null) {
366             languageId = CookieUtil.get(
367                 req.getCookies(), CookieKeys.GUEST_LANGUAGE_ID);
368 
369             if (Validator.isNotNull(languageId)) {
370                 locale = LocaleUtil.fromLanguageId(languageId);
371             }
372         }
373 
374         return getLanguageId(locale);
375     }
376 
377     public String getLanguageId(Locale locale) {
378         return LocaleUtil.toLanguageId(locale);
379     }
380 
381     public Locale getLocale(String languageCode) {
382         return _getInstance()._getLocale(languageCode);
383     }
384 
385     public String getTimeDescription(
386         PageContext pageContext, Long milliseconds) {
387 
388         return getTimeDescription(pageContext, milliseconds.longValue());
389     }
390 
391     public String getTimeDescription(
392         PageContext pageContext, long milliseconds) {
393 
394         String desc = Time.getDescription(milliseconds);
395 
396         String value = null;
397 
398         try {
399             int pos = desc.indexOf(StringPool.SPACE);
400 
401             int x = GetterUtil.getInteger(desc.substring(0, pos));
402 
403             value =
404                 x + " " +
405                 get(
406                     pageContext,
407                     desc.substring(pos + 1, desc.length()).toLowerCase());
408         }
409         catch (Exception e) {
410             if (_log.isWarnEnabled()) {
411                 _log.warn(e.getMessage());
412             }
413         }
414 
415         return value;
416     }
417 
418     public void updateCookie(HttpServletResponse res, Locale locale) {
419         String languageId = LocaleUtil.toLanguageId(locale);
420 
421         Cookie languageIdCookie = new Cookie(
422             CookieKeys.GUEST_LANGUAGE_ID, languageId);
423 
424         languageIdCookie.setPath(StringPool.SLASH);
425         languageIdCookie.setMaxAge(CookieKeys.MAX_AGE);
426 
427         CookieKeys.addCookie(res, languageIdCookie);
428     }
429 
430     private static LanguageImpl _getInstance() {
431         Long companyIdObj = new Long(CompanyThreadLocal.getCompanyId());
432 
433         LanguageImpl instance = (LanguageImpl)_instances.get(companyIdObj);
434 
435         if (instance == null) {
436             instance = new LanguageImpl();
437 
438             _instances.put(companyIdObj, instance);
439         }
440 
441         return instance;
442     }
443 
444     private LanguageImpl() {
445         String[] array = StringUtil.split(
446             PropsUtil.get(PropsUtil.LOCALES), StringPool.COMMA);
447 
448         _locales = new Locale[array.length];
449         _localesByLanguageCode = CollectionFactory.getHashMap();
450         _charEncodings = CollectionFactory.getHashMap();
451 
452         for (int i = 0; i < array.length; i++) {
453             String languageId = array[i];
454 
455             int x = languageId.indexOf(StringPool.UNDERLINE);
456 
457             String language = array[i].substring(0, x);
458             //String country = array[i].substring(x + 1, array[i].length());
459 
460             Locale locale = LocaleUtil.fromLanguageId(languageId);
461 
462             _locales[i] = locale;
463             _localesByLanguageCode.put(language, locale);
464             _charEncodings.put(locale.toString(), DEFAULT_ENCODING);
465         }
466     }
467 
468     private String _getCharset(Locale locale) {
469         return DEFAULT_ENCODING;
470     }
471 
472     private Locale _getLocale(String languageCode) {
473         return (Locale)_localesByLanguageCode.get(languageCode);
474     }
475 
476     private static Log _log = LogFactory.getLog(LanguageImpl.class);
477 
478     private static Map _instances = CollectionFactory.getSyncHashMap();
479 
480     private Locale[] _locales;
481     private Map _localesByLanguageCode;
482     private Map _charEncodings;
483 
484 }