@c This file is part of the GNU gettext manual.
@c Copyright (C) 1995-2020 Free Software Foundation, Inc.
@c See the file gettext.texi for copying conditions.

@node Java
@subsection Java
@cindex Java

@table @asis
@item RPMs
java, java2

@item Ubuntu packages
default-jdk

@item File extension
@code{java}

@item String syntax
"abc", """text block"""

@item gettext shorthand
i18n("abc")

@item gettext/ngettext functions
@code{GettextResource.gettext}, @code{GettextResource.ngettext},
@code{GettextResource.pgettext}, @code{GettextResource.npgettext}

@item textdomain
---, use @code{ResourceBundle.getResource} instead

@item bindtextdomain
---, use CLASSPATH instead

@item setlocale
automatic

@item Prerequisite
---

@item Use or emulate GNU gettext
---, uses a Java specific message catalog format

@item Extractor
@code{xgettext -ki18n}

@item Formatting with positions
@code{MessageFormat.format "@{1,number@} @{0,number@}"}
or @code{String.format "%2$d %1$d"}

@item Portability
fully portable

@item po-mode marking
---
@end table

Before marking strings as internationalizable, uses of the string
concatenation operator need to be converted to @code{MessageFormat}
applications.  For example, @code{"file "+filename+" not found"} becomes
@code{MessageFormat.format("file @{0@} not found", new Object[] @{ filename @})}.
Only after this is done, can the strings be marked and extracted.

GNU gettext uses the native Java internationalization mechanism, namely
@code{ResourceBundle}s.  There are two formats of @code{ResourceBundle}s:
@code{.properties} files and @code{.class} files.  The @code{.properties}
format is a text file which the translators can directly edit, like PO
files, but which doesn't support plural forms.  Whereas the @code{.class}
format is compiled from @code{.java} source code and can support plural
forms (provided it is accessed through an appropriate API, see below).

To convert a PO file to a @code{.properties} file, the @code{msgcat}
program can be used with the option @code{--properties-output}.  To convert
a @code{.properties} file back to a PO file, the @code{msgcat} program
can be used with the option @code{--properties-input}.  All the tools
that manipulate PO files can work with @code{.properties} files as well,
if given the @code{--properties-input} and/or @code{--properties-output}
option.

To convert a PO file to a ResourceBundle class, the @code{msgfmt} program
can be used with the option @code{--java} or @code{--java2}.  To convert a
ResourceBundle back to a PO file, the @code{msgunfmt} program can be used
with the option @code{--java}.

Two different programmatic APIs can be used to access ResourceBundles.
Note that both APIs work with all kinds of ResourceBundles, whether
GNU gettext generated classes, or other @code{.class} or @code{.properties}
files.

@enumerate
@item
The @code{java.util.ResourceBundle} API.

In particular, its @code{getString} function returns a string translation.
Note that a missing translation yields a @code{MissingResourceException}.

This has the advantage of being the standard API.  And it does not require
any additional libraries, only the @code{msgcat} generated @code{.properties}
files or the @code{msgfmt} generated @code{.class} files.  But it cannot do
plural handling, even if the resource was generated by @code{msgfmt} from
a PO file with plural handling.

@item
The @code{gnu.gettext.GettextResource} API.

Reference documentation in Javadoc 1.1 style format is in the
@uref{javadoc2/index.html,javadoc2 directory}.

Its @code{gettext} function returns a string translation.  Note that when
a translation is missing, the @var{msgid} argument is returned unchanged.

This has the advantage of having the @code{ngettext} function for plural
handling and the @code{pgettext} and @code{npgettext} for strings constraint
to a particular context.

@cindex @code{libintl} for Java
To use this API, one needs the @code{libintl.jar} file which is part of
the GNU gettext package and distributed under the LGPL.
@end enumerate

Four examples, using the second API, are available in the @file{examples}
directory: @code{hello-java}, @code{hello-java-awt}, @code{hello-java-swing},
@code{hello-java-qtjambi}.

Now, to make use of the API and define a shorthand for @samp{getString},
there are three idioms that you can choose from:

@itemize @bullet
@item
(This one assumes Java 1.5 or newer.)
In a unique class of your project, say @samp{Util}, define a static variable
holding the @code{ResourceBundle} instance and the shorthand:

@smallexample
private static ResourceBundle myResources =
  ResourceBundle.getBundle("domain-name");
public static String i18n(String s) @{
  return myResources.getString(s);
@}
@end smallexample

All classes containing internationalized strings then contain

@smallexample
import static Util.i18n;
@end smallexample

@noindent
and the shorthand is used like this:

@smallexample
System.out.println(i18n("Operation completed."));
@end smallexample

@item
In a unique class of your project, say @samp{Util}, define a static variable
holding the @code{ResourceBundle} instance:

@smallexample
public static ResourceBundle myResources =
  ResourceBundle.getBundle("domain-name");
@end smallexample

All classes containing internationalized strings then contain

@smallexample
private static ResourceBundle res = Util.myResources;
private static String i18n(String s) @{ return res.getString(s); @}
@end smallexample

@noindent
and the shorthand is used like this:

@smallexample
System.out.println(i18n("Operation completed."));
@end smallexample

@item
You add a class with a very short name, say @samp{S}, containing just the
definition of the resource bundle and of the shorthand:

@smallexample
public class S @{
  public static ResourceBundle myResources =
    ResourceBundle.getBundle("domain-name");
  public static String i18n(String s) @{
    return myResources.getString(s);
  @}
@}
@end smallexample

@noindent
and the shorthand is used like this:

@smallexample
System.out.println(S.i18n("Operation completed."));
@end smallexample
@end itemize

Which of the three idioms you choose, will depend on whether your project
requires portability to Java versions prior to Java 1.5 and, if so, whether
copying two lines of codes into every class is more acceptable in your project
than a class with a single-letter name.
