Resource Bundles
Protege Resource Bundles
This articles describes Protege's support for internationalization using Java resource bundles.
The mechanisms described on this page are used to replace "fixed text" in the Protege user interface. Fixed text includes things like menu items, tab names, labels, and dialog titles. This is not a mechanism for authoring ontology and knowledge-base content in multiple languages simultaneously. Such support is entirely separate and documented elsewhere on this wiki.
Most of the fixed English text in the Protege user interface can be replaced with text from other languages. We also provide easy, standard ways for Protege plug-ins to provide internationalization support so that end-users can localize plug-in text. Currently, there are French and Russian resource bundles available for download from our Subversion repository:
French: protege_text_fr.properties
Russian: protege_text_ru.properties
If you develop a Protege resource bundle, please consider contributing it back to the Protege user community. We will be happy to host resource bundles in our source code repository.
Protege's support for internalization and localization is directly layered on top of Java's built-in support. Those already familiar with the way this support works will find the scheme described here easy to understand. Those not familiar with this support may wish to browse the Java Internationalization page on the Sun Microsystems web site for additional background information.
What is a resource bundle?
A resource bundle is essentially one or more Java "properties" files.
A Java properties file is just a list of "key-value" pairs. There is a "key" associated with every piece of text that needs to appear in the application. The "value" is the string that appears in the application. Thus, when the program needs a string, it accesses it from this file in a standard way using a key and displays whatever value is returned. Note that the program must be specifically written to access strings in this manner. If a Protege plug-in has not been written to be localizable, then you cannot localize it by providing a resource bundle. Instead you need to make modifications to the source code (or talk the original plug-in developer into doing so).
To follow is an example of a properties file (snippet taken from the actual properties file for the main Protege application):
menubar.file=File menubar.file.mnemonic=F menubar.edit=Edit menubar.edit.mnemonic=E menubar.project=Project menubar.project.mnemonic=P menubar.window=Window menubar.window.mnemonic=W menubar.help=Help menubar.help.mnemonic=H project.new=New Project... project.new.mnemonic=N project.new.shortcut=N project.open=Open... project.open.mnemonic=O project.open.shortcut=O project.open_recent=Open Recent project.open_remote=Open Remote Project... project.open_remote.mnemonic=R project.close=Close Project project.close.mnemonic=C project.save=Save Project project.save.mnemonic=S ...
The main Protege application (and each Protege plug-in) must have separate resource bundles for each language. Files in a resource bundle use the naming convention of <something>.properties. The property resource bundles for the main Protege application are located in the Protege installation directory and are named "protege_text_<language>_<country>.properties". Property resource bundles for Protege plug-ins go in the plug-in's installation directory and are named something like "<plugin_name>_text_<language>_<country>.properties". The exact name for the plug-in's files are chosen by the plug-in author.
These properties files contain the strings used by the Protege application. There can be simultaneous English, French, and German versions of these strings available in the same Protege installation since each file will have its own unique name. There can also be variants of these properties files such as "Canadian French", "Swiss French", "Australian English", etc. When the system starts up, the locale of the application is checked and the closest available set of files are loaded. Thus a user in Geneva might start up the application and strings would be loaded first from the "Swiss French", then from the "French", and then from the "default" properties files. This sort of mechanism decreases maintenance problems because the country specific files, if needed at all, can be quite small, only providing "overrides" where default language provides a value that is undesirable for the language dialect spoken in that country.
How do I use an existing resource bundle?
You simply need to place the relevant properties files in the installation directory for the program you are trying to localize. For the main Protege application, this is the Protege installation directory, and for a plug-in, it is the plug-in's installation directory. For example, if you wanted to localize the Collaborative Protege extension, you would place the properties file in:
<protege-install-dir>/plugins/edu.stanford.smi.protege.collab
When Protege starts up, it prints the language and country (to the console window) that it believes is appropriate for you based on your system. The language and country are both two letter codes - the language is always lower case and the country is always upper case. These codes are used in identifying the resource bundle that the system will use.
You may wish to use a resource bundle other than the one that is the default for your system. To do this you need to override the language/country that the Java runtime system reports to the application by setting the "user.language" Java property to the two-character code that you desire. You can also specify the country dialect of a language by setting the "user.country" Java property. These properties can be specified in the Protege.lax file or on the Java command line, depending on how you start Protege.
A list of the two-character language codes is available at: http://www.loc.gov/standards/iso639-2/php/code_list.php
... and a list of the two-character country codes is available at: http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
How do I develop a new resource bundle?
First let's discuss how NOT to develop a resource bundle. Please do not change the default, existing .properties file. Any changes you make will be overwritten and lost every time you install a new version of Protege or Protege plug-in.
The logical first step is to make a copy of the existing properties file and rename it with the appropriate language/country part. Note that the language code is always lower case, while the country code is always upper case. Thus, a properties file for the French language should be named:
protege_text_fr.properties
... and a properties file for the Swiss French dialect should be named:
protege_text_fr_CH.properties
The case sensitivity of the language/country part is not relevant on Windows operating systems, but is critical if any Unix or Mac users want to load your bundle.
As indicated above you should develop the generic language file (say "French") first, and then develop country specific files (say "Swiss French") later, as needed. The country specific files should only provide text for keys whose value you want to override.
At this point, you can proceed with editing the properties file in your favorite text editor. Note that you must not change the value of the "key" for any entry (the value on the left of the equals sign). You are only changing the values on the right of the equals sign. Enter translations for all values.
N.B. Unfortunately, the properties file must be in ISO Latin-I encoding with Java Unicode escape characters in order to be used by the system. This restriction is a Java library "feature", and not a Protege implementation decision. This restriction seems to have been designed to make it as easy as possible for American Java programmers to do language translations and as difficult as possible for anyone else. A group of people less willing and able to do language translations than American Java programmers would be difficult to imagine. Nevertheless, this restriction is real and must be worked around. There are two ways to do this:
- Enter the translations directly in Latin-I using Java Unicode escapes. For languages where most characters are in the Latin-I character set this is clumsy but possible. For languages with other character sets (Chinese, Arabic, etc.), this approach is all but impossible.
- Enter the translations and save the file in your default system encoding. Then translate the .properties file to Latin-I using the "native2ascii" program, which, in spite of the name, converts from the native encoding to Latin-I plus Java unicode escapes. This program is described on the Sun Microsystems website: http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/native2ascii.html.
The restriction mentioned above is also described in somewhat more detail on Sun's website:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html
More information (programmer documentation) about loading resource bundles is available here:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/ResourceBundle.html