More Control over ResourceBundle
Did you ever wish you had a little more control over the ResourceBundle class?
Say, have it instantiate bundles from XML files or from data in a database,
rather than just class and properties files? Or, to the contrary, have
it look only for properties files, because you never use class-based resource
bundles? Or have it reload a bundle with a little fix without having to
restart your web application, which otherwise is on the way towards reaching
99.999% uptime? Well, you just got that little more control: The ResourceBundle.Control class
in JDK 6.
The central method in ResourceBundle has always been getBundle.
This method looks for resource bundles of predefined types in predefined
places using a predefined search strategy, loaded them in predefined ways,
and cached them in a largely unspecified way.
The idea of the Control class is to expose every major step
of the bundle loading process as a separate method that can be overridden
and customized. The Control class itself implements the methods
so that using it directly results in the same behavior as in previous releases.
But applications can subclass it, override as many methods as necessary
to implement the behavior they need, and pass an instance of this subclass
to new getBundle methods
that accept Control objects.
For some of the most common cases, you don’t actually need to write your
own subclass: If you just want to use only class-based or only properties-based
resource bundles, or if you want to avoid the fallback to the default locale,
the getControl and getNoFallbackControl methods
provide you with ready-made instances.
Here are a few examples for how you can go further (the class description has more):
- To search for bundles according to the list of languages that your
web application received in an Accept-Language HTTP header, override
the
getFallbackLocalemethod to successively return the locales of the language list. - To load resource bundles from locale-specific directories rather than
using locale-specific suffixes, override the
toBundleNamemethod to insert the locale ID components into the appropriate places of the bundle name. - To use bundles for Chinese/Taiwan as the parent bundles of Chinese/Hong
Kong bundles in order to share traditional Chinese strings, override
getCandidateLocalesto insert the Chinese/Taiwan locale in the right place. - To ensure that cached bundles are checked against their source files
on disk at least every 6 hours, override
getTimeToLiveto return 21,600,000. (The specification currently says that that’s the default behavior. Unfortunately, this uncovered a bug in a major third-party application that we test with, so in order to avoid incompatibilities, the default behavior will revert toTTL_NO_EXPIRATION_CONTROL, which reflects behavior in previous releases.)
Some methods need to be overridden together. For example, if you override
getFormats to
return formats other than "java.class" and "java.properties", you also need
to override newBundle to
load bundles of these formats. If, in addition, you override getTimeToLive
to enable checking whether a bundle in the cache is still up to date, you
may also need to override needsReload to
implement the checking.
If, instead of periodically checking whether resource bundles in the cache
are still up to date, you’d rather remove all your application’s bundles
from the cache when installing new bundles, you can use the new ResourceBundle.clearCache methods.
As always, we’d love to hear from you whether these API additions meet your needs, or what’s wrong with them. Please try them, file bugs, or send us your feedback.
feed