This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: ResourceBundle fix and cleanup
- To: java-patches at gcc dot gnu dot org
- Subject: Patch: ResourceBundle fix and cleanup
- From: Anthony Green <green at redhat dot com>
- Date: Thu, 6 Sep 2001 20:45:20 -0700
- Reply-to: green at cygnus dot com
(I've also submitted this to classpath via their web interface)
This patch fixes a bug in ResourceBundle which caused the following
program to throw a missing key exception...
import java.util.Locale;
import java.text.DateFormatSymbols;
public class dfs
{
public static void main(String args[])
{
DateFormatSymbols dfs;
dfs = new DateFormatSymbols (new Locale ("ie", "es"));
dfs = new DateFormatSymbols (new Locale ("ie", "es"));
}
}
Assuming there is no gnu.java.locale.LocaleInformation_ie* around, the
first time through DateFormatSymbols.DateFormatSymbols(), the
ResourceBundle.getBundle code would cache
gnu.java.local.LocaleInformation for this locale and then _use_ the
en_US version. The second time through it simply returns the cached
version, which is definitely the wrong one.
This patch changes ResourceBundle.tryBundle() to only cache exact
matches. This also has the advantage that you can add locale matching
resource bundles to long running programs by dropping the somewhere in
the classpath.
The second half of the patch removes some redundant method calls and
Locale("", "") allocations.
2001-09-06 Anthony Green <green@redhat.com>
* java/util/ResourceBundle.java (tryLocalBundle): Eliminate
redundant method calls.
(emptyLocale): New private member.
(tryBundle): Use emptyLocale. Remove duplicate code. Only cache
exact matches.
Index: libjava/java/util/ResourceBundle.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/util/ResourceBundle.java,v
retrieving revision 1.13
diff -u -p -r1.13 ResourceBundle.java
--- ResourceBundle.java 2001/08/31 21:31:20 1.13
+++ ResourceBundle.java 2001/09/07 03:27:21
@@ -201,8 +201,14 @@ public abstract class ResourceBundle
private static Map resourceBundleCache = new HashMap();
/**
+ * The `empty' locale is created once in order to optimize
+ * tryBundle().
+ */
+ private static final Locale emptyLocale = new Locale ("", "");
+
+ /**
* Tries to load a class or a property file with the specified name.
- * @param name the name.
+ * @param localizedName the name.
* @param locale the locale, that must be used exactly.
* @param classloader the classloader.
* @param bundle the back up (parent) bundle
@@ -229,21 +235,24 @@ public abstract class ResourceBundle
}
}
+ // foundBundle holds exact matches for the localizedName resource
+ // bundle, which may later be cached.
+ ResourceBundle foundBundle = null;
+
try
{
java.io.InputStream is;
+ final String resourceName =
+ localizedName.replace('.', '/') + ".properties";
if (classloader == null)
- is = ClassLoader.getSystemResourceAsStream
- (localizedName.replace('.', '/') + ".properties");
+ is = ClassLoader.getSystemResourceAsStream (resourceName);
else
- is = classloader.getResourceAsStream
- (localizedName.replace('.', '/') + ".properties");
+ is = classloader.getResourceAsStream (resourceName);
if (is != null)
{
- ResourceBundle rb = new PropertyResourceBundle(is);
- rb.parent = bundle;
- rb.locale = locale;
- bundle = rb;
+ foundBundle = new PropertyResourceBundle(is);
+ foundBundle.parent = bundle;
+ foundBundle.locale = locale;
}
}
catch (java.io.IOException ex)
@@ -257,10 +266,9 @@ public abstract class ResourceBundle
rbClass = Class.forName(localizedName);
else
rbClass = classloader.loadClass(localizedName);
- ResourceBundle rb = (ResourceBundle) rbClass.newInstance();
- rb.parent = bundle;
- rb.locale = locale;
- bundle = rb;
+ foundBundle = (ResourceBundle) rbClass.newInstance();
+ foundBundle.parent = bundle;
+ foundBundle.locale = locale;
}
catch (ClassNotFoundException ex)
{
@@ -274,11 +282,10 @@ public abstract class ResourceBundle
// XXX should we also ignore ClassCastException?
}
- // Put the bundle in the cache
- if (bundle != null)
- cache.put(localizedName, new SoftReference(bundle));
+ if (foundBundle != null)
+ cache.put(localizedName, new SoftReference(foundBundle));
- return bundle;
+ return foundBundle;
}
/**
@@ -298,26 +305,31 @@ public abstract class ResourceBundle
ResourceBundle bundle,
HashMap cache)
{
- if (locale.getLanguage().length() > 0)
+ final String language = locale.getLanguage();
+
+ if (language.length() > 0)
{
- String name = baseName + "_" + locale.getLanguage();
+ final String country = locale.getCountry();
+ String name = baseName + "_" + language;
- if (locale.getCountry().length() != 0)
+ if (country.length() != 0)
{
bundle = tryBundle(name,
- new Locale(locale.getLanguage(), ""),
+ new Locale(language, ""),
classloader, bundle, cache);
+
+ name += "_" + country;
- name += "_" + locale.getCountry();
+ final String variant = locale.getVariant();
- if (locale.getVariant().length() != 0)
+ if (variant.length() != 0)
{
bundle = tryBundle(name,
- new Locale(locale.getLanguage(),
- locale.getCountry()),
+ new Locale(language,
+ country),
classloader, bundle, cache);
- name += "_" + locale.getVariant();
+ name += "_" + variant;
}
}
bundle = tryBundle(name, locale, classloader, bundle, cache);
@@ -367,7 +379,7 @@ public abstract class ResourceBundle
}
}
- ResourceBundle baseBundle = tryBundle(baseName, new Locale("", ""),
+ ResourceBundle baseBundle = tryBundle(baseName, emptyLocale,
classLoader, null, cache);
if (baseBundle == null)
// JDK says, that if one provides a bundle base_en_UK, one