Skip to content

Internationalization

Steven Soloff edited this page Feb 15, 2017 · 1 revision

Overview

Internationalization (I18N) refers to the architecture and design of software such that only one set of source code and binary is produced to support all the markets in which the software will be used.

What Should NOT be Internationalized

Not everything in Gamegineer should be designed for internationalization for reasons of both performance and maintenance.

Debug Traces

Debug traces (i.e. any message ultimately sent to a method of the org.gamegineer.common.core.runtime.Debug class) must always be in English. They are intended only to be viewed by the development team. When debug tracing is enabled, tens of messages may be output per second, thus performance considerations dictate these messages should be as simple as possible. Debug trace messages should always be embedded directly in the code -- they should never be read from a resource bundle to avoid them from being accidentally localized. Any formatting required should be done in-place using either java.lang.String.format or java.text.MessageFormat.format.

Support Log

Support log messages (i.e. any message ultimately sent to the java.util.logging.Logger.log method of a java.util.logging.Logger instance obtained from the org.gamegineer.common.core.logging.ILoggingService service) must always be in English. They are intended only to be viewed by the development team and support personnel. It is highly recommended to place support log messages in a resource bundle for several reasons:

  • It provides a common location in which all messages can be reviewed and edited, possibly by a non-developer.
  • A message which is used in multiple log statements only has to be maintained in a single location.
  • The decision to not localize the support log may be changed in the future. By placing these messages in a resource bundle, the support log is I18N-ready.

Exception Detail Messages

Exception detail messages (i.e. the return value of the java.lang.Throwable.getMessage method) must always be in English. This is necessary because exception detail messages will inevitably be output as a debug trace and to the support log. As with the support log, it is recommended to place exception detail messages in a resource bundle for the same reasons outlined above.

If you are building a message for a debug trace or a support log that contains information about an exception, you should strive to ensure java.lang.Throwable.getMessage is called to guarantee a non-localized message is output. Note that java.lang.Throwable.toString invokes java.lang.Throwable.getLocalizedMessage and may not yield the desired result in all cases (see below).

What Should be Internationalized

In general, end-user facing information should be internationalized, but there may be some gray areas as described below.

User Interface

Any information appearing in the user interface must be internationalized. All locale-sensitive information must be placed in a resource bundle.

Exceptions

It is inevitable that exceptions will occur in the software and must be reported to the end-user in a locale-sensitive manner. The developer has several options for internationalizing exceptions.

Internationalization by the Exception Receiver

In this case, the exception receiver will use information carried by the exception itself to generate an internationalized message. At the most basic level, the exception class may be mapped to a specific message. Sometimes additional information will be required to format the message appropriately (e.g. the line number where a parse error occurred). This information should be available to the receiver via accessor methods on the exception itself (e.g. a getLineNumber method).

Internationalization by the Exception Originator

The previous option may not be appropriate in all cases because it may require the introduction of numerous abstractions simply to support the receiver being able to determine the correct context necessary for internationalization. In this case, it is acceptable to have the exception originator provide a localized message for consumption by the receiver. The exception subclass must override the java.lang.Throwable.getLocalizedMessage method to return the localized detail message. Note that receivers must still have some means of determining if an exception can provide a localized message. This may be accomplished by checking the type of the exception for a specific class, interface, or annotation.

If this option is chosen, the implementer of the locale-aware exception class must still abide by the requirement above that the detail message returned by java.lang.Throwable.getMessage should not be localized. Therefore, the exception class must provide a mechanism for setting the localized message independently of the non-localized message. The localized exception detail messages must be placed in a resource bundle.

If the implementer has chosen to place the non-localized exception detail messages in a resource bundle as recommended above, a strategy must be chosen for ensuring both localized and non-localized messages can be loaded as expected. If both types of messages are co-located in the same resource bundle, one strategy would be to choose a different key for the non-localized message (e.g. use the localized key with the suffix "_non_nls") and ensure these values are not copied to the locale-specific property files. Another strategy is to simply split the localized and non-localized messages into two separate resource bundles.