Supporting multiple languages in ADF applications backed by resource bundles – and programmatically controlling the JSF locale
Java (Web) applications typically make use of a built in structure for centralizing (and internationalizing) boiler plate text; it is called Resource Bundle. Usually, resource bundles are implemented using property files – one per supported language – that contain key-value pairs; note that the XLIFF file format for resource bundles is gaining ground. The key is referred to in pages, code and wherever a boiler plate text element is required, the value is the language specific and centrally managed translation of the key.
In two previous articles, I have explained how to centralize the boilerplate text elements in ADF applications using resource bundles – either plain file based resource bundles (http://technology.amis.nl/2012/08/09/introduction-to-resource-bundles-in-adf-applications-for-centralizing-management-of-boilerplate-text) or resource bundles implemented using a database (http://technology.amis.nl/2012/08/10/implement-resource-bundles-for-adf-applications-in-a-database-table/). These two articles did not discuss how multiple languages can be supported and how the user can pick his or her favorite language. That is the purpose of this article.
In later articles I will discuss how to support not just different boilerplate text items for different languages but also different sets of boiler plate text for user groups that vary by location, role, department, age or personal preference. We will discuss how to refresh a resource bundle in running application and finally we will see how we can create an in-line resource bundle editing mechanism that allows users to manipulate the boiler plate text in context in a running application.
1. Specify supported locales in faces-config.xml
2. Create resource bundles per language
property file – create new files with the language as appendix to the file name, for example ApplicationBundle_en.properties and ApplicationBundle_nl.properties.
Java Class – the same approach: create a class per supported language and add _<language code> as suffix to the classname.
Additionally, the method getLocaleCode() needs to be defined in each of the classes:
3. Add entries for all supported languages to the resource bundle
Either the property files for the database table – depending on the implementation – needs to be extended with the proper key value pairs for the supported languages. Of course the keys are the same for all languages!
Here two new entries for the nl support (Dutch):
4. Run the page.
Try switching to a different preferred language. The default behavior for JSF is to take the locale set in the browser as the current locale. By changing the browser locale, you can instruct JSF therefore to change to a different language.
and the page renders like this:
5. Programmatically taking control of the locale in JSF
You may not always want to go with the locale defined in the browser. You may for example want to offer the user an option of selecting the language in the application itself. The JSF behavior can be overridden. One way of doing so is by explicitly setting the local on the f:view component using the locale attribute, that can either be static or set using an EL expression or by overriding the ViewHandler. I will discuss and implement this approach.
The ViewHandler in JSF takes care of determining the current locale, using the calculateLocale() method. The default implementation derives the locale from the browser setting. The default ViewHandler can be overridden with our own implementation. This is done by creating a class that extends from an existing ViewHandler implementation – overriding the calculateLocale() method – and by configuring the ViewHandler in faces-config.xml.
The LocaleSettingViewHandler is implemented like this:
The remainder of this class is quite important too, as it ensures that all normal operations by the ViewHandler still take place:
and there is the local utility method to evaluate EL expressions:
Here the calculateLocale() method refers in an EL expression to a managed bean. This bean has a language property, that can be manipulated by the user through a drop down component in the page:
The managed bean definition:
The ViewHandler is configured in faces-config.xml:
6. Run the page.
The default locale is still English – because the managed bean says so, not because of the browser setting.
Changing the selected language
and refreshing the page, using the newly selected language for retrieving the resource bundle entries:
Download the ADF application described in this article: ADFFacesWithResourceBundle_step3_multipleLanguagesAndLocaleControl.
Article on http://www.i-coding.de/www/en/jsf/application/locale.html describing how to set the locale.
Other articles in this series:
- Implement resource bundles for ADF applications in a database table
- Introduction to Resource Bundles in ADF applications for centralizing (management of) boilerplate text
- Context Sensitive Resource Bundle entries in JavaServer Faces applications – going beyond plain language, region & variant locales
- Personalize Resource Bundles in ADF applications with JHeadstart 10.3.2 run time
- Testing i18n features of JSF applications – Forcing a refresh of the Resource Bundle(s)
- ADF: (Automatic) Partial Page Rendering across Taskflows
- ADF client-side architecture – Select All
- On the Integrity of Data
- ADF DVT: Analyzing Financial Position of the European Football (Soccer) Leagues using Treemap
- ADF DVT – Scaling TreeMap components for comparisons across masters and categories
- ADF DVT: Using the Tree Map visualization component – to compare relative sizes and distributions
- ADF DVT: Using the Timeline component to visualize the recent history of an RSS feed
- ADF: (re-)Introducing Contextual Events in several simple steps
- ADF DVT Speed Date: Interactive Bubble Graph
- Out of the box usage of ADF DVT Scheduling Gantt Chart to report Database Query Results using stacked bar charts per time period