Localization Made Easy
XML resource bundles provide a powerful, easily applicable approach that gives you all the benefits of the standard Java localization model
by Claude Duguay
December 2002 Issue
XML is particularly well suited for handling multiple language problems, such as internationalization and localization, because XML is great at identifying the encoding scheme as part of its document header information. Java provides a powerful localization mechanism called resource bundles, which must either be coded into Java classes or handled by the default Java Properties object and its associated file format. XML seems better suited for this mechanism than property files; therefore, we'll build a localization infrastructure for Java that's based on XML.
One task that the standard Java ResourceBundle class does well is handling the management of property filenames using a hierarchical naming convention based on Locale objects. A Locale is built up from three elements: Language, Country, and Variant. In practice, the Language is important and the Country is sometimes important, but the Variant is rarely used. Each element can be represented by two-letter symbols. Filenames can be built easily by using an underscore delimiter and a base filename. For example, a US-English bundle might have the name "BaseName_en_US.xml", while a more general English bundle would have the name "BaseName_en.xml". This format is the same basic naming scheme used for property filenames in standard Java resource bundles.
Localization is really about externalizing language or Locale-specific resources and loading them using keys. Java uses String keys to get at resources, while other languages may use integer values. The keys, however, are completely arbitrary, and conventions are entirely up to developers. In a large project, it's important to develop and adopt a global scheme for naming resources as early as possible; that way name collisions don't occur during development. Fortunately, naming can be handled in part by using resource bundles that are specific to given components or modules, with each having a different base name.
What's important in resolving localization keys is that the more specific entries are found first, hence the importance of the hierarchical nature of resource bundles. A US-English entry is more specific than a more general English entry with the same name. XML is hierarchical, as well, so you can imagine a scheme in which keys are resolved from the deepest node first. Distributing bundles across files is still important, but keeping multiple languages or locales in the same file should also be possible. We'll design an infrastructure where both approaches, or a mix, are possible.
Let's take a look at the high-level interface we want to be able to use. We'll define an XMLResourceBundle by its base filename, so the constructor requires a single String argument. The loadFile() method will load resources from one or more XML bundles based on a given Locale (provided as the only argument). We want this call to handle all the conflict resolution for us so that we end up with the key mappings that are appropriate for the provided Locale. After this call, we'll be free to call the getText() method with a key to get a String resource, or the getFile() method to get filenames.
Back to top