001    /**
002     * Copyright (c) 2000-2011 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    
020    import java.util.Arrays;
021    import java.util.HashMap;
022    import java.util.Locale;
023    import java.util.Map;
024    import java.util.TreeMap;
025    
026    /**
027     * @author Brian Wing Shun Chan
028     */
029    public class LocaleUtil {
030    
031            public static Locale fromLanguageId(String languageId) {
032                    return _instance._fromLanguageId(languageId);
033            }
034    
035            public static Locale[] fromLanguageIds(String[] languageIds) {
036                    return _instance._fromLanguageIds(languageIds);
037            }
038    
039            public static Locale getDefault() {
040                    return _instance._getDefault();
041            }
042    
043            public static LocaleUtil getInstance() {
044                    return _instance;
045            }
046    
047            public static Map<String, String> getISOLanguages(Locale locale) {
048                    return _instance._getISOLanguages(locale);
049            }
050    
051            public static void setDefault(
052                    String userLanguage, String userCountry, String userVariant) {
053    
054                    _instance._setDefault(userLanguage, userCountry, userVariant);
055            }
056    
057            public static String toLanguageId(Locale locale) {
058                    return _instance._toLanguageId(locale);
059            }
060    
061            public static String[] toLanguageIds(Locale[] locales) {
062                    return _instance._toLanguageIds(locales);
063            }
064    
065            public static String toW3cLanguageId(Locale locale) {
066                    return _instance._toW3cLanguageId(locale);
067            }
068    
069            public static String toW3cLanguageId(String languageId) {
070                    return _instance._toW3cLanguageId(languageId);
071            }
072    
073            public static String[] toW3cLanguageIds(Locale[] locales) {
074                    return _instance._toW3cLanguageIds(locales);
075            }
076    
077            public static String[] toW3cLanguageIds(String[] languageIds) {
078                    return _instance._toW3cLanguageIds(languageIds);
079            }
080    
081            private LocaleUtil() {
082                    _locale = new Locale("en", "US");
083    
084                    _isoCountries = Locale.getISOCountries().clone();
085    
086                    for (int i = 0; i < _isoCountries.length; i++) {
087                            _isoCountries[i] = _isoCountries[i].toUpperCase();
088                    }
089    
090                    Arrays.sort(_isoCountries);
091    
092                    _isoLanguages = Locale.getISOLanguages().clone();
093    
094                    for (int i = 0; i < _isoLanguages.length; i++) {
095                            _isoLanguages[i] = _isoLanguages[i].toLowerCase();
096                    }
097    
098                    Arrays.sort(_isoLanguages);
099            }
100    
101            private Locale _fromLanguageId(String languageId) {
102                    if (languageId == null) {
103                            return _locale;
104                    }
105    
106                    Locale locale = null;
107    
108                    try {
109                            locale = _locales.get(languageId);
110    
111                            if (locale == null) {
112                                    int pos = languageId.indexOf(CharPool.UNDERLINE);
113    
114                                    if (pos == -1) {
115                                            if (Arrays.binarySearch(_isoLanguages, languageId) < 0) {
116                                                    return _getDefault();
117                                            }
118    
119                                            locale = new Locale(languageId);
120                                    }
121                                    else {
122                                            String[] languageIdParts = StringUtil.split(
123                                                    languageId, StringPool.UNDERLINE);
124    
125                                            String languageCode = languageIdParts[0];
126                                            String countryCode = languageIdParts[1];
127    
128                                            if ((Arrays.binarySearch(
129                                                            _isoLanguages, languageCode) < 0) ||
130                                                    (Arrays.binarySearch(_isoCountries, countryCode) < 0)) {
131    
132                                                    return _getDefault();
133                                            }
134    
135                                            String variant = null;
136    
137                                            if (languageIdParts.length > 2) {
138                                                    variant = languageIdParts[2];
139                                            }
140    
141                                            if (Validator.isNotNull(variant)) {
142                                                    locale = new Locale(languageCode, countryCode, variant);
143                                            }
144                                            else {
145                                                    locale = new Locale(languageCode, countryCode);
146                                            }
147                                    }
148    
149                                    _locales.put(languageId, locale);
150                            }
151                    }
152                    catch (Exception e) {
153                            if (_log.isWarnEnabled()) {
154                                    _log.warn(languageId + " is not a valid language id");
155                            }
156                    }
157    
158                    if (locale == null) {
159                            locale = _locale;
160                    }
161    
162                    return locale;
163            }
164    
165            private Locale[] _fromLanguageIds(String[] languageIds) {
166                    Locale[] locales = new Locale[languageIds.length];
167    
168                    for (int i = 0; i < languageIds.length; i++) {
169                            locales[i] = _fromLanguageId(languageIds[i]);
170                    }
171    
172                    return locales;
173            }
174    
175            private Locale _getDefault() {
176                    Locale locale = LocaleThreadLocal.getLocale();
177    
178                    if (locale != null) {
179                            return locale;
180                    }
181    
182                    return _locale;
183            }
184    
185            private Map<String, String> _getISOLanguages(Locale locale) {
186                    Map<String, String> isoLanguages = new TreeMap<String, String>(
187                            String.CASE_INSENSITIVE_ORDER);
188    
189                    for (String isoLanguageId : Locale.getISOLanguages()) {
190                            Locale isoLocale = _fromLanguageId(isoLanguageId);
191    
192                            isoLanguages.put(
193                                    isoLocale.getDisplayLanguage(locale), isoLanguageId);
194                    }
195    
196                    return isoLanguages;
197            }
198    
199            private void _setDefault(
200                    String userLanguage, String userCountry, String userVariant) {
201    
202                    if (Validator.isNotNull(userLanguage) &&
203                            Validator.isNull(userCountry) && Validator.isNull(userVariant)) {
204    
205                            _locale = new Locale(userLanguage);
206                    }
207                    else if (Validator.isNotNull(userLanguage) &&
208                                     Validator.isNotNull(userCountry) &&
209                                     Validator.isNull(userVariant)) {
210    
211                            _locale = new Locale(userLanguage, userCountry);
212                    }
213                    else if (Validator.isNotNull(userLanguage) &&
214                                     Validator.isNotNull(userCountry) &&
215                                     Validator.isNotNull(userVariant)) {
216    
217                            _locale = new Locale(userLanguage, userCountry, userVariant);
218                    }
219            }
220    
221            private String _toLanguageId(Locale locale) {
222                    if (locale == null) {
223                            locale = _locale;
224                    }
225    
226                    String country = locale.getCountry();
227    
228                    boolean hasCountry = false;
229    
230                    if (country.length() != 0) {
231                            hasCountry = true;
232                    }
233    
234                    String variant = locale.getVariant();
235    
236                    boolean hasVariant = false;
237    
238                    if (variant.length() != 0) {
239                            hasCountry = true;
240                    }
241    
242                    if (!hasCountry && !hasVariant) {
243                            return locale.getLanguage();
244                    }
245    
246                    int length = 3;
247    
248                    if (hasCountry && hasVariant) {
249                            length = 5;
250                    }
251    
252                    StringBundler sb = new StringBundler(length);
253    
254                    sb.append(locale.getLanguage());
255    
256                    if (hasCountry) {
257                            sb.append(StringPool.UNDERLINE);
258                            sb.append(country);
259                    }
260    
261                    if (hasVariant) {
262                            sb.append(StringPool.UNDERLINE);
263                            sb.append(variant);
264                    }
265    
266                    return sb.toString();
267            }
268    
269            private String[] _toLanguageIds(Locale[] locales) {
270                    String[] languageIds = new String[locales.length];
271    
272                    for (int i = 0; i < locales.length; i++) {
273                            languageIds[i] = _toLanguageId(locales[i]);
274                    }
275    
276                    return languageIds;
277            }
278    
279            private String _toW3cLanguageId(Locale locale) {
280                    return _toW3cLanguageId(_toLanguageId(locale));
281            }
282    
283            private String _toW3cLanguageId(String languageId) {
284                    return StringUtil.replace(
285                            languageId, CharPool.UNDERLINE, CharPool.MINUS);
286            }
287    
288            private String[] _toW3cLanguageIds(Locale[] locales) {
289                    return _toW3cLanguageIds(_toLanguageIds(locales));
290            }
291    
292            private String[] _toW3cLanguageIds(String[] languageIds) {
293                    String[] w3cLanguageIds = new String[languageIds.length];
294    
295                    for (int i = 0; i < languageIds.length; i++) {
296                            w3cLanguageIds[i] = _toW3cLanguageId(languageIds[i]);
297                    }
298    
299                    return w3cLanguageIds;
300            }
301    
302            private static Log _log = LogFactoryUtil.getLog(LocaleUtil.class);
303    
304            private static LocaleUtil _instance = new LocaleUtil();
305    
306            private String[] _isoCountries;
307            private String[] _isoLanguages;
308            private Locale _locale;
309            private Map<String, Locale> _locales = new HashMap<String, Locale>();
310    
311    }