Translation of text for multilingual applications.

### Last-Second Localization

WEB4J's goal is to make the task of changing a single-language application into a multilingual one as painless and as focused as possible, with minimal ripple effects. To support this idea, WEB4J has two main design goals :

- Model Objects, actions, and Data Access Objects should be exactly the same regardless of whether the application is multilingual or not.
- Markup in a multilingual application should appear almost the same as in a single language application.

To achieve the first goal, WEB4J uses a policy of "last-second localization", whereby translations are performed outside of normal code, and only in Java Server Pages, using custom tags. This corresponds to the idea that a translation is "just a view".

### Overview

The various items are :

- {@link hirondelle.web4j.request.LocaleSource} defines how an application deduces a {@link java.util.Locale} from an incoming request (using a policy defined by your application).
- the `Locale` obtained from {@link hirondelle.web4j.request.LocaleSource} is passed to a {@link hirondelle.web4j.ui.translate.Translator}, which defines how an application translates base text into a given target language.
- the {@link hirondelle.web4j.ui.translate.Text} tag uses the above to perform the translation "at the last second", in a JSP.
- the {@link hirondelle.web4j.ui.translate.TextFlow} tag translates all the text flow (the text appearing outside of tags) appearing in its body. This tag is suitable for translating large sections of markup whose text flow is simple and non-structured.
- the {@link hirondelle.web4j.ui.translate.Tooltips} tag translates all `TITLE` and `ALT` attributes appearing in its body (it also translates the text of `SUBMIT` buttons). If placed in a high-level template, it translates those attributes across a large number of pages - perhaps even the whole site.
- the {@link hirondelle.web4j.ui.translate.Messages} tag translates the {@link hirondelle.web4j.model.AppResponseMessage}s emitted by {@link hirondelle.web4j.action.Action}s.

### Translatable Items

Translatable items include :

- static text in a web page
- tooltips - the `TITLE` and `ALT` attributes of tags
- links whose target is dependent on `Locale`
- dynamic messages generated by the application

### Suggested Development Style

For a new multilingual application, one may proceed as follows :

- start development with a do-nothing {@link hirondelle.web4j.ui.translate.Translator}, that simply returns the base text, unchanged and untranslated
- use the {@link hirondelle.web4j.ui.translate.Text}, {@link hirondelle.web4j.ui.translate.Tooltips}, {@link hirondelle.web4j.ui.translate.TextFlow}, and {@link hirondelle.web4j.ui.translate.Messages} tags during development, to internationalize JSPs from the beginning. (The text is not localized at this point.)
- when nearing completion, begin localization by changing the {@link hirondelle.web4j.ui.translate.Translator} implementation, to always record the base text in some way (save to the database, or to an in-memory `List`, for example). Thus, by simply exercising all parts of the application (including all possible error messages), one may generate a listing of all items that need translation.
- finally, translate all items, and provide the "correct" {@link hirondelle.web4j.ui.translate.Translator} implementation. (See the example application for illustration.)

If an existing application needs to be changed from a single-language style to a multilingual style, then a similar technique may be used.

### Database versus {@link java.util.ResourceBundle}

Although a {@link hirondelle.web4j.ui.translate.Translator} may be backed by a `ResourceBundle`, the recommended style is to use a database instead. `ResourceBundle` is a mediocre tool for web applications.