Static String Internationalization

Static string localization relies on code generation from properties files. GWT supports static string localization through two tag interfaces (that is, interfaces having no methods that represent a functionality contract) and a code generation library to generate implementations of those interfaces.

For example, if you wanted to localize the constant strings "hello, world" and "goodbye, world" in your GWT application, you could define an interface that abstracts those strings by extending the built-in Constants interface:

public interface MyConstants extends Constants {
  String helloWorld();
  String goodbyeWorld();
}
Now create an associated default properties file called MyConstants.properties in the same package:
helloWorld = hello, world
goodbyeWorld = goodbye, world
You can also create a localized translation for each supported locale in separate properties file. In this case, we localize for Spanish:
helloWorld = hola, mundo
goodbyeWorld = adiós, mundo
To use the internationalized constants, you create an implementation of MyConstants using GWT.create(Class):
public void useMyConstants() {
  MyConstants myConstants = (MyConstants) GWT.create(MyConstants.class);
  Window.alert(myConstants.helloWorld());
}

The Benefits of Static String Internationalization

As you can see from the example above, static internationalization relies on a very tight binding between internationalized code and its localized resources. Using explicit method calls in this way has a number of advantages. The GWT compiler can optimize deeply, removing uncalled methods and inlining localized strings -- making generated code as efficient as if the strings had been hard-coded.

The value of compile-time checking becomes even more apparent when applied to messages that take multiple arguments. Creating a Java method for each message allows the compiler to check both the number and types of arguments supplied by the calling code against the message template defined in a properties file. For example, attempting to use this interface:

public interface ErrorMessages extends Messages {
  String permissionDenied(int errorCode, String username);
}
with this properties file:
permissionDenied = Error {0}: User {1} does not have permission to access {2} 
results in a compile-time error because the message template in the properties file expects three arguments, while the permissionDenied method can only supply two.

Which Interface to Use?

Extend Constants to create a collection of constant values of a variety of types that can be accessed by calling methods (called constant accessors) on an interface. Constant accessors may return a variety of types, including strings, numbers, booleans, and even maps. A compile-time check is done to ensure that the value in a properties file matches the return type declared by its corresponding constant accessor. In other words, if a constant accessor is declared to return an int, its associated property is guaranteed to be a valid int value -- avoiding a potential source of runtime errors.

ConstantsWithLookup is identical to Constants except that the interface also includes a method to look up strings by property name, which facilitates dynamic binding to constants by name at runtime. ConstantsWithLookup can sometimes be useful in highly data-driven applications. One caveat: ConstantsWithLookup is less efficient than Constants because the compiler cannot discard unused constant methods, resulting in larger applications.

Extend Messages to create a collection of formatted messages that can accept parameters. You might think of the Messages interface as a statically verifiable equivalent of the traditional Java combination of Properties, ResourceBundle, and MessageFormat rolled into a single mechanism.

Properties Files

All of the types above use properties files based on the traditional Java properties file format, although GWT uses an enhanced properties file format that are encoded as UTF-8 and can therefore contain Unicode characters directly.

Related topics

Constants, ConstantsWithLookup, Messages, Localized Properties Files, Dynamic String Internationalization, Dictionary