This chapter includes the following sections:
Internationalization is the process of designing and developing products for easy adaptation to specific local languages and cultures. Localization is the process of adapting a product for a specific local language or culture by translating text and adding locale-specific components. A successfully localized application will appear to have been developed within the local culture. JDeveloper supports easy localization of ADF Faces components using the abstract class java.util.ResourceBundle
to provide locale-specific resources.
When your application will be viewed by users in more than one country, you can configure your JSF page or application to use different locales so that it displays the correct language for the language setting of a user's browser. For example, if you know your page will be viewed in Italy, you can localize your page so that when a user's browser is set to use the Italian language, text strings in the browser page appear in Italian.
ADF Faces components may include text that is part of the component, for example the af:table
component uses the resource string af_table.LABEL_FETCHING
for the message text that displays in the browser while the af:table
component fetches data during the initial load of data or while the user scrolls the table. JDeveloper provides automatic translation of these text resources into 28 languages. These text resources are referenced in a resource bundle. You must enable support for each language that you want your application to support by specifying the <supported-locale>
element in the faces-config.xml
file. For example, if you set the browser to use the language in Italy, and you add <supported-locale>it</supported-locale>
to the faces-config.xml
file, any text contained within the components automatically displays in Italian. For more information, see How to Register a Locale for Your Application.
For any text you add to a component, for example if you define the label of an af:button
component by setting the text
attribute, you must provide a resource bundle that holds the actual text, create a version of the resource bundle for each locale, and add a <locale-config>
element to define default and support locales in the application's faces-config.xml
file. You must also add a <resource-bundle>
element to your application's faces-config.xml
file in order to make the resource bundles available to all the pages in your application. Once you have configured and registered a resource bundle, the Expression Builder displays the key from the bundle, making it easier to reference the bundle in application pages.
To simplify the process of creating text resources for text you add to ADF Faces components, JDeveloper supports automatic resource bundle synchronization for any translatable string in the visual editor. When you edit components directly in the visual editor or in the Properties window, text resources are automatically created in the base resource bundle. For more information, see Using Automatic Resource Bundle Integration in JDeveloper.
Note:
Any text retrieved from the database is not translated. This document explains how to localize static text, not text that is stored in the database.
Assume, for example, that you have a panel box with a title of My Purchase Requests. Rather than set the literal string, My Purchase Requests
, as the value of the af:panelBox
component's text
attribute, you bind the value of the text
attribute to a key in the UIResources
resource bundle. The UIResources
resource bundle is registered in the faces-config.xml
file for the application, as shown in the following example.
<resource-bundle> <base-name>resources.UIResources</base-name> <var>res</var> </resource-bundle>
The resource bundle is given a variable name (in this case, res
) that can then be used in EL expressions. On the page, the text
attribute of the af:panelBox
component is then bound to the myDemo.pageTitle
key in that resource bundle, as shown in the folloiwng example.
<af:panelBox text="#{res['myDemo.pageTitle']}" .... id="pb1">
The UIResources
resource bundle has an entry in the English language for all static text displayed on each page in the application, as well as for text for messages and global text, such as generic labels. Example 34-1 shows the keys for the myDemo page. Example 34-2
shows the resource bundle version for the Italian (Italy) locale,
UIResources_it
. Note that there is no entry for the selection facet's title, yet it was translated from Select to Seleziona automatically. That is because this text is part of the ADF Faces table
component's selection facet.
Note that text in the banner image and data retrieved from the database are not translated.
Example 34-1 Resource Bundle Keys for the myDemo Page Displayed in English
#myDemo Screen
myDemo.pageTitle=My Purchase Requests
myDemo.menubar.openLink=Open Requests
myDemo.menubar.pendingLink=Requests Awaiting customer
Example 34-2 Resource Bundle Keys for the myDemo Page Displayed in Italian
#myDemo Screen myDemo.pageTitle=Miei Ticket myDemo.menubar.openLink=Ticket Aperti myDemo.menubar.pendingLink=Ticket in Attesa del Cliente
You may find it helpful to understand other ADF Faces features before you internationalize or localize your application. Additionally, once you have internationalized or localized your application, you may find that you need to add functionality such as accessibility or render ADF Faces components from right to left. Following are links to other functionality that you can use.
Using parameters in text: You can use the ADF Faces EL format tags if you want the text displayed in a component to contain parameters that will resolve at runtime. For more information, see How to Use the EL Format Tags.
Pseudo-classes: ADF skins support a number of pseudo-classes that you can use to change how an application renders in a particular locale. For example, the :rtl
pseudo-class renders ADF Faces components from right to left. This may be useful if your application is localized into languages, such as Arabic and Hebrew, that read from right to left. For more information, see Customizing the Appearance Using Styles and Skins.
Accessibility: You can make the pages in your application accessible. For more information, see Developing Accessible ADF Faces Pages.
Global resource strings: The default resource bundle stores the global resource strings that ADF Faces components support and the resource strings that are specific to individual components. For information about these resource strings, see the Tag Reference for Oracle ADF Faces Skin Selectors.
Touch Devices: ADF Faces components may behave and display differently on touch devices. For more information, see Creating Web Applications for Touch Devices Using ADF Faces
Drag and Drop: You can configure your components so that the user can drag and drop them to another area on the page. For more information, see Adding Drag and Drop Functionality
JDeveloper supports the automatic creation of text resources in the default resource bundle when editing ADF Faces components in the visual editor. To treat user-defined strings as static values, clear the Automatically Synchronize Bundle checkbox in the Project Properties dialog, as described in How to Set Resource Bundle Options.
Automatic resource bundle integration can be configured to support one resource bundle per page or project.
You can edit translatable text strings using the Select Text Resource dialog shown in Figure 34-1. The dialog can be accessed from the Properties window by clicking the icon that appears when you hover over the property field of a translatable property and select Select Text Resource from the context menu. For more information on using this dialog, see How to Create an Entry in a JDeveloper-Generated Resource Bundle
.
Figure 34-1 Select Text Resource Dialog
You can set resource bundle options for your project in the Project Properties dialog.
Before you begin:
It may help to understand how JDeveloper manages resource bundles. For more information, see Using Automatic Resource Bundle Integration in JDeveloper.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To set resource bundle options for a project:
JDeveloper generates one or more resource bundles of a particular type based on the selections that you make in the resource bundle options part of the Project Properties dialog, as illustrated in Figure 34-2. It generates a resource bundle the first time that you invoke the Select Text Resource dialog, as illustrated in Figure 34-1
.
Assume, for example, that you select the One Bundle Per Project checkbox and the List Resource Bundle
value from the Resource Bundle Type dropdown list. The first time that you invoke the Select Text Resource dialog, JDeveloper generates one resource bundle for the project. The generated resource bundle is a Java class named after the default project bundle name in the Project Properties dialog (for example, ViewControllerBundle.java
).
JDeveloper generates a resource bundle as an .xlf
file if you select the XML Localization Interchange File Format (XLIFF) Bundle option and a .properties
file if you select the Properties Bundle option.
By default, JDeveloper creates the generated resource bundle in the view subdirectory of the project's Application Sources directory.
JDeveloper generates one or more resource bundles based on the values you select in the resource bundle options part of the Project Properties dialog. It generates a resource bundle the first time that you invoke the Select Text Resource dialog from a component property in the Properties window.
JDeveloper writes key-value pairs to the resource bundle based on the values that you enter in the Select Text Resource dialog. It also allows you to select an existing key-value pair from a resource bundle to render a runtime display value for a component.
Before you begin:
It may help to understand how JDeveloper manages resource bundles. For more information, see Using Automatic Resource Bundle Integration in JDeveloper.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To create an entry in the resource bundle generated by JDeveloper:
JDeveloper writes the key-value pair that you define in the Select Text Resource dialog to the resource bundle. The options that you select in the resource bundle options part of the Project Properties dialog determine what type of resource bundle JDeveloper writes the key-value pair to. For more information, see What Happens When You Set Resource Bundle Options.
The component property for which you define the resource bundle entry uses an EL expression to retrieve the value from the resource bundle at runtime. For example, an af:inputText
component's Label property may reference an EL expression similar to the following:
#{viewcontrollerBundle.Label1}
where viewcontrollerBundle
references the resource bundle and Label1
is the key for the runtime value.
A resource bundle contains a number of named resources, where the data type of the named resources is String
. A bundle may have a parent bundle. When a resource is not found in a bundle, the parent bundle is searched for the resource. Resource bundles can be either Java classes, property files, or XLIFF files. The abstract class java.util.ResourceBundle
has two subclasses:
java.util.PropertyResourceBundle
java.util.ListResourceBundle
A java.util.PropertyResourceBundle
is stored in a property file, which is a plain-text file containing translatable text. Property files can contain values only for String
objects. If you need to store other types of objects, you must use a java.util.ListResourceBundle
class instead.
For more information about using XLIFF, see http://docs.oasis-open.org/xliff/xliff-core/xliff-core.html
To add support for an additional locale, replace the values for the keys with localized values and save the property file, appending a language code (mandatory) and an optional country code and variant as identifiers to the name, for example, UIResources_it.properties
.
The java.util.ListResourceBundle
class manages resources in a name and value array. Each java.util.ListResourceBundle
class is contained within a Java class file. You can store any locale-specific object in a java.util.ListResourceBundle
class. To add support for an additional locale, you create a subclass from the base class, save it to a file with a locale or language extension, translate it, and compile it into a class file.
The ResourceBundle
class is flexible. If you first put your locale-specific String
objects in a java.util.PropertyResourceBundle
file, you can still move them to a ListResourceBundle
class later. There is no impact on your code, because any call to find your key will look in both the java.util.ListResourceBundle
class and the java.util.PropertyResourceBundle
file.
The precedence order is class before properties. So if a key exists for the same language in both a class file and a property file, the value in the class file will be the value presented to you. Additionally, the search algorithm for determining which bundle to load is as follows:
(baseclass)+(specific language)+(specific country)+(specific variant)
(baseclass)+(specific language)+(specific country)
(baseclass)+(specific language)
(baseclass)+(default language)+(default country)+(default variant)
(baseclass)+(default language)+(default country)
(baseclass)+(default language)
For example, if your browser is set to the Italian (Italy) locale and the default locale of the application is US English, the application attempts to find the closest match, looking in the following order:
it_IT
it
en_US
en
The base class bundle
Tip:
The getBundle
method used to load the bundle looks for the default locale classes before it returns the base class bundle. If it fails to find a match, it throws a MissingResourceException
error. A base class with no suffixes should always exist as a default. Otherwise, it may not find a match and the exception is thrown.
You must create a base resource bundle that contains all the text strings that are not part of the components themselves. This bundle should be in the default language of the application. You can create a resource bundle as a property file, as an XLIFF file, or as a Java class. After a resource bundle file has been created, you can edit the file using the Edit Resource Bundles dialog.
You can create a resource bundle as a property file or as an XLIFF file.
Before you begin:
It may help to understand what types of resource bundle you can create. For more information, see Manually Defining Resource Bundles and Locales.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To create a resource bundle as a property file or an XLIFF file:
You can create a resource bundle as a Java class.
Before you begin:
It may help to understand what types of resource bundle you can create. For more information, see Manually Defining Resource Bundles and Locales.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To create a resource bundle as a Java class:
Example 34-3 Base Resource Bundle Java Class
package sample; import java.util.ListResourceBundle; public class MyResources extends ListResourceBundle { @Override protected Object[][] getContents() { return contents; } static final Object[][] contents { {"button_Search", "Search"}, {"button_Reset", "Reset"} }; }
After you have created a resource bundle property file, XLIFF file, or Java class file, you can edit it using the source editor.
Before you begin:
It may help to understand what types of resource bundles you can define and edit. For more information, see Manually Defining Resource Bundles and Locales.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To edit a resource bundle after it has been created:
You must register the locales that you want your application to support in the application's faces-config.xml
file.
Before you begin:
It may help to understand how you can manually manage resource bundles. For more information, see Manually Defining Resource Bundles and Locales.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To register a locale for your application:
You must register the resource bundles that you want your application to use in the application's faces-config.xml
file.
Before you begin:
It may help to understand how you can manually manage resource bundles. For more information, see Manually Defining Resource Bundles and Locales.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To register a resource bundle:
You set your page encoding and response encoding to all supported languages and you bind to the resource bundle.
Before you begin:
It may help to understand how you can manually manage resource bundles. For more information, see Manually Defining Resource Bundles and Locales.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To use a base resource bundle on your page:
Example 34-4 Binding Using adfBundle
<af:button text="#{adfBundle['project.EmpMsgBundle'] ['Deptno_LABEL']}"
If you use an ADF skin and have created a custom resource bundle for the skin, you must also create localized versions of the resource bundle. Similarly, if your application uses control hints to set any text, you must create localized versions of the generated resource bundles for that text.
An override bundle is a resource bundle with key-value pairs that differ from the base resource bundle that you want to use in a customizable application that you develop using the Oracle Metadata Services (MDS) framework. If you create an override bundle, you need to configure your application's adf-config.xml
file to support the overriding of the base resource bundle. For example, if you have a base resource bundle with the name oracle.demo.CustAppUIBundle
, you configure an entry in your application's adf-config.xml
file, as shown in Example 34-5, to make it overrideable. Once it is marked as overriden, any customizations of that bundle will be stored in your customizable application's override bundle. The override bundle is maintained in both the default role in JDeveloper and in the customizable application. To avoid having to manage this override bundle in two locations, Oracle recommends that you:
Create a separate resource bundle from the base resource bundle using JDeveloper's default role
Add the key-value pairs that you want to override in your customizable application from the base resource bundle to this separate resource bundle
In the customizable application you pick these key-value pairs from the separate resource bundle. This makes sure that you do not create new key-value pairs in your customizable application's override bundle and that only the customizable application uses the override bundle.
For more information about the adf-config.xml
file, see Configuration in adf-config.xml. For more information about creating customizable applications using MDS, see the "Customizing Applications with MDS" chapter of Developing Fusion Web Applications with Oracle Application Development Framework.
Example 34-5 Entry for Override Bundle in adf-config.xml File
<?xml version="1.0" encoding="UTF-8" ?> <adf-config xmlns="http://xmlns.oracle.com/adf/config" xmlns:config="http://xmlns.oracle.com/bc4j/configuration" xmlns:adf="http://xmlns.oracle.com/adf/config/properties"> ... <adf-resourcebundle-config xmlns="http://xmlns.oracle.com/adf/resourcebundle/config"> <applicationBundleName>oracle/app.../xliffBundle/FusionAppsOverrideBundle</applicationBundleName> <bundleList> <bundleId override="true">oracle.demo.CustAppUIBundle</bundleId> </bundleList> </adf-resourcebundle-config> </adf-config>
You can configure an application so end users can specify the locale at runtime rather than the default behavior where the locale settings of the end user's browser determine the runtime locale. Implement this functionality if you want your application to allow end users to specify their preferred locale and save their preference.
Create a new page or open an existing page. Configure it so that:
It references a backing bean to store locale information
An end user can invoke a control at runtime to update the locale information in the backing bean
The locale
attribute of the f:view
tag references the backing bean
Before you begin:
It may help to understand the configuration options available to you. For more information, see Configuring Pages for an End User to Specify Locale at Runtime.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To configure a page for an end user to specify locale:
Create a page with a backing bean to store locale information.
For more information, see How to Create JSF Pages.
Provide a control (for example, a selectOneChoice
component) that an end user can use to change locale.
For example, in the Components window, from the Text and Selection panel, drag a Choice component and drop it onto the page.
Bind the control to a backing bean that stores the locale value, as illustrated in the following example.
<af:selectOneChoice label="Select Locale" binding="#{backingBeanScope.backing_changeLocale.soc1}" id="soc1"> <af:selectItem label="French" value="FR" binding="#{backingBeanScope.backing_changeLocale.si1}" id="si1"/> ... </af:selectOneChoice>
Bind the locale
attribute of the f:view
tag to the locale value in the backing bean.
In the Structure window for the JSF page, right-click the f:view
tag and choose Go to Properties.
In the Properties window, expand the Common section and choose Expression Builder from the context menu that appears when you click the icon that appears when you hover over the Locale field.
In the Expression Builder, bind to the locale value in the backing bean, as shown in Figure 34-8.
Figure 34-8 Expression Builder Binding the Locale Attribute to a Backing Bean
Save the page.
JDeveloper generates a reference to the backing bean for the command component that you use to change the locale. Example 34-6 shows an example using the
selectOneChoice
component. JDeveloper also generates the required methods in the backing bean for the page. Example 34-7 shows extracts for the backing bean that correspond to Example 34-6
.
Example 34-6 selectOneChoice Component Referencing a Backing Bean
<af:selectOneChoice label="Select Locale" binding="#{backingBeanScope.backing_changeLocale.soc1}" id="soc1"> <af:selectItem label="French" value="FR" binding="#{backingBeanScope.backing_changeLocale.si1}" id="si1"/> ... </af:selectOneChoice>
Example 34-7 Backing Bean Methods to Change Locale
package view.backing; ... import oracle.adf.view.rich.component.rich.input.RichSelectOneChoice; public class ChangeLocale { ... ... private RichSelectOneChoice soc1; ... ... ... public void setD2(RichDocument d2) { this.d2 = d2; } ... public void setSoc1(RichSelectOneChoice soc1) { this.soc1 = soc1; } public RichSelectOneChoice getSoc1() { return soc1; } public void setSi1(RichSelectItem si1) { this.si1 = si1; } ... }
At runtime, an end user invokes the command component you configured to change the locale of the application. The backing bean stores the updated locale information. Pages where the locale
attribute of the f:view
tag reference the backing bean render using the locale specified by the end user.
The locale specified by the end user must be registered with your application. For more information about specifying a locale and associated resource bundles, see How to Register a Locale for Your Application.
Along with providing text translation, ADF Faces also automatically provides other types of translation, such as currency codes and support for bidirectional rendering (also known as BiDi support). The application will automatically be displayed appropriately, based on the user's selected locale. However, you can also manually set the following localization settings for an application in the trinidad-config.xml
file:
<currency-code>
: Defines the default ISO 4217 currency code used by oracle.adf.view.faces.converter.NumberConverter
to format currency fields that do not specify a currency code in their own converter.
<number-grouping-separator>
: Defines the separator used for groups of numbers (for example, a comma). ADF Faces automatically derives the separator from the current locale, but you can override this default by specifying a value in this element. If set, this value is used by oracle.adf.view.faces.converter.NumberConverter
while it parses and formats.
<decimal-separator>
: Defines the separator used for the decimal point (for example, a period or a comma). ADF Faces automatically derives the separator from the current locale, but you can override this default by specifying a value in this element. If set, this value is used by oracle.adf.view.faces.converter.NumberConverter
while it parses and formats.
<right-to-left>
: Defines the direction in which text appears in a page. ADF Faces supports bidirectional rendering and automatically derives the rendering direction from the current locale, but you can explicitly set the default page rendering direction by using the values true
or false
.
<formatting-locale>
: Defines the date and number format appropriate to the selected locale. By default, ADF Faces will format dates and numbers in the same locale used for localized text. If you want dates and numbers formatted in a different locale, you can use an IANA-formatted locale (for example, ja, fr-CA). The contents of this element can also be an EL expression pointing at an IANA string or a java.util.Locale
object.
To set the time zone used for processing and displaying dates, and the year offset that should be used for parsing years with only two digits, use the following elements:
<time-zone>
: By default, ADF Faces uses the time zone used by the application server if no value is set. If needed, you can use an EL expression that evaluates to a TimeZone
object. This value is used by org.apache.myfaces.trinidad.converter.DateTimeConverter
while converting strings to Date
.
<two-digit-year-start>
: This value is specified as a Gregorian calendar year and is used by org.apache.myfaces.trinidad.converter.DateTimeConverter
to convert strings to Date
. This element defaults to the year 1950 if no value is set. If needed, you can use a static integer value or an EL expression that evaluates to an Integer
object.
For more information about the elements that you can configure in the trinidad-config.xml
file, see Configuration in trinidad-config.xml.
You can configure optional localization properties by entering elements in your application's trinidad-config.xml
file.
Before you begin:
It may help to understand what optional localization properties you can modify. For more information, see Manually Defining Resource Bundles and Locales.
You may also find it helpful to understand functionality that can be added using other Oracle ADF features. For more information, see Additional Functionality for Internationalizing and Localizing Pages.
To configure optional localization properties:
<trinidad-config>
element.Example 34-8 shows a sample
trinidad-config.xml
file with all the optional localization elements set.
Example 34-8 Configuring Currency Code and Separators for Numbers and Decimal Point
<!-- Set the currency code to US dollars. --> <currency-code>USD</currency-code> <!-- Set the number grouping separator to period for German --> <!-- and comma for all other languages --> <number-grouping-separator> #{view.locale.language=='de' ? '.' : ','} </number-grouping-separator> <!-- Set the decimal separator to comma for German --> <!-- and period for all other languages --> <decimal-separator> #{view.locale.language=='de' ? ',' : '.'} </decimal-separator> <!-- Render the page right-to-left for Arabic --> <!-- and left-to-right for all other languages --> <right-to-left> #{view.locale.language=='ar' ? 'true' : 'false'} </right-to-left> <formatting-locale> #{request.locale} </formatting-locale> <!-- Set the time zone to Pacific Daylight Savings Time --> <time-zone>PDT</time-zone>