gettext: Java
1
1 15.5.11 Java
1 ------------
1
1 RPMs
1 java, java2
1
1 File extension
1 ‘java’
1
1 String syntax
1 "abc"
1
1 gettext shorthand
1 _("abc")
1
1 gettext/ngettext functions
1 ‘GettextResource.gettext’, ‘GettextResource.ngettext’,
1 ‘GettextResource.pgettext’, ‘GettextResource.npgettext’
1
1 textdomain
1 —, use ‘ResourceBundle.getResource’ instead
1
1 bindtextdomain
1 —, use CLASSPATH instead
1
1 setlocale
1 automatic
1
1 Prerequisite
1 —
1
1 Use or emulate GNU gettext
1 —, uses a Java specific message catalog format
1
1 Extractor
1 ‘xgettext -k_’
1
1 Formatting with positions
1 ‘MessageFormat.format "{1,number} {0,number}"’
1
1 Portability
1 fully portable
1
1 po-mode marking
1 —
1
1 Before marking strings as internationalizable, uses of the string
1 concatenation operator need to be converted to ‘MessageFormat’
1 applications. For example, ‘"file "+filename+" not found"’ becomes
1 ‘MessageFormat.format("file {0} not found", new Object[] { filename })’.
1 Only after this is done, can the strings be marked and extracted.
1
1 GNU gettext uses the native Java internationalization mechanism,
1 namely ‘ResourceBundle’s. There are two formats of ‘ResourceBundle’s:
1 ‘.properties’ files and ‘.class’ files. The ‘.properties’ format is a
1 text file which the translators can directly edit, like PO files, but
1 which doesn’t support plural forms. Whereas the ‘.class’ format is
1 compiled from ‘.java’ source code and can support plural forms (provided
1 it is accessed through an appropriate API, see below).
1
1 To convert a PO file to a ‘.properties’ file, the ‘msgcat’ program
1 can be used with the option ‘--properties-output’. To convert a
1 ‘.properties’ file back to a PO file, the ‘msgcat’ program can be used
1 with the option ‘--properties-input’. All the tools that manipulate PO
1 files can work with ‘.properties’ files as well, if given the
1 ‘--properties-input’ and/or ‘--properties-output’ option.
1
1 To convert a PO file to a ResourceBundle class, the ‘msgfmt’ program
1 can be used with the option ‘--java’ or ‘--java2’. To convert a
1 ResourceBundle back to a PO file, the ‘msgunfmt’ program can be used
1 with the option ‘--java’.
1
1 Two different programmatic APIs can be used to access
1 ResourceBundles. Note that both APIs work with all kinds of
1 ResourceBundles, whether GNU gettext generated classes, or other
1 ‘.class’ or ‘.properties’ files.
1
1 1. The ‘java.util.ResourceBundle’ API.
1
1 In particular, its ‘getString’ function returns a string
1 translation. Note that a missing translation yields a
1 ‘MissingResourceException’.
1
1 This has the advantage of being the standard API. And it does not
1 require any additional libraries, only the ‘msgcat’ generated
1 ‘.properties’ files or the ‘msgfmt’ generated ‘.class’ files. But
1 it cannot do plural handling, even if the resource was generated by
1 ‘msgfmt’ from a PO file with plural handling.
1
1 2. The ‘gnu.gettext.GettextResource’ API.
1
1 Reference documentation in Javadoc 1.1 style format is in the
1 javadoc2 directory (javadoc2/index.html).
1
1 Its ‘gettext’ function returns a string translation. Note that
1 when a translation is missing, the MSGID argument is returned
1 unchanged.
1
1 This has the advantage of having the ‘ngettext’ function for plural
1 handling and the ‘pgettext’ and ‘npgettext’ for strings constraint
1 to a particular context.
1
1 To use this API, one needs the ‘libintl.jar’ file which is part of
1 the GNU gettext package and distributed under the LGPL.
1
1 Four examples, using the second API, are available in the ‘examples’
1 directory: ‘hello-java’, ‘hello-java-awt’, ‘hello-java-swing’,
1 ‘hello-java-qtjambi’.
1
1 Now, to make use of the API and define a shorthand for ‘getString’,
1 there are three idioms that you can choose from:
1
1 • (This one assumes Java 1.5 or newer.) In a unique class of your
1 project, say ‘Util’, define a static variable holding the
1 ‘ResourceBundle’ instance and the shorthand:
1
1 private static ResourceBundle myResources =
1 ResourceBundle.getBundle("domain-name");
1 public static String _(String s) {
1 return myResources.getString(s);
1 }
1
1 All classes containing internationalized strings then contain
1
1 import static Util._;
1
1 and the shorthand is used like this:
1
1 System.out.println(_("Operation completed."));
1
1 • In a unique class of your project, say ‘Util’, define a static
1 variable holding the ‘ResourceBundle’ instance:
1
1 public static ResourceBundle myResources =
1 ResourceBundle.getBundle("domain-name");
1
1 All classes containing internationalized strings then contain
1
1 private static ResourceBundle res = Util.myResources;
1 private static String _(String s) { return res.getString(s); }
1
1 and the shorthand is used like this:
1
1 System.out.println(_("Operation completed."));
1
1 • You add a class with a very short name, say ‘S’, containing just
1 the definition of the resource bundle and of the shorthand:
1
1 public class S {
1 public static ResourceBundle myResources =
1 ResourceBundle.getBundle("domain-name");
1 public static String _(String s) {
1 return myResources.getString(s);
1 }
1 }
1
1 and the shorthand is used like this:
1
1 System.out.println(S._("Operation completed."));
1
1 Which of the three idioms you choose, will depend on whether your
1 project requires portability to Java versions prior to Java 1.5 and, if
1 so, whether copying two lines of codes into every class is more
1 acceptable in your project than a class with a single-letter name.
1