001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
020    
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Locale;
024    import java.util.Map;
025    import java.util.TreeMap;
026    
027    /**
028     * @author Brian Wing Shun Chan
029     * @author Raymond Augé
030     */
031    public class LocaleUtil {
032    
033            public static boolean equals(Locale locale1, Locale locale2) {
034                    return getInstance()._equals(locale1, locale2);
035            }
036    
037            public static Locale fromLanguageId(String languageId) {
038                    return getInstance()._fromLanguageId(languageId);
039            }
040    
041            public static Locale[] fromLanguageIds(List<String> languageIds) {
042                    return getInstance()._fromLanguageIds(languageIds);
043            }
044    
045            public static Locale[] fromLanguageIds(String[] languageIds) {
046                    return getInstance()._fromLanguageIds(languageIds);
047            }
048    
049            public static Locale getDefault() {
050                    return getInstance()._getDefault();
051            }
052    
053            public static LocaleUtil getInstance() {
054                    PortalRuntimePermission.checkGetBeanProperty(LocaleUtil.class);
055    
056                    return _instance;
057            }
058    
059            public static Map<String, String> getISOLanguages(Locale locale) {
060                    return getInstance()._getISOLanguages(locale);
061            }
062    
063            public static Locale getMostRelevantLocale() {
064                    return getInstance()._getMostRelevantLocale();
065            }
066    
067            public static void setDefault(
068                    String userLanguage, String userCountry, String userVariant) {
069    
070                    getInstance()._setDefault(userLanguage, userCountry, userVariant);
071            }
072    
073            public static String toLanguageId(Locale locale) {
074                    return getInstance()._toLanguageId(locale);
075            }
076    
077            public static String[] toLanguageIds(Locale[] locales) {
078                    return getInstance()._toLanguageIds(locales);
079            }
080    
081            public static String toW3cLanguageId(Locale locale) {
082                    return getInstance()._toW3cLanguageId(locale);
083            }
084    
085            public static String toW3cLanguageId(String languageId) {
086                    return getInstance()._toW3cLanguageId(languageId);
087            }
088    
089            public static String[] toW3cLanguageIds(Locale[] locales) {
090                    return getInstance()._toW3cLanguageIds(locales);
091            }
092    
093            public static String[] toW3cLanguageIds(String[] languageIds) {
094                    return getInstance()._toW3cLanguageIds(languageIds);
095            }
096    
097            private LocaleUtil() {
098                    _locale = new Locale("en", "US");
099            }
100    
101            private boolean _equals(Locale locale1, Locale locale2) {
102                    String languageId1 = _toLanguageId(locale1);
103                    String languageId2 = _toLanguageId(locale2);
104    
105                    return languageId1.equalsIgnoreCase(languageId2);
106            }
107    
108            private Locale _fromLanguageId(String languageId) {
109                    if (languageId == null) {
110                            return _locale;
111                    }
112    
113                    Locale locale = _locales.get(languageId);
114    
115                    if (locale != null) {
116                            return locale;
117                    }
118    
119                    try {
120                            int pos = languageId.indexOf(CharPool.UNDERLINE);
121    
122                            if (pos == -1) {
123                                    locale = new Locale(languageId);
124                            }
125                            else {
126                                    String[] languageIdParts = StringUtil.split(
127                                            languageId, CharPool.UNDERLINE);
128    
129                                    String languageCode = languageIdParts[0];
130                                    String countryCode = languageIdParts[1];
131    
132                                    String variant = null;
133    
134                                    if (languageIdParts.length > 2) {
135                                            variant = languageIdParts[2];
136                                    }
137    
138                                    if (Validator.isNotNull(variant)) {
139                                            locale = new Locale(languageCode, countryCode, variant);
140                                    }
141                                    else {
142                                            locale = new Locale(languageCode, countryCode);
143                                    }
144                            }
145    
146                            if (_locales.size() < _MAX_LOCALES) {
147                                    _locales.put(languageId, locale);
148                            }
149                            else {
150                                    if (_log.isWarnEnabled()) {
151                                            _log.warn("There are too many entries in the locales map");
152                                    }
153                            }
154                    }
155                    catch (Exception e) {
156                            if (_log.isWarnEnabled()) {
157                                    _log.warn(languageId + " is not a valid language id");
158                            }
159                    }
160    
161                    if (locale == null) {
162                            locale = _locale;
163                    }
164    
165                    return locale;
166            }
167    
168            private Locale[] _fromLanguageIds(List<String> languageIds) {
169                    Locale[] locales = new Locale[languageIds.size()];
170    
171                    for (int i = 0; i < languageIds.size(); i++) {
172                            locales[i] = _fromLanguageId(languageIds.get(i));
173                    }
174    
175                    return locales;
176            }
177    
178            private Locale[] _fromLanguageIds(String[] languageIds) {
179                    Locale[] locales = new Locale[languageIds.length];
180    
181                    for (int i = 0; i < languageIds.length; i++) {
182                            locales[i] = _fromLanguageId(languageIds[i]);
183                    }
184    
185                    return locales;
186            }
187    
188            private Locale _getDefault() {
189                    Locale locale = LocaleThreadLocal.getDefaultLocale();
190    
191                    if (locale != null) {
192                            return locale;
193                    }
194    
195                    return _locale;
196            }
197    
198            private Map<String, String> _getISOLanguages(Locale locale) {
199                    Map<String, String> isoLanguages = new TreeMap<String, String>(
200                            String.CASE_INSENSITIVE_ORDER);
201    
202                    for (String isoLanguageId : Locale.getISOLanguages()) {
203                            Locale isoLocale = _fromLanguageId(isoLanguageId);
204    
205                            isoLanguages.put(
206                                    isoLocale.getDisplayLanguage(locale), isoLanguageId);
207                    }
208    
209                    return isoLanguages;
210            }
211    
212            private Locale _getMostRelevantLocale() {
213                    Locale locale = LocaleThreadLocal.getThemeDisplayLocale();
214    
215                    if (locale == null) {
216                            locale = _getDefault();
217                    }
218    
219                    return locale;
220            }
221    
222            private void _setDefault(
223                    String userLanguage, String userCountry, String userVariant) {
224    
225                    PortalRuntimePermission.checkSetBeanProperty(getClass());
226    
227                    if (Validator.isNotNull(userLanguage) &&
228                            Validator.isNull(userCountry) && Validator.isNull(userVariant)) {
229    
230                            _locale = new Locale(userLanguage);
231                    }
232                    else if (Validator.isNotNull(userLanguage) &&
233                                     Validator.isNotNull(userCountry) &&
234                                     Validator.isNull(userVariant)) {
235    
236                            _locale = new Locale(userLanguage, userCountry);
237                    }
238                    else if (Validator.isNotNull(userLanguage) &&
239                                     Validator.isNotNull(userCountry) &&
240                                     Validator.isNotNull(userVariant)) {
241    
242                            _locale = new Locale(userLanguage, userCountry, userVariant);
243                    }
244            }
245    
246            private String _toLanguageId(Locale locale) {
247                    if (locale == null) {
248                            locale = _locale;
249                    }
250    
251                    String country = locale.getCountry();
252    
253                    boolean hasCountry = false;
254    
255                    if (country.length() != 0) {
256                            hasCountry = true;
257                    }
258    
259                    String variant = locale.getVariant();
260    
261                    boolean hasVariant = false;
262    
263                    if (variant.length() != 0) {
264                            hasVariant = true;
265                    }
266    
267                    if (!hasCountry && !hasVariant) {
268                            return locale.getLanguage();
269                    }
270    
271                    int length = 3;
272    
273                    if (hasCountry && hasVariant) {
274                            length = 5;
275                    }
276    
277                    StringBundler sb = new StringBundler(length);
278    
279                    sb.append(locale.getLanguage());
280    
281                    if (hasCountry) {
282                            sb.append(StringPool.UNDERLINE);
283                            sb.append(country);
284                    }
285    
286                    if (hasVariant) {
287                            sb.append(StringPool.UNDERLINE);
288                            sb.append(variant);
289                    }
290    
291                    return sb.toString();
292            }
293    
294            private String[] _toLanguageIds(Locale[] locales) {
295                    String[] languageIds = new String[locales.length];
296    
297                    for (int i = 0; i < locales.length; i++) {
298                            languageIds[i] = _toLanguageId(locales[i]);
299                    }
300    
301                    return languageIds;
302            }
303    
304            private String _toW3cLanguageId(Locale locale) {
305                    return _toW3cLanguageId(_toLanguageId(locale));
306            }
307    
308            private String _toW3cLanguageId(String languageId) {
309                    return StringUtil.replace(
310                            languageId, CharPool.UNDERLINE, CharPool.MINUS);
311            }
312    
313            private String[] _toW3cLanguageIds(Locale[] locales) {
314                    return _toW3cLanguageIds(_toLanguageIds(locales));
315            }
316    
317            private String[] _toW3cLanguageIds(String[] languageIds) {
318                    String[] w3cLanguageIds = new String[languageIds.length];
319    
320                    for (int i = 0; i < languageIds.length; i++) {
321                            w3cLanguageIds[i] = _toW3cLanguageId(languageIds[i]);
322                    }
323    
324                    return w3cLanguageIds;
325            }
326    
327            private static final int _MAX_LOCALES = 1000;
328    
329            private static Log _log = LogFactoryUtil.getLog(LocaleUtil.class);
330    
331            private static LocaleUtil _instance = new LocaleUtil();
332    
333            private Locale _locale;
334            private Map<String, Locale> _locales = new HashMap<String, Locale>();
335    
336    }