Version 4.10.0

hirondelle.web4j.ui.translate
Interface Translator


public interface Translator

Translate base text into a localized form.

See BuildImpl for important information on how this item is configured. BuildImpl.forTranslator() returns the configured implementation of this interface.

Here, "base text" refers to either :

In code, it is likely best to use user-presentable text instead of coder keys, whenever possible - since lookups are never needed, it makes code clearer at the point of call.

Please see the package overview for an interesting way of evolving the implementation of this interface during development, allowing applications to assist in their own translation.

One might validly object to a framework which requires an implementation of this interface even for single-language applications. However, arguments in favor of such a style include :

The recommended style is to implement this interface with a database, and to avoid ResourceBundle.

Guidance For Implementing With A Database
Example of a web application with the following particular requirements (see the example application for further illustration):

Here is a style of ResultSet that can be used to implement this interface :

BaseTextLocaleTranslation
Fish And ChipsenFish And Chips
Fish And ChipsfrPoisson et Frites
deleteendelete
deletefrsupprimer
add.edit.buttonenAdd/Edit
add.edit.buttonfrAjouter/Changer

Only the last two rows use a "coder key". The BaseText column holds either the coder key, or the user-presentable English. The BaseText is the lookup key. The fact that there is repetition of data between the BaseText and English columns is not a real duplication problem, since this is a ResultSet, not a table - the underlying tables will not have such repetition (if designed properly, of course).

For example, such a ResultSet can be constructed from three underlying tables - BaseText, Locale, and Translation. Translation is a cross-reference table, with foreign keys to both BaseText and Locale. When such a scheme is normalized, it will have no repeated data. (In underlying queries, however, the base language will be necessarily treated differently than the other languages.)

Upon startup, the tables are read, the above ResultSet is created and stored in a private static Map, represented schematically as Map[BaseText, Map[Locale, Translation]]. When a translation is required, this Map is used as an in-memory lookup table. This avoids repeated fetching from the database of trivial data that rarely changes.

Note on Thread Safety
In the suggested implementation style, the private static Map that stores translation data is static, and thus shared by multiple threads. Implementations are free to implement any desired policy regarding thread safety, from relaxed to strict. A relaxed implementation might completely ignore the possibility of a mistaken read/write, since no writes are expected in production, or simply because the consequences are usually trivial. A strict implementation would take the opposite approach, and demand that the private static Map be used in an fully thread-safe manner.


Method Summary
 String get(String aBaseText, Locale aLocale)
          Translate aBaseText into text appropriate for aLocale.
 

Method Detail

get

String get(String aBaseText,
           Locale aLocale)
Translate aBaseText into text appropriate for aLocale.

aBaseText is either user-presentable text in the base language of development, or a "coder key" known only to the programmer.

If aBaseText is unknown, then the implementation is free to define any desired behavior. For example, this method might return

If aBaseText is known, but there is no explicit translation for the given Locale, then an implementation might choose to mimic the behavior of ResourceBundle, and choose a translation from the "nearest available" Locale instead.

Parameters:
aBaseText - is not null, but may be empty
aLocale - comes from the configured LocaleSource.

Version 4.10.0

Copyright Hirondelle Systems. Published October 19, 2013 - User Guide - All Docs.