Using Java 6 to Access Translatable Text in XML Files | 2 | WebReference

Using Java 6 to Access Translatable Text in XML Files | 2


Using Java 6 to Access Translatable Text in XML Files [con't]

If you plan on implementing more methods, you should probably write a proper class. Typically, instantiation of a resource bundle is handled by the newBundle() method of the ResourceBundle.Control class. The advantage of overriding the newBundle() method is that it allows you to customize the default implementation of the Bundle instantiation to suit your specific needs. In this case, you want to plug in your XMLResourceBundle class, passing it a BufferedInputStream.

You may recall from the previous article that the ResourceBundle.Control class defines a set of callback methods that are called by the factory method ResourceBundle.getBundle() to instantiate a ResourceBundle for the base bundle name, a locale, and a format. Because you don't have to call the newBundle() method directly, all you have to do is override it to implement your own bundle-loading procedure.

Here is the full code for the newBundle() method:

Don't be intimidated by the parameter-heavy signature. Because it's called internally, you don't have to worry about any of that. The important thing is to get the method body right, which is made easier by the fact that it typically follows the same pattern. The loading proceeds as follows:

  • Handle null input parameters: Because they are required, a NullPointerException should be thrown if any nulls are encountered.
  • Check the format: Exit the method, if incorrect.
  • Create the bundle name from the baseName and locale (e.g., "autoparts", (no locale), autoparts_fr (French).
  • Set the resourceName by calling toResourceName() with the bundleName and format.
  • If the reload input parameter is false:
    • Load the file by calling loader.getResource(resourceName); exit the method if the method returns null.
    • Open a connection to the URL; exit the method if a connection cannot be established.
    • Turn off connection caching.
    • Get an InputStream from the connection.
  • If the reload input parameter is true:
    • Get an InputStream using the resourceName, calling the loader.getResourceAsStream() method.
  • Exit the method if an InputStream could not be created.
  • Create a BufferedInputStream from the InputStream.
  • Instantiate the ResourceBundle class, passing it the BufferedInputStream. In this case, you should create an instance of your XMLReourceBundle class.
  • Close the BufferedInputStream.
  • Return the Bundle object.

To test your classes you need to call the ResourceBundle's static getBundle() method, with the name and control parameters. The easiest thing for you to do is to put all of your control code in a class of its own, called XMLResourceBundleControl:

The following code will create an instance of your bundle and print the value for a key of "yes" using the default locale:

You can also test for other locales by using the three-argument version of the getBundle() method, which accepts a locale object in addition to the bundle name and control object:

You saw how Java's ResourceBundle, ResourceBundle.Control, and Properties files can be easily extended to suit a variety of file formats, including XML. While this does afford you greater flexibility in managing translatable text in files, properties files still have the inherent weakness of being cumbersome to manage if you have many languages to support. Many businesses have found using a relational database to be a superior choice for managing language systems. In the next article, I'll explore this powerful option for localizing text.

Have a suggestion for an article topic? Do you have a product or service that you'd like reviewed? Email it to Rob .

Rob Gravelle combined his love of programming and music to become a software guru and accomplished guitar player. He created systems that are used by Canada Border Services, CSIS and other Intelligence-related organizations. As a software consultant, Rob has developed Web applications for many businesses and recently created a MooTools version of PHPFreechat for ViziMetrics. Musically, Rob recently embarked on a solo music career, after playing with Ivory Knight since 2000. That band was rated as one Canada's top bands by Brave Words magazine (issue #92) and released two CDs. Rob's latest release is called "The Rabbit of Seville". Loosely based on Rossini's The Barber of Seville overture, Rob's amazing rendition includes a full orchestra and numerous guitar tracks. It is sold on his site as a high bitrate MP3 for only $0.99 cents! Rob is available for short-term software projects and recording session work. to inquire, but note that, due to the volume of emails received, he cannot respond to every email. Potential jobs and praise receive highest priority!

Original: June 21, 2010