001    /**
002     * Copyright (c) 2000-2010 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.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    
025    /**
026     * @author Brian Wing Shun Chan
027     */
028    public class LocaleUtil {
029    
030            public static Locale fromLanguageId(String languageId) {
031                    return _instance._fromLanguageId(languageId);
032            }
033    
034            public static Locale[] fromLanguageIds(String[] languageIds) {
035                    return _instance._fromLanguageIds(languageIds);
036            }
037    
038            public static Locale getDefault() {
039                    return _instance._getDefault();
040            }
041    
042            public static LocaleUtil getInstance() {
043                    return _instance;
044            }
045    
046            public static void setDefault(
047                    String userLanguage, String userCountry, String userVariant) {
048    
049                    _instance._setDefault(userLanguage, userCountry, userVariant);
050            }
051    
052            public static String toLanguageId(Locale locale) {
053                    return _instance._toLanguageId(locale);
054            }
055    
056            public static String[] toLanguageIds(Locale[] locales) {
057                    return _instance._toLanguageIds(locales);
058            }
059    
060            public static String toW3cLanguageId(Locale locale) {
061                    return _instance._toW3cLanguageId(locale);
062            }
063    
064            public static String toW3cLanguageId(String languageId) {
065                    return _instance._toW3cLanguageId(languageId);
066            }
067    
068            public static String[] toW3cLanguageIds(Locale[] locales) {
069                    return _instance._toW3cLanguageIds(locales);
070            }
071    
072            public static String[] toW3cLanguageIds(String[] languageIds) {
073                    return _instance._toW3cLanguageIds(languageIds);
074            }
075    
076            private LocaleUtil() {
077                    _locale = new Locale("en", "US");
078    
079                    _isoCountries = Locale.getISOCountries().clone();
080    
081                    for (int i = 0; i < _isoCountries.length; i++) {
082                            _isoCountries[i] = _isoCountries[i].toUpperCase();
083                    }
084    
085                    Arrays.sort(_isoCountries);
086    
087                    _isoLanguages = Locale.getISOLanguages().clone();
088    
089                    for (int i = 0; i < _isoLanguages.length; i++) {
090                            _isoLanguages[i] = _isoLanguages[i].toLowerCase();
091                    }
092    
093                    Arrays.sort(_isoLanguages);
094            }
095    
096            private Locale _fromLanguageId(String languageId) {
097                    if (languageId == null) {
098                            return _locale;
099                    }
100    
101                    Locale locale = null;
102    
103                    try {
104                            locale = _locales.get(languageId);
105    
106                            if (locale == null) {
107                                    int pos = languageId.indexOf(StringPool.UNDERLINE);
108    
109                                    if (pos == -1) {
110                                            if (Arrays.binarySearch(_isoLanguages, languageId) < 0) {
111                                                    return _getDefault();
112                                            }
113    
114                                            locale = new Locale(languageId);
115                                    }
116                                    else {
117                                            String languageCode = languageId.substring(0, pos);
118                                            String countryCode = languageId.substring(
119                                                    pos + 1, languageId.length());
120    
121                                            if ((Arrays.binarySearch(
122                                                            _isoLanguages, languageCode) < 0) ||
123                                                    (Arrays.binarySearch(_isoCountries, countryCode) < 0)) {
124    
125                                                    return _getDefault();
126                                            }
127    
128                                            locale = new Locale(languageCode, countryCode);
129                                    }
130    
131                                    _locales.put(languageId, locale);
132                            }
133                    }
134                    catch (Exception e) {
135                            if (_log.isWarnEnabled()) {
136                                    _log.warn(languageId + " is not a valid language id");
137                            }
138                    }
139    
140                    if (locale == null) {
141                            locale = _locale;
142                    }
143    
144                    return locale;
145            }
146    
147            private Locale[] _fromLanguageIds(String[] languageIds) {
148                    Locale[] locales = new Locale[languageIds.length];
149    
150                    for (int i = 0; i < languageIds.length; i++) {
151                            locales[i] = _fromLanguageId(languageIds[i]);
152                    }
153    
154                    return locales;
155            }
156    
157            private Locale _getDefault() {
158                    Locale locale = LocaleThreadLocal.getLocale();
159    
160                    if (locale != null) {
161                            return locale;
162                    }
163    
164                    return _locale;
165            }
166    
167            public void _setDefault(
168                    String userLanguage, String userCountry, String userVariant) {
169    
170                    if (Validator.isNotNull(userLanguage) &&
171                            Validator.isNull(userCountry) && Validator.isNull(userVariant)) {
172    
173                            _locale = new Locale(userLanguage);
174                    }
175                    else if (Validator.isNotNull(userLanguage) &&
176                                     Validator.isNotNull(userCountry) &&
177                                     Validator.isNull(userVariant)) {
178    
179                            _locale = new Locale(userLanguage, userCountry);
180                    }
181                    else if (Validator.isNotNull(userLanguage) &&
182                                     Validator.isNotNull(userCountry) &&
183                                     Validator.isNotNull(userVariant)) {
184    
185                            _locale = new Locale(userLanguage, userCountry, userVariant);
186                    }
187            }
188    
189            private String _toLanguageId(Locale locale) {
190                    if (locale == null) {
191                            locale = _locale;
192                    }
193    
194                    String languageId = locale.getLanguage();
195    
196                    if (Validator.isNotNull(locale.getCountry())) {
197                            languageId = languageId.concat(StringPool.UNDERLINE);
198                            languageId = languageId.concat(locale.getCountry());
199                    }
200    
201                    return languageId;
202            }
203    
204            private String[] _toLanguageIds(Locale[] locales) {
205                    String[] languageIds = new String[locales.length];
206    
207                    for (int i = 0; i < locales.length; i++) {
208                            languageIds[i] = _toLanguageId(locales[i]);
209                    }
210    
211                    return languageIds;
212            }
213    
214            private String _toW3cLanguageId(Locale locale) {
215                    return _toW3cLanguageId(_toLanguageId(locale));
216            }
217    
218            private String _toW3cLanguageId(String languageId) {
219                    return StringUtil.replace(
220                            languageId, StringPool.UNDERLINE, StringPool.MINUS);
221            }
222    
223            private String[] _toW3cLanguageIds(Locale[] locales) {
224                    return _toW3cLanguageIds(_toLanguageIds(locales));
225            }
226    
227            private String[] _toW3cLanguageIds(String[] languageIds) {
228                    String[] w3cLanguageIds = new String[languageIds.length];
229    
230                    for (int i = 0; i < languageIds.length; i++) {
231                            w3cLanguageIds[i] = _toW3cLanguageId(languageIds[i]);
232                    }
233    
234                    return w3cLanguageIds;
235            }
236    
237            private static Log _log = LogFactoryUtil.getLog(LocaleUtil.class);
238    
239            private static LocaleUtil _instance = new LocaleUtil();
240    
241            private String[] _isoCountries;
242            private String[] _isoLanguages;
243            private Locale _locale;
244            private Map<String, Locale> _locales = new HashMap<String, Locale>();
245    
246    }