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.language;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.StringBundler;
020    import com.liferay.portal.kernel.util.StringPool;
021    import com.liferay.portal.kernel.util.StringUtil;
022    import com.liferay.portal.kernel.util.Validator;
023    
024    import java.io.InputStream;
025    
026    import java.net.URL;
027    
028    import java.util.Collections;
029    import java.util.HashMap;
030    import java.util.Locale;
031    import java.util.Map;
032    import java.util.Properties;
033    import java.util.concurrent.ConcurrentHashMap;
034    
035    /**
036     * @author Shuyang Zhou
037     */
038    public class LanguageResources {
039    
040            public static String getMessage(Locale locale, String key) {
041                    if (locale == null) {
042                            return null;
043                    }
044    
045                    Map<String, String> languageMap = _languageMaps.get(locale);
046    
047                    if (languageMap == null) {
048                            languageMap = loadLocale(locale);
049                    }
050    
051                    String value = languageMap.get(key);
052    
053                    if (value == null) {
054                            return getMessage(getSuperLocale(locale), key);
055                    }
056                    else {
057                            return value;
058                    }
059            }
060    
061            public static Map<String, String> putLanguageMap(
062                    Locale locale, Map<String, String> languageMap) {
063    
064                    Map<String, String> oldLanguageMap = _languageMaps.get(locale);
065    
066                    if (oldLanguageMap == null) {
067                            loadLocale(locale);
068                            oldLanguageMap = _languageMaps.get(locale);
069                    }
070    
071                    Map<String, String> newLanguageMap = new HashMap<String, String>();
072    
073                    if (oldLanguageMap != null) {
074                            newLanguageMap.putAll(oldLanguageMap);
075                    }
076    
077                    newLanguageMap.putAll(languageMap);
078    
079                    _languageMaps.put(locale, newLanguageMap);
080    
081                    return oldLanguageMap;
082            }
083    
084            public void setConfig(String config) {
085                    _config = config;
086            }
087    
088            private static Locale getSuperLocale(Locale locale) {
089                    if (Validator.isNotNull(locale.getVariant())) {
090                            return new Locale(locale.getLanguage(), locale.getCountry());
091                    }
092    
093                    if (Validator.isNotNull(locale.getCountry())) {
094                            return new Locale(locale.getLanguage());
095                    }
096    
097                    if (Validator.isNotNull(locale.getLanguage())) {
098                            return new Locale(StringPool.BLANK);
099                    }
100    
101                    return null;
102            }
103    
104            private static Map<String, String> loadLocale(Locale locale) {
105                    String[] names = StringUtil.split(
106                            _config.replace(StringPool.PERIOD, StringPool.SLASH));
107    
108                    Map<String, String> languageMap = null;
109    
110                    if (names.length > 0) {
111                            String localeName = locale.toString();
112    
113                            languageMap = new HashMap<String, String>();
114    
115                            for (String name : names) {
116                                    StringBundler sb = new StringBundler(4);
117    
118                                    sb.append(name);
119    
120                                    if (localeName.length() > 0) {
121                                            sb.append(StringPool.UNDERLINE);
122                                            sb.append(localeName);
123                                    }
124    
125                                    sb.append(".properties");
126    
127                                    Properties properties = loadProperties(sb.toString());
128    
129                                    for (Map.Entry<Object, Object> entry : properties.entrySet()) {
130                                            String key = (String)entry.getKey();
131                                            String value = (String)entry.getValue();
132    
133                                            languageMap.put(key, value);
134                                    }
135                            }
136                    }
137                    else {
138                            languageMap = Collections.EMPTY_MAP;
139                    }
140    
141                    _languageMaps.put(locale, languageMap);
142    
143                    return languageMap;
144            }
145    
146            private static Properties loadProperties(String name) {
147                    Properties properties = new Properties();
148    
149                    try {
150                            ClassLoader classLoader = LanguageResources.class.getClassLoader();
151    
152                            URL url = classLoader.getResource(name);
153    
154                            if (_log.isInfoEnabled()) {
155                                    _log.info("Attempting to load " + name);
156                            }
157    
158                            if (url != null) {
159                                    InputStream inputStream = url.openStream();
160    
161                                    properties.load(inputStream);
162    
163                                    inputStream.close();
164    
165                                    if (_log.isInfoEnabled()) {
166                                            _log.info(
167                                                    "Loading " + url + " with " + properties.size() +
168                                                            " values");
169                                    }
170                            }
171                    }
172                    catch (Exception e) {
173                            if (_log.isWarnEnabled()) {
174                                    _log.warn(e, e);
175                            }
176                    }
177    
178                    return properties;
179            }
180    
181            private static Log _log = LogFactoryUtil.getLog(LanguageResources.class);
182    
183            private static String _config;
184            private static Map<Locale, Map<String, String>> _languageMaps =
185                    new ConcurrentHashMap<Locale, Map<String, String>>(64);
186    
187    }