Supporting multiple languages in ADF applications backed by resource bundles – and programmatically controlling the JSF locale

0

Any web application contains boiler plate text: text that is not part of the enterprise data from web services or databases that is manipulated by the end users using the application but that is part of the application definition itself. Text that is shown as prompt, title, message, hint text and in other ways. Developers can sprinkle the boilerplate text all throughout the application, in pages, JavaScript and other code sections. But they should not do that. Changing boiler plate text is a frequent requirement from the business. Having all boilerplate text in a central location makes such changes a lot easier. Additionally, many organizations require applications to be multi-lingual: different groups of users speak different languages and want to have the application support them in their own language. That means boiler plate text is not just defined once in that central location, but once for every language the application needs to support.

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

image

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.

image

Additionally, the method getLocaleCode() needs to be defined in each of the classes:

image

and

image

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):

image

4. Run the page.

image

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.

image

and the page renders like this:

image

 

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:

image

The remainder of this class is quite important too, as it ensures that all normal operations by the ViewHandler still take place:

image

and there is the local utility method to evaluate EL expressions:

image

 

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:

image

defined through:

image

 

image

The managed bean definition:

image

The ViewHandler is configured in faces-config.xml:

image

6. Run the page.

The default locale is still English – because the managed bean says so, not because of the browser setting.

image

Changing the selected language

image

and refreshing the page, using the newly selected language for retrieving the resource bundle entries:

image

 

Resources

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:

  1. Introduction to Resource Bundles in ADF applications for centralizing (management of) boilerplate text

  2. Implement resource bundles for ADF applications in a database table

  3. Supporting multiple languages in ADF applications backed by resource bundles – and programmatically controlling the JSF locale

  4. Adding customization (or context sensitivity) to boilerplate text from database backed resource bundles in ADF applications

  5. Refresh resource bundle from within the ADF application – to absorb changes in database backed bundles

  6. Live update of Resource Bundle from within running ADF application

  7. Live resource bundle entry editing in a generic way through declarative component and UI component tree manipulation

  8. Creating reusable ADF Library with generic live resource bundle editing functionality and reusing it in any ADF application

Share.

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director for Fusion Middleware. Consultant, trainer and instructor on diverse areas including Oracle Database (SQL & PLSQL), Service Oriented Architecture, BPM, ADF, Java in various shapes and forms and many other things. Author of the Oracle Press book: Oracle SOA Suite 11g Handbook. Frequent presenter on conferences such as JavaOne, Oracle OpenWorld, ODTUG Kaleidoscope, Devoxx and OBUG. Presenter for Oracle University Celebrity specials.

Leave a Reply