An XML Language for Describing Java Resource Bundles

The resources of a Java application that need to change when it is localised are stored in a Java ResourceBundle class. Hand-coding a ResourceBundle class can be difficult and time consuming, especially for non-textual resources. This article describes an XML language for describing the resources required by a Java application. The XML language simplifies the task of describing textual and byte-encoded resources, such as icons and audio clips, and enables the source code for the corresponding ResourceBundle class to be generated automatically.

1. Introduction

The resources of a Java application that need to change when it is localised are stored in a Java ResourceBundle class. Hand-coding a ResourceBundle class can be difficult and time consuming, especially for non-textual resources. This article describes an XML language for describing the resources required by a Java application. The XML language simplifies the task of describing textual and byte-encoded resources, such as icons and audio clips, and enables the source code for the corresponding ResourceBundle class to be generated automatically. Section 2 describes the tags that mark up the information that describes the resources. Section 3 describes how the XML description is used to generate the source code of a Java ResourceBundle class.

2. XML Description

The following screenshot shows an example Java program that requires four resources: two labels—Open File and Save File—and two icons—the open file icon and the save file icon.

Java program that requires four resources

The code below shows the XML description of the resources required to build this example program. The XML description is organized under the <resource-bundle> tag. A resource bundle starts with the <locale> tag that describes the locale of the resource bundle, the <class> tag that describes the resource bundle class to be generated, and the <resource-bundle-file> that describes the Java source file that will be generated.

<?xml version="1.0" encoding="UTF-8"?>
<resource-bundle>
    <locale>
        <language>en</language>
        <country>GB</country>
    </locale>
	<class>
        <name>ResourcesExample</name>
        <package>web.resources.test</package>
        <description>
          This class contains the text and byte resource information
          for the button labels and icons of the example program.
        </description>
    </class>
    <resource-bundle-file>
        <directory>c:/software/examples/resources</directory>
        <description>
           This file contains the class ResourcesExample_en_GB,
           the UK English resources of the example program.
        </description>
    </resource-bundle-file>
    <resource-group>
        <name>Example Program Resources</name>
        <description>The label and icon resources</description>
        <text-resource>
            <name>file.open.text</name>
            <value>Open File</value>
            <description>Open file button label</description>>
        </text-resource>
        <byte-resource>
            <name>file.open.icon</name>
            <url>file:/c:/software/examples/resources/Open16.png</url>
            <description>>Open file button icon</description>
        </byte-resource>
        <text-resource>
            <name>file.save.text</name>
            <value>Save File</value>
            <description>>Save file button label</description>
        </text-resource>
        <byte-resource>
            <name>file.save.icon</name>
            <url>file:/c:/software/examples/resources/Save16.png</url>
            <description>Save file button icon</description>
        </byte-resource>
    </resource-group>
</resource-bundle>

The <locale> tag stores the language and country codes of the resource bundle in the <language> and <country> tags, respectively. These codes are used to construct the name of the Java class and the name of the Java source file.

The <class> tag stores the base name of the Java class in the <name> tag. The full class name is constructed by appending the language and country codes to the base class name. The <package> tag contains the fully qualified name of the package of which the ResourceBundle class is a part. The <description> tag contains text that is used to generate a comment for the Java class.

The <resource-bundle-file> tag contains further information for generating the Java class source file. The name of the directory in which the source file will be stored is recorded in the <directory> tag. The <description> tag contains text used to generate a comment placed at the beginning of the source file.

The remainder of the <resource-bundle> tag contains one or more <resource-group> tags. A resource group collects together a set of related resources. For example, the resources for the File menu would be stored in one resource group and the resources for the Edit menu would be stored in a second resource group. A <resource-group> tag begins with the name of the resource group and a textual description of the resources in the group which are stored in the <name> and <description> tags, respectively. The remainder of a <resource-group> tag contains a sequence of <text-resource> and <byte-resource> tags that describe textual and byte-encoded resources, respectively.

A text resource is any string required by an application such as the name of a label or the tool tip text of a button. The <name> tag of the <text-resource> tag records the name of the resource as it is known in the application code. The <value> tag records the text that is displayed in the user interface and is the text that is changed when an application is localized. A textual description of the resource is recorded in the <description> tag.

A byte resource is a non-textual resource such as an icon or an audio file. The > tag of the <byte-resource> tag records the name of the resource as it is known in the application code. The <url> tag describes the location of the file containing the bytes of the resource.

The information about the resources stored in these tags is used to generate the source code of a Java ResourceBundle class.

3. Java Source Code Generation

The XML description of resources described in the previous section is used to generate a Java ResourceBundle class. A ResourceBundle class groups together the string and byte-encoded values that might need to change when preparing an application for use in another locale. The following Java source code was generated from the XML resource description shown above. The contents of the Java source code generated is determined by the Java resource bundle API. The format and layout of the source code follows Deitsch & Czarnecki (2001), chapter 4.

/*
 * This file contains the class ResourcesExample_en_GB,
 * the UK English resources of the example program.
 */
package web.resources.test;

import java.util.ListResourceBundle;

/**
 * This class contains the text and byte resource information
 * for the button labels and icons of the example program.
 */
public class ResourcesExample_en_GB extends ListResourceBundle {
    public Object[][] getContents() {
        return contents;
    }

    static byte[] _file_open_icon = {
        (byte)71,
        (byte)73,
        (byte)70,
           ...
        (byte)10,
        (byte)0,
        (byte)59
    };

    static byte[] _file_save_icon = {
        (byte)71,
        (byte)73,
        (byte)70,
           ...
        (byte)10,
        (byte)0,
        (byte)59
    };

    static final Object[][] contents = {
        { "file.open.text", "Open File" },     // Open file button label
        { "file.open.icon", _file_open_icon }, // Open file button icon
        { "file.save.text", "Save File" },     // Save file button label
        { "file.save.icon", _file_save_icon }, // Save file button icon
    };
}

The first item generated is the comment at the beginning of the source file which is the text contained in the <description> tag of the <resource-bundle-file> tag. The package statement is constructed from the <package> tag of the <class> tag. Every ResourceBundle class generated from the XML description is a sub-class of the ListResourceBundle class so the import statement is inserted automatically.

The comment preceding the class statement is generated from the text contained in the <description> tag of the <class> tag. The name of the class is constructed from the base class name recorded in the <name> tag of the <class> tag and the language and country codes recorded in the <locale> tag. In the Java source code above, the language and country codes, en and GB, are appended to the base class name ResourcesExample to produce the full class name ResourcesExample_en_GB. In Java, the name of the source file containing a class is the name of the class with a .java extension. The name of the Java source file is therefore ResourcesExample_en_GB.java.

The ListResourceBundle class stores resource values in a two-dimensional Object array called contents. Values are accessed by supplying a string key value to the getObject(String key) method inherited from ListResourceBundle. The getObject(String key) method uses the contents array to map keys to values. Text resources simply map from the string key to the string value. For example, from the key file.open.text to the value Open File.

Byte resources are stored in an array of bytes. A static byte[] object is created for each byte resource and the value of each byte is listed in the source file. A name for each byte[] object variable is constructed from the name of the resource by replacing the full stops with underscores and prefixing the new name with an underscore. For example, the variable name of the byte[] object representing the resource named file.open.icon will be _file_open_icon. The contents array maps a string key value to the variable name created for the corresponding byte array. For example, the key file.save.icon maps onto the byte[] object referenced by the variable name _file_save_icon.

The comment at the end of each line of key value pairs is generated from the <description> tag of the corresponding <text-resource> or <byte-resource> tag.

References

  • Deitsch, A. and D. Czarnecki, Java Internationalization, O’Reilly, 2001.