View Javadoc

1   /*
2    * Copyright (c) 2009 QOS.ch All rights reserved.
3    * 
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   * 
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   * 
14   * THE SOFTWARE IS PROVIDED "AS  IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  package ch.qos.cal10n.util;
23  
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.io.Reader;
28  import java.io.UnsupportedEncodingException;
29  import java.net.URL;
30  import java.net.URLConnection;
31  import java.util.Locale;
32  
33  public class CAL10NResourceBundleFinder {
34  
35    public static CAL10NResourceBundle getBundle(ClassLoader classLoader,
36        String baseName, Locale locale, String charset) {
37  
38      // same as the JDK convention
39      //
40      // It generates a path name from the candidate bundle name by replacing all
41      // "."
42      // characters with "/" and appending the string ".properties".
43      // / see also http: // tinyurl.com/ldgej8
44      baseName = baseName.replace('.', '/');
45  
46      String languageAndCountryCandidate = computeLanguageAndCountryCandidate(
47          baseName, locale);
48      String languageOnlyCandidate = computeLanguageOnlyCandidate(baseName,
49          locale);
50  
51      CAL10NResourceBundle cprbLanguageOnly = makePropertyResourceBundle(
52          classLoader, languageOnlyCandidate, charset);
53      CAL10NResourceBundle cprbLanguageAndCountry = null;
54  
55      if (languageAndCountryCandidate != null) {
56        cprbLanguageAndCountry = makePropertyResourceBundle(classLoader,
57            languageAndCountryCandidate, charset);
58      }
59  
60      if (cprbLanguageAndCountry != null) {
61        cprbLanguageAndCountry.setParent(cprbLanguageOnly);
62        return cprbLanguageAndCountry;
63      }
64      return cprbLanguageOnly;
65    }
66  
67    private static CAL10NResourceBundle makePropertyResourceBundle(
68        ClassLoader classLoader, String resourceCandiate, String charset) {
69  
70      CAL10NResourceBundle prb = null;
71  
72      URL url = classLoader.getResource(resourceCandiate);
73      if (url != null) {
74        try {
75          InputStream in = openConnectionForUrl(url);
76  
77          Reader reader = toReader(in, charset);
78          if (charset == null || charset.length() == 0)
79            reader = new InputStreamReader(in);
80          else
81            reader = new InputStreamReader(in, charset);
82  
83          prb = new CAL10NResourceBundle(reader, MiscUtil.urlToFile(url));
84          in.close();
85        } catch (IOException e) {
86        }
87      }
88      return prb;
89    }
90  
91    static Reader toReader(InputStream in, String charset) {
92      if (charset == null || charset.length() == 0)
93        return new InputStreamReader(in);
94      else {
95        try {
96          return new InputStreamReader(in, charset);
97        } catch (UnsupportedEncodingException e) {
98          throw new IllegalArgumentException("Failed to open reader", e);
99        }
100     }
101   }
102 
103   private static String computeLanguageAndCountryCandidate(String baseName,
104       Locale locale) {
105     String language = locale.getLanguage();
106     String country = locale.getCountry();
107     if (country != null && country.length() > 0) {
108       return baseName + "_" + language + "_" + country + ".properties";
109     } else {
110       return null;
111     }
112   }
113 
114   private static String computeLanguageOnlyCandidate(String baseName,
115       Locale locale) {
116     String language = locale.getLanguage();
117     return baseName + "_" + language + ".properties";
118   }
119 
120   private static InputStream openConnectionForUrl(URL url) throws IOException {
121     URLConnection urlConnection = url.openConnection();
122     urlConnection.setDefaultUseCaches(false);
123     InputStream in = urlConnection.getInputStream();
124     return in;
125   }
126 }