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