001    /**
002     * Copyright (c) 2000-present 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.UTF8Control;
018    
019    import java.text.MessageFormat;
020    
021    import java.util.ArrayList;
022    import java.util.Deque;
023    import java.util.LinkedList;
024    import java.util.List;
025    import java.util.Locale;
026    import java.util.Map;
027    import java.util.MissingResourceException;
028    import java.util.ResourceBundle;
029    
030    /**
031     * @author Shuyang Zhou
032     * @author Neil Griffin
033     */
034    public class ResourceBundleUtil {
035    
036            public static ResourceBundle getBundle(String baseName, Class<?> clazz) {
037                    return getBundle(baseName, clazz.getClassLoader());
038            }
039    
040            public static ResourceBundle getBundle(
041                    String baseName, ClassLoader classLoader) {
042    
043                    return ResourceBundle.getBundle(
044                            baseName, Locale.getDefault(), classLoader, UTF8Control.INSTANCE);
045            }
046    
047            public static ResourceBundle getBundle(
048                    String baseName, Locale locale, Class<?> clazz) {
049    
050                    return getBundle(baseName, locale, clazz.getClassLoader());
051            }
052    
053            public static ResourceBundle getBundle(
054                    String baseName, Locale locale, ClassLoader classLoader) {
055    
056                    return ResourceBundle.getBundle(
057                            baseName, locale, classLoader, UTF8Control.INSTANCE);
058            }
059    
060            public static String getString(
061                    ResourceBundle resourceBundle, Locale locale, String key,
062                    Object[] arguments) {
063    
064                    String value = getString(resourceBundle, key);
065    
066                    if (value == null) {
067                            return null;
068                    }
069    
070                    // Get the value associated with the specified key, and substitute any
071                    // arguments like {0}, {1}, {2}, etc. with the specified argument
072                    // values.
073    
074                    if (ArrayUtil.isNotEmpty(arguments)) {
075                            MessageFormat messageFormat = new MessageFormat(value, locale);
076    
077                            value = messageFormat.format(arguments);
078                    }
079    
080                    return value;
081            }
082    
083            public static String getString(ResourceBundle resourceBundle, String key) {
084                    if (!resourceBundle.containsKey(key)) {
085                            return null;
086                    }
087    
088                    try {
089                            return resourceBundle.getString(key);
090                    }
091                    catch (MissingResourceException mre) {
092                            return null;
093                    }
094            }
095    
096            public static void loadResourceBundles(
097                    Map<String, ResourceBundle> resourceBundles, Locale locale,
098                    ResourceBundleLoader resourceBundleLoader) {
099    
100                    String languageId = LocaleUtil.toLanguageId(locale);
101    
102                    loadResourceBundles(resourceBundles, languageId, resourceBundleLoader);
103            }
104    
105            public static void loadResourceBundles(
106                    Map<String, ResourceBundle> resourceBundles, String languageId,
107                    ResourceBundleLoader resourceBundleLoader) {
108    
109                    Deque<ResourceBundle> currentResourceBundles = new LinkedList<>();
110    
111                    for (String currentLanguageId : _getLanguageIds(languageId)) {
112                            ResourceBundle resourceBundle =
113                                    resourceBundleLoader.loadResourceBundle(currentLanguageId);
114    
115                            if (resourceBundle != null) {
116                                    currentResourceBundles.addFirst(resourceBundle);
117                            }
118                            else if (currentResourceBundles.isEmpty()) {
119                                    continue;
120                            }
121    
122                            if (currentResourceBundles.size() == 1) {
123                                    resourceBundles.put(
124                                            currentLanguageId, currentResourceBundles.peek());
125                            }
126                            else {
127                                    int size = currentResourceBundles.size();
128    
129                                    resourceBundles.put(
130                                            currentLanguageId,
131                                            new AggregateResourceBundle(
132                                                    currentResourceBundles.toArray(
133                                                            new ResourceBundle[size])));
134                            }
135                    }
136            }
137    
138            public interface ResourceBundleLoader {
139    
140                    public ResourceBundle loadResourceBundle(String languageId);
141    
142            }
143    
144            private static List<String> _getLanguageIds(String languageId) {
145                    List<String> languageIds = new ArrayList<>();
146    
147                    languageIds.add(StringPool.BLANK);
148    
149                    int index = 0;
150    
151                    while ((index = languageId.indexOf(CharPool.UNDERLINE, index + 1)) !=
152                                            -1) {
153    
154                            languageIds.add(languageId.substring(0, index));
155                    }
156    
157                    languageIds.add(languageId);
158    
159                    return languageIds;
160            }
161    
162    }