Release 2.0 - 30 September 2010
This document describes the support that Ganymede 2.0 has for Internationalization and Localization, and how to go about translating the Ganymede server, client, and admin console for use in your language.
by Jonathan Abbey.
Ganymede 2.0 is intended to give as much flexibility as possible to adopters who want to put it into operation. A crucial part of this flexibility, for an international audience, is to support translation of buttons, menus, and server messages into languages other than English.
Obviously, it would be a terrible burden to have to search through all of the Ganymede .java source files, looking for text strings to translate. No one would want to translate the Ganymede software if it meant that they were then obliged to maintain their own translated version of Ganymede.
To solve this problem, Ganymede takes advantage of the localization support built into the Java platform. All message strings are read from Java property files, and all Strings, Dates, and Numbers are formatted with the Java MessageFormat Class.
Translators can translate Ganymede to languages other than English by creating language-specific versions of these property files. If the Ganymede software is run on a Java Runtime Environment that is configured to use a non-English language, the Java environment will automatically look for and use the appropriate versions of these property files. If no appropriate translation exists, Ganymede reverts to using the default English message strings.
In this document, we will discuss how you go about translating Ganymede to new languages, as well as how to take advantage of the support code in the Ganymede system to ensure that new code that you write in the Ganymede system will be easily translatable by someone else.
The default message files are named after the classes they are
serving. For instance, the message strings for the client's
central class, arlut.csd.ganymede.client.gclient
, is
held in
src/resources/arlut/csd/ganymede/client/gclient.properties
.
German language message strings are held in files named after
the class, followed by an underscore and the ISO language code for
German. So the German version of the gclient message file is
called src/resources/arlut/csd/ganymede/client/gclient_de.properties
.
By extension, a French language message file would be gclient_fr.properties, a Norwegian version would be gclient_no.properties, etc.
You can find a complete list of these language codes at http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt.
To support adopters writing their own translations, Ganymede's
ant build script, src/build.xml
, includes special
support for validating all message files against the Ganymede
source code.
If you run ant validate
, a Perl script will be run
which will analyze all message files and cross-check them against
the Ganymede sources. ant validate
will print out a
report letting you know how complete your translation is, and
whether it is properly constructed.
If you do generate a new translation for Ganymede, we encourage you to send us patches at ganymede_author@arlut.utexas.edu for us to incorporate into the master Ganymede repository.
The Ganymede source tree uses a class named arlut.csd.Util.TranslationService pervasively to handle translation for all text message strings in the server, client, and admin console.
This class must be used in conjunction with a particular usage convention in order to support automatic validation of message files with the 'ant validate' task in the Ganymede build.xml file.
That convention is that every class that needs language translation services must declare a static final TranslationService object named 'ts' which is initialized with the fully qualified name of the class to which it belongs.
All of your translatable code should include a declaration for 'ts' that looks like this:
/** * TranslationService object for handling string localization in * the Ganymede server. */ static final TranslationService ts = TranslationService.getTranslationService("arlut.csd.ganymede.server.GanymedeXMLSession");
With 'arlut.csd.ganymede.server.GanymedeXMLSession' replaced with the fully qualified name of your class.
Actual translation calls should all be in the form of ts.l("messageName"), possibly with extra parameters, such as ts.l("messageName", arg1, arg2), and so forth. The 'l' method of TranslationService is designed to be as compact as possible so that it can be used wherever you would normally use a string. It returns a String formatted according to whatever language-sensitive property files are defined in Ganymede's src/resources directory.
If you follow these conventions, the 'ant validate' task will be able to automatically analyze your code and cross reference it against the message property files under src/resources. 'ant validate' will warn you if you are missing messages, or if the messages are malformed, or if the messages specify a different number of parameters than the source code which uses the messages is expecting.
So, for use within Ganymede, please be sure always to follow these conventions in your code.