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