/[classpath]/classpath/java/util/ResourceBundle.java
ViewVC logotype

Diff of /classpath/java/util/ResourceBundle.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.14 by mark, Tue Jan 22 22:27:01 2002 UTC revision 1.15 by ericb, Fri Mar 22 21:25:19 2002 UTC
# Line 1  Line 1 
1  /* java.util.ResourceBundle  /* ResourceBundle -- aids in loading resource bundles
2     Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 37  exception statement from your version. * Line 37  exception statement from your version. *
37    
38    
39  package java.util;  package java.util;
40    
41  import java.lang.ref.Reference;  import java.lang.ref.Reference;
42  import java.lang.ref.SoftReference;  import java.lang.ref.SoftReference;
43    import java.io.InputStream;
44    import java.io.IOException;
45  import java.security.AccessController;  import java.security.AccessController;
46  import java.security.PrivilegedAction;  import java.security.PrivilegedAction;
47  import gnu.classpath.Configuration;  import gnu.classpath.Configuration;
# Line 76  import gnu.classpath.Configuration; Line 79  import gnu.classpath.Configuration;
79   * When a bundle is searched, we look first for a class with   * When a bundle is searched, we look first for a class with
80   * the given name and if that is not found for a file with   * the given name and if that is not found for a file with
81   * <code>.properties</code> extension in the classpath.  The name   * <code>.properties</code> extension in the classpath.  The name
82   * must be a fully qualified classname (with dots as path separators).     * must be a fully qualified classname (with dots as path separators).
83   * <br>   * <br>
84   * (Note: This implementation always backs up the class with a   * (Note: This implementation always backs up the class with a
85   * properties file if that is existing, but you shouldn't rely on   * properties file if that is existing, but you shouldn't rely on
# Line 90  public abstract class ResourceBundle Line 93  public abstract class ResourceBundle
93    /**    /**
94     * The parent bundle.  This is consulted when you call getObject     * The parent bundle.  This is consulted when you call getObject
95     * and there is no such resource in the current bundle.  This     * and there is no such resource in the current bundle.  This
96     * field may be null.       * field may be null.
97     */     */
98    protected ResourceBundle parent;    protected ResourceBundle parent;
99    
100    /**    /**
101     * The locale of this resource bundle.  You can read this with     * The locale of this resource bundle.  You can read this with
102     * <code>getLocale</code> and it is automatically set in     * <code>getLocale</code> and it is automatically set in
103     * <code>getBundle</code>.       * <code>getBundle</code>.
104     */     */
105    private Locale locale;    private Locale locale;
106    
107    /**    /**
108     * We override SecurityManager in order to access getClassContext().     * We override SecurityManager in order to access getClassContext().
109     */     */
110    static class Security extends SecurityManager    static class Security extends SecurityManager
111    {    {
# Line 117  public abstract class ResourceBundle Line 120  public abstract class ResourceBundle
120        return null;        return null;
121      }      }
122    }    }
123      
124    // This will always work since java.util classes have (all) system    // This will always work since java.util classes have (all) system
125    // permissions.    // permissions.
126    static Security security = (Security) AccessController.doPrivileged    static Security security = (Security) AccessController.doPrivileged
# Line 143  public abstract class ResourceBundle Line 146  public abstract class ResourceBundle
146     * Objects are Strings, this method provides a convenient way to get     * Objects are Strings, this method provides a convenient way to get
147     * them without casting.     * them without casting.
148     * @param key the name of the resource.     * @param key the name of the resource.
149     * @exception MissingResourceException     * @throws MissingResourceException
150     *   if that particular object could not be found in this bundle nor     *   if that particular object could not be found in this bundle nor
151     *   the parent bundle.     *   the parent bundle.
152     */     */
# Line 156  public abstract class ResourceBundle Line 159  public abstract class ResourceBundle
159     * Get an array of Strings from this resource bundle.  This method     * Get an array of Strings from this resource bundle.  This method
160     * provides a convenient way to get it without casting.     * provides a convenient way to get it without casting.
161     * @param key the name of the resource.     * @param key the name of the resource.
162     * @exception MissingResourceException     * @throws MissingResourceException
163     *   if that particular object could not be found in this bundle nor     *   if that particular object could not be found in this bundle nor
164     *   the parent bundle.     *   the parent bundle.
165     */     */
# Line 169  public abstract class ResourceBundle Line 172  public abstract class ResourceBundle
172    /**    /**
173     * Get an object from this resource bundle.     * Get an object from this resource bundle.
174     * @param key the name of the resource.     * @param key the name of the resource.
175     * @exception MissingResourceException     * @throws MissingResourceException
176     *   if that particular object could not be found in this bundle nor     *   if that particular object could not be found in this bundle nor
177     *   the parent bundle.     *   the parent bundle.
178     */     */
# Line 192  public abstract class ResourceBundle Line 195  public abstract class ResourceBundle
195    }    }
196    
197    /**    /**
198     * Get the appropriate ResourceBundle for the default locale.       * Get the appropriate ResourceBundle for the default locale.
199     * @param baseName the name of the ResourceBundle.  This should be     * @param baseName the name of the ResourceBundle.  This should be
200     * a name of a Class or a properties-File.  See the class     * a name of a Class or a properties-File.  See the class
201     * description for details.       * description for details.
202     * @return the desired resource bundle     * @return the desired resource bundle
203     * @exception MissingResourceException     * @throws MissingResourceException if the resource bundle can't be found
    *    if the resource bundle couldn't be found.    
204     */     */
205    public static final ResourceBundle getBundle(String baseName)    public static final ResourceBundle getBundle(String baseName)
206      throws MissingResourceException      throws MissingResourceException
# Line 208  public abstract class ResourceBundle Line 210  public abstract class ResourceBundle
210    }    }
211    
212    /**    /**
213     * Get the appropriate ResourceBundle for the given locale.       * Get the appropriate ResourceBundle for the given locale.
214     * @param baseName the name of the ResourceBundle.  This should be     * @param baseName the name of the ResourceBundle.  This should be
215     * a name of a Class or a properties-File.  See the class     * a name of a Class or a properties-File.  See the class
216     * description for details.       * description for details.
217     * @param locale A locale.     * @param locale A locale.
218     * @return the desired resource bundle     * @return the desired resource bundle
219     * @exception MissingResourceException     * @throws MissingResourceException if the resource bundle can't be found
    *    if the resource bundle couldn't be found.  
220     */     */
221    public static final ResourceBundle getBundle(String baseName,    public static final ResourceBundle getBundle(String baseName,
222                                                 Locale locale)                                                 Locale locale)
# Line 233  public abstract class ResourceBundle Line 234  public abstract class ResourceBundle
234    
235    /**    /**
236     * The `empty' locale is created once in order to optimize     * The `empty' locale is created once in order to optimize
237     * tryBundle().       * tryBundle().
238     */     */
239    private static final Locale emptyLocale = new Locale ("", "");    private static final Locale emptyLocale = new Locale ("", "");
240    
# Line 243  public abstract class ResourceBundle Line 244  public abstract class ResourceBundle
244     * @param locale the locale, that must be used exactly.     * @param locale the locale, that must be used exactly.
245     * @param classloader the classloader.     * @param classloader the classloader.
246     * @param bundle the back up (parent) bundle     * @param bundle the back up (parent) bundle
247     * @return the resource bundle if that could be loaded, otherwise     * @return the resource bundle if that could be loaded, otherwise
248     * <code>bundle</code>.     * <code>bundle</code>.
249     */     */
250    private static final ResourceBundle tryBundle(String localizedName,    private static final ResourceBundle tryBundle(String localizedName,
# Line 269  public abstract class ResourceBundle Line 270  public abstract class ResourceBundle
270      // foundBundle holds exact matches for the localizedName resource      // foundBundle holds exact matches for the localizedName resource
271      // bundle, which may later be cached.      // bundle, which may later be cached.
272      ResourceBundle foundBundle = null;      ResourceBundle foundBundle = null;
   
     try  
       {  
         java.io.InputStream is;  
         final String resourceName =  
           localizedName.replace('.', '/') + ".properties";  
         if (classloader == null)  
           is = ClassLoader.getSystemResourceAsStream (resourceName);  
         else  
           is = classloader.getResourceAsStream (resourceName);  
         if (is != null)  
           {  
             foundBundle = new PropertyResourceBundle(is);  
             foundBundle.parent = bundle;  
             foundBundle.locale = locale;  
           }  
       }  
     catch (java.io.IOException ex)  
       {  
       }  
   
273      try      try
274        {        {
275          Class rbClass;          Class rbClass;
# Line 312  public abstract class ResourceBundle Line 292  public abstract class ResourceBundle
292          // ignore them all          // ignore them all
293          // XXX should we also ignore ClassCastException?          // XXX should we also ignore ClassCastException?
294        }        }
295        if (foundBundle == null)
296          try
297            {
298              InputStream is;
299              final String resourceName
300                = localizedName.replace('.', '/') + ".properties";
301              if (classloader == null)
302                is = ClassLoader.getSystemResourceAsStream (resourceName);
303              else
304                is = classloader.getResourceAsStream (resourceName);
305              if (is != null)
306                {
307                  foundBundle = new PropertyResourceBundle(is);
308                  foundBundle.parent = bundle;
309                  foundBundle.locale = locale;
310                }
311            }
312          catch (IOException ex)
313            {
314            }
315    
316      if (foundBundle != null)      if (foundBundle != null)
317        cache.put(localizedName, new SoftReference(foundBundle));        cache.put(localizedName, new SoftReference(foundBundle));
# Line 327  public abstract class ResourceBundle Line 327  public abstract class ResourceBundle
327     * @param locale the locale, that must be used exactly.     * @param locale the locale, that must be used exactly.
328     * @param classloader the classloader.     * @param classloader the classloader.
329     * @param bundle the back up (parent) bundle     * @param bundle the back up (parent) bundle
330     * @return the resource bundle if that could be loaded, otherwise     * @return the resource bundle if that could be loaded, otherwise
331     * <code>bundle</code>.     * <code>bundle</code>.
332     */     */
333    private static final ResourceBundle tryLocalBundle(String baseName,    private static final ResourceBundle tryLocalBundle(String baseName,
# Line 337  public abstract class ResourceBundle Line 337  public abstract class ResourceBundle
337                                                       HashMap cache)                                                       HashMap cache)
338    {    {
339      final String language = locale.getLanguage();      final String language = locale.getLanguage();
340        StringBuffer sb = new StringBuffer(60);
341    
342      if (language.length() > 0)      if (language.length() > 0)
343        {        {
344          final String country = locale.getCountry();          final String country = locale.getCountry();
345          String name = baseName + "_" + language;          sb.append(baseName).append('_').append(language);
346            String name = sb.toString();
347    
348          if (country.length() != 0)          if (country.length() != 0)
349            {            {
350              bundle = tryBundle(name,              bundle = tryBundle(name,
351                                 new Locale(language, ""),                                 new Locale(language, ""),
352                                 classloader, bundle, cache);                                 classloader, bundle, cache);
353                sb.append('_').append(country);
354              name += "_" + country;              name = sb.toString();
355    
356              final String variant = locale.getVariant();              final String variant = locale.getVariant();
357    
# Line 359  public abstract class ResourceBundle Line 361  public abstract class ResourceBundle
361                                     new Locale(language,                                     new Locale(language,
362                                                country),                                                country),
363                                     classloader, bundle, cache);                                     classloader, bundle, cache);
364                    sb.append('_').append(variant);
365                  name += "_" + variant;                  name = sb.toString();
366                }                }
367            }            }
368          bundle = tryBundle(name, locale, classloader, bundle, cache);          bundle = tryBundle(name, locale, classloader, bundle, cache);
# Line 369  public abstract class ResourceBundle Line 371  public abstract class ResourceBundle
371    }    }
372    
373    /**    /**
374     * Get the appropriate ResourceBundle for the given locale.       * Get the appropriate ResourceBundle for the given locale.
375     * @param baseName the name of the ResourceBundle.  This should be     * @param baseName the name of the ResourceBundle.  This should be
376     * a name of a Class or a properties file.  See the class     * a name of a Class or a properties file.  See the class
377     * description for details.       * description for details.
378     * @param locale A locale.     * @param locale A locale.
379     * @param classloader a ClassLoader.     * @param classloader a ClassLoader.
380     * @return the desired resource bundle     * @return the desired resource bundle
381     * @exception MissingResourceException     * @throws MissingResourceException if the resource bundle can't be found
    *    if the resource bundle couldn't be found.  
382     */     */
383    // This method is synchronized so that the cache is properly    // This method is synchronized so that the cache is properly
384    // handled.    // handled.
# Line 390  public abstract class ResourceBundle Line 391  public abstract class ResourceBundle
391      // and builds the parent chain on the fly.      // and builds the parent chain on the fly.
392    
393      HashMap cache = (HashMap) resourceBundleCache.get(classLoader);      HashMap cache = (HashMap) resourceBundleCache.get(classLoader);
394        StringBuffer sb = new StringBuffer(60);
395        sb.append(baseName).append('_').append(locale);
396        String name = sb.toString();
397    
398      if (cache == null)      if (cache == null)
399        {        {
400          cache = new HashMap();          cache = new HashMap();
# Line 397  public abstract class ResourceBundle Line 402  public abstract class ResourceBundle
402        }        }
403      else      else
404        {        {
         // Fast path: If baseName + "_" + locale is in cache use it.  
         String name = baseName + "_" + locale.toString();  
405          Reference ref = (Reference) cache.get(name);          Reference ref = (Reference) cache.get(name);
406          if (ref != null)          if (ref != null)
407            {            {
# Line 427  public abstract class ResourceBundle Line 430  public abstract class ResourceBundle
430          bundle = tryLocalBundle(baseName, Locale.getDefault(),          bundle = tryLocalBundle(baseName, Locale.getDefault(),
431                                  classLoader, baseBundle, cache);                                  classLoader, baseBundle, cache);
432        }        }
433    
434        // Check whether baseName_locale has been loaded; if not, map the
435        // "baseName" bundle to "baseName_locale" to avoid retrying to load
436        // baseName_locale.
437        Reference ref = (Reference) cache.get(name);
438        if (ref == null)
439          cache.put(name, new SoftReference(bundle));
440    
441      return bundle;      return bundle;
442    }    }
443    
# Line 455  public abstract class ResourceBundle Line 466  public abstract class ResourceBundle
466     * Override this method to provide the resource for a keys.  This gets     * Override this method to provide the resource for a keys.  This gets
467     * called by <code>getObject</code>.  If you don't have a resource     * called by <code>getObject</code>.  If you don't have a resource
468     * for the given key, you should return null instead throwing a     * for the given key, you should return null instead throwing a
469     * MissingResourceException.   You don't have to ask the parent,     * MissingResourceException.   You don't have to ask the parent,
470     * getObject() already does this.     * getObject() already does this.
471     *     *
472     * @param key The key of the resource.     * @param key The key of the resource.
473     * @return The resource for the key, or null if not in bundle.     * @return The resource for the key, or null if not in bundle.
474     * @exception MissingResourceException     * @throws MissingResourceException you shouldn't throw this
    *   you shouldn't throw this.  
475     */     */
476    protected abstract Object handleGetObject(String key)    protected abstract Object handleGetObject(String key)
477      throws MissingResourceException;      throws MissingResourceException;

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26