JavaBeat Feeds
|
|
|
|
|
|
|
|
|
|
String Resources
Wicket can also manage message localization with ResourceBundle properties
files.
The Localizer is a utility class that encapsulates all of the localization
related functionality in Wicket so it can be accessed by all areas of the
framework in a consistent way. All classes derived from Component have a
getLocalizer() method which retrieves the shared Localizer from the
Application. The Localizer maintains a static cache of messages already
retrieved by a key generated from the class, locale, style and messageKey for
the message. Message bundles are looked up using classes derived from
AbstractStringResourceLoader. The Localizer fetches a list of
AbstractStringResourceLoader from the Application object. By default, the
Application provides a ComponentStringResourceLoader and an
ApplicationStringResourceLoader.
In the default setup, the ComponentStringResourceLoader is first asked to
locate the message bundle. If it can't find one (using the algorithm described
below), the ApplicationStringResourceLoader is consulted next. The
ApplicationStringResourceLoader attempts to find a single resource bundle that
has the same name and location as the application
The algorithm employed by ComponentStringResourceLoader to resolve message
requests is described in the javadoc for the AbstractStringResourceLoader:
The component based string resource loader attempts to find the resource from
a bundle that corresponds to the supplied component object or one of its
parent containers. Generally the component will be an instance of Page, but it
may also be an instance of any reusable component that is packaged along with
its own resource files. If the component is not an instance of Page then it
must be a component that has already been added to a page.
The search order for resources is built around the containers that hold the
component (if it is not a page). Consider a Page that contains a Panel that
contains a Label. If we pass the Label as the component then resource loading
will first look for the resource against the page, then against the panel and
finally against the label.
An exception will be thrown if you are using Localizer on a component that has
not already been added to a page. Unless you are sure your component has
already been attached to the Page hierarchy, use StringResourceModel, which
will defer message bundle lookup until after the component has been attached
to a page (during the render process).
The naming convention for resource lookup is the similar to the convention to
markup files. The resource loader is style and locale aware. For example, you
have a page Home with a panel Kitchen that has a panel Sink, and Sink has
labels LeftFawcett (key fawcett.left) and RightFawcett (key fawcett.right)
that need to be localized. Your locale is German and your style is "standard".
The ComponentStringResourceLoader will first look for fawcett.left and
fawcett.right in Home_standard_de_DE.properties, then the same extension for
Kitchen, and then Sink. If the key is not found, it will continue following
the same steps detailed above for the markup files, but for each step trying
it for Home, then Kitchen, then Sink
The Localizer contains powerful ognl string substitution methods for
manipulating message values. Examples are provided in the javadoc for
StringResourceModel, such this:
/** * In this example the found resource string contains an OGNL expression that is * substituted via the model. */ public MyPage extends WebPage { public MyPage(final PageParameters parameters) { WeatherStation ws = new WeatherStation(); add(new Label("weatherMessage", new StringResourceModel("weather.message", this, new Model(ws))); } }
Where the resource bundle contains the entry
weather.message=Weather station reports that the temperature is ${currentTemperature} ${units}
For Localizing components, you mostly will want to rely on
StringResourceModel. As mentioned before, you cannot call getLocalizer on a
component before it has been attached to the framework (added to a hierarchy
that has a Page). StringResourceModel uses Localizer inside it, but does not
get rendered until after the component heirarchy has been established, so no
exceptions. The StringResourceModel offers all the features of Localizer, plus
the application of substitution parameters by java.text.MessageFormat. Again,
there is an example demonstrating this in the StringResourceModel javadocs:
public MyPage extends WebPage { public MyPage(final PageParameters parameters) { WeatherStation ws = new WeatherStation(); Model model = new Model(ws); add(new Label("weatherMessage", new StringResourceModel( "weather.detail", this, model, new Object[] { new Date(), new PropertyModel(model, "currentStatus"), new PropertyModel(model, "currentTemperature"), new PropertyModel(model, "units") })); } }
And where the resource bundle entry is:
weather.detail=The report for {0,date}, shows the temparature as {2,number,###.##} {3} \ and the weather to be {1}
FormValidators derived from AbstractValidator or StringValidator also exploit
Wicket's localization capabilities. Inside, they delegate localization to the
Localizer. There must be a resource bundle properties file in the Localizer
search path that has a messageKey equivalent to
form-name .component-name .validator-class .
This allows the validators to be Style and locale aware. OGNL substitution is
enabled, but parameterized MessageFormat is not.
|