001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.language.LanguageUtil;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
021    
022    import java.util.HashMap;
023    import java.util.List;
024    import java.util.Locale;
025    import java.util.Map;
026    import java.util.Set;
027    import java.util.TreeMap;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     * @author Raymond Augé
032     */
033    public class LocaleUtil {
034    
035            public static boolean equals(Locale locale1, Locale locale2) {
036                    return getInstance()._equals(locale1, locale2);
037            }
038    
039            public static Locale fromLanguageId(String languageId) {
040                    return getInstance()._fromLanguageId(languageId, true);
041            }
042    
043            public static Locale fromLanguageId(String languageId, boolean validate) {
044                    return getInstance()._fromLanguageId(languageId, validate);
045            }
046    
047            public static Locale[] fromLanguageIds(List<String> languageIds) {
048                    return getInstance()._fromLanguageIds(languageIds);
049            }
050    
051            public static Locale[] fromLanguageIds(String[] languageIds) {
052                    return getInstance()._fromLanguageIds(languageIds);
053            }
054    
055            public static Locale getDefault() {
056                    return getInstance()._getDefault();
057            }
058    
059            public static LocaleUtil getInstance() {
060                    PortalRuntimePermission.checkGetBeanProperty(LocaleUtil.class);
061    
062                    return _instance;
063            }
064    
065            public static Map<String, String> getISOLanguages(Locale locale) {
066                    return getInstance()._getISOLanguages(locale);
067            }
068    
069            public static String getLongDisplayName(Locale locale) {
070                    return getInstance()._getLongDisplayName(locale);
071            }
072    
073            public static Locale getMostRelevantLocale() {
074                    return getInstance()._getMostRelevantLocale();
075            }
076    
077            public static String getShortDisplayName(
078                    Locale locale, Set<String> duplicateLanguages) {
079    
080                    return getInstance()._getShortDisplayName(locale, duplicateLanguages);
081            }
082    
083            public static void setDefault(
084                    String userLanguage, String userCountry, String userVariant) {
085    
086                    getInstance()._setDefault(userLanguage, userCountry, userVariant);
087            }
088    
089            public static String toLanguageId(Locale locale) {
090                    return getInstance()._toLanguageId(locale);
091            }
092    
093            public static String[] toLanguageIds(Locale[] locales) {
094                    return getInstance()._toLanguageIds(locales);
095            }
096    
097            public static String toW3cLanguageId(Locale locale) {
098                    return getInstance()._toW3cLanguageId(locale);
099            }
100    
101            public static String toW3cLanguageId(String languageId) {
102                    return getInstance()._toW3cLanguageId(languageId);
103            }
104    
105            public static String[] toW3cLanguageIds(Locale[] locales) {
106                    return getInstance()._toW3cLanguageIds(locales);
107            }
108    
109            public static String[] toW3cLanguageIds(String[] languageIds) {
110                    return getInstance()._toW3cLanguageIds(languageIds);
111            }
112    
113            private LocaleUtil() {
114                    _locale = new Locale("en", "US");
115            }
116    
117            private boolean _equals(Locale locale1, Locale locale2) {
118                    String languageId1 = _toLanguageId(locale1);
119                    String languageId2 = _toLanguageId(locale2);
120    
121                    return languageId1.equalsIgnoreCase(languageId2);
122            }
123    
124            private Locale _fromLanguageId(String languageId, boolean validate) {
125                    if (languageId == null) {
126                            return _locale;
127                    }
128    
129                    Locale locale = _locales.get(languageId);
130    
131                    if (locale != null) {
132                            return locale;
133                    }
134    
135                    try {
136                            int pos = languageId.indexOf(CharPool.UNDERLINE);
137    
138                            if (pos == -1) {
139                                    locale = new Locale(languageId);
140                            }
141                            else {
142                                    String[] languageIdParts = StringUtil.split(
143                                            languageId, CharPool.UNDERLINE);
144    
145                                    String languageCode = languageIdParts[0];
146                                    String countryCode = languageIdParts[1];
147    
148                                    String variant = null;
149    
150                                    if (languageIdParts.length > 2) {
151                                            variant = languageIdParts[2];
152                                    }
153    
154                                    if (Validator.isNotNull(variant)) {
155                                            locale = new Locale(languageCode, countryCode, variant);
156                                    }
157                                    else {
158                                            locale = new Locale(languageCode, countryCode);
159                                    }
160                            }
161    
162                            if (validate && !LanguageUtil.isAvailableLanguageCode(languageId)) {
163                                    throw new IllegalArgumentException("Invalid locale " + locale);
164                            }
165    
166                            _locales.put(languageId, locale);
167                    }
168                    catch (Exception e) {
169                            locale = null;
170    
171                            if (_log.isWarnEnabled()) {
172                                    _log.warn(languageId + " is not a valid language id");
173                            }
174                    }
175    
176                    if (locale == null) {
177                            locale = _locale;
178                    }
179    
180                    return locale;
181            }
182    
183            private Locale[] _fromLanguageIds(List<String> languageIds) {
184                    Locale[] locales = new Locale[languageIds.size()];
185    
186                    for (int i = 0; i < languageIds.size(); i++) {
187                            locales[i] = _fromLanguageId(languageIds.get(i), true);
188                    }
189    
190                    return locales;
191            }
192    
193            private Locale[] _fromLanguageIds(String[] languageIds) {
194                    Locale[] locales = new Locale[languageIds.length];
195    
196                    for (int i = 0; i < languageIds.length; i++) {
197                            locales[i] = _fromLanguageId(languageIds[i], true);
198                    }
199    
200                    return locales;
201            }
202    
203            private Locale _getDefault() {
204                    Locale locale = LocaleThreadLocal.getDefaultLocale();
205    
206                    if (locale != null) {
207                            return locale;
208                    }
209    
210                    return _locale;
211            }
212    
213            private Map<String, String> _getISOLanguages(Locale locale) {
214                    Map<String, String> isoLanguages = new TreeMap<String, String>(
215                            String.CASE_INSENSITIVE_ORDER);
216    
217                    for (String isoLanguageId : Locale.getISOLanguages()) {
218                            Locale isoLocale = _fromLanguageId(isoLanguageId, true);
219    
220                            isoLanguages.put(
221                                    isoLocale.getDisplayLanguage(locale), isoLanguageId);
222                    }
223    
224                    return isoLanguages;
225            }
226    
227            private String _getLongDisplayName(Locale locale) {
228                    String displayName = locale.getDisplayName(locale);
229    
230                    if (LanguageUtil.isBetaLocale(locale)) {
231                            return displayName.concat(_BETA_SUFFIX);
232                    }
233    
234                    return displayName;
235            }
236    
237            private Locale _getMostRelevantLocale() {
238                    Locale locale = LocaleThreadLocal.getThemeDisplayLocale();
239    
240                    if (locale == null) {
241                            locale = _getDefault();
242                    }
243    
244                    return locale;
245            }
246    
247            private String _getShortDisplayName(
248                    Locale locale, Set<String> duplicateLanguages) {
249    
250                    StringBundler sb = new StringBundler(6);
251    
252                    String language = locale.getDisplayLanguage(locale);
253    
254                    if (language.length() > 3) {
255                            language = locale.getLanguage();
256                            language = language.toUpperCase();
257                    }
258    
259                    sb.append(language);
260    
261                    if (duplicateLanguages.contains(locale.getLanguage())) {
262                            sb.append(StringPool.SPACE);
263                            sb.append(StringPool.OPEN_PARENTHESIS);
264    
265                            String country = locale.getCountry();
266    
267                            sb.append(country.toUpperCase());
268    
269                            sb.append(StringPool.CLOSE_PARENTHESIS);
270                    }
271    
272                    if (LanguageUtil.isBetaLocale(locale)) {
273                            sb.append(_BETA_SUFFIX);
274                    }
275    
276                    return sb.toString();
277            }
278    
279            private void _setDefault(
280                    String userLanguage, String userCountry, String userVariant) {
281    
282                    PortalRuntimePermission.checkSetBeanProperty(getClass());
283    
284                    if (Validator.isNotNull(userLanguage) &&
285                            Validator.isNull(userCountry) && Validator.isNull(userVariant)) {
286    
287                            _locale = new Locale(userLanguage);
288                    }
289                    else if (Validator.isNotNull(userLanguage) &&
290                                     Validator.isNotNull(userCountry) &&
291                                     Validator.isNull(userVariant)) {
292    
293                            _locale = new Locale(userLanguage, userCountry);
294                    }
295                    else if (Validator.isNotNull(userLanguage) &&
296                                     Validator.isNotNull(userCountry) &&
297                                     Validator.isNotNull(userVariant)) {
298    
299                            _locale = new Locale(userLanguage, userCountry, userVariant);
300                    }
301            }
302    
303            private String _toLanguageId(Locale locale) {
304                    if (locale == null) {
305                            locale = _locale;
306                    }
307    
308                    String country = locale.getCountry();
309    
310                    boolean hasCountry = false;
311    
312                    if (country.length() != 0) {
313                            hasCountry = true;
314                    }
315    
316                    String variant = locale.getVariant();
317    
318                    boolean hasVariant = false;
319    
320                    if (variant.length() != 0) {
321                            hasVariant = true;
322                    }
323    
324                    if (!hasCountry && !hasVariant) {
325                            return locale.getLanguage();
326                    }
327    
328                    int length = 3;
329    
330                    if (hasCountry && hasVariant) {
331                            length = 5;
332                    }
333    
334                    StringBundler sb = new StringBundler(length);
335    
336                    sb.append(locale.getLanguage());
337    
338                    if (hasCountry) {
339                            sb.append(StringPool.UNDERLINE);
340                            sb.append(country);
341                    }
342    
343                    if (hasVariant) {
344                            sb.append(StringPool.UNDERLINE);
345                            sb.append(variant);
346                    }
347    
348                    return sb.toString();
349            }
350    
351            private String[] _toLanguageIds(Locale[] locales) {
352                    String[] languageIds = new String[locales.length];
353    
354                    for (int i = 0; i < locales.length; i++) {
355                            languageIds[i] = _toLanguageId(locales[i]);
356                    }
357    
358                    return languageIds;
359            }
360    
361            private String _toW3cLanguageId(Locale locale) {
362                    return _toW3cLanguageId(_toLanguageId(locale));
363            }
364    
365            private String _toW3cLanguageId(String languageId) {
366                    return StringUtil.replace(
367                            languageId, CharPool.UNDERLINE, CharPool.MINUS);
368            }
369    
370            private String[] _toW3cLanguageIds(Locale[] locales) {
371                    return _toW3cLanguageIds(_toLanguageIds(locales));
372            }
373    
374            private String[] _toW3cLanguageIds(String[] languageIds) {
375                    String[] w3cLanguageIds = new String[languageIds.length];
376    
377                    for (int i = 0; i < languageIds.length; i++) {
378                            w3cLanguageIds[i] = _toW3cLanguageId(languageIds[i]);
379                    }
380    
381                    return w3cLanguageIds;
382            }
383    
384            private static final String _BETA_SUFFIX = " [Beta]";
385    
386            private static Log _log = LogFactoryUtil.getLog(LocaleUtil.class);
387    
388            private static LocaleUtil _instance = new LocaleUtil();
389    
390            private Locale _locale;
391            private Map<String, Locale> _locales = new HashMap<String, Locale>();
392    
393    }