|
Version 4.10.0 | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
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 :
Translator
can also
be used, even in a single-language application, to translate from such 'coder keys'
to user-presentable text.
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):
BaseText | Locale | Translation |
---|---|---|
Fish And Chips | en | Fish And Chips |
Fish And Chips | fr | Poisson et Frites |
delete | en | delete |
delete | fr | supprimer |
add.edit.button | en | Add/Edit |
add.edit.button | fr | Ajouter/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 |
---|
String get(String aBaseText, Locale 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
RuntimeException
when
an item is missing, but this is not recommended for applications in production
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.
aBaseText
- is not null, but may be emptyaLocale
- comes from the configured LocaleSource
.
|
Version 4.10.0 | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |