Using Locale Resources
Web Application Toolkit provides locale resources for client-based, multicultural support in your applications. To support locales in a client, the controller framework gets the client locale from each browser request, and returns an HTML page in the language specified in the request. Therefore, users of various languages are supported—provided that you translate your application's UI strings in the various languages of your users.
Web Application Toolkit includes the following resources for multicultural support:
-
Locale utility classes that retrieve locale-specific UI strings from resource bundles. Because locale-specific information is isolated in resource bundles, you can write program code that is locale independent. Resource bundles are easily translated by non-programmers using any text-editing tool.
-
ResourceParser, a Java™ utility for generating property resource bundles from source code files.
This topic consists of two parts. The first, How Locale Resources are Retrieved, gives you a conceptual understanding of the Toolkit's locale support. The second, Working with Locale Resources, provides guidelines and procedures for working with locale resource strings.
Note that any customization that involves locale resource strings requires an understanding of the Toolkit's locale support—even if you will not be translating resource bundles to another language.
How Locale Resources are Retrieved
Code components that generate a UI (Java, Java™ Server Pages (JSP), XML, XSL) use
WcmString and WcmException to retrieve locale-specific UI strings from
a resource bundle. The following diagram shows a simplified view
of the process, where a locale value is retrieved using a key
prefixed with "server
".
A component requiring a locale-specific string creates an instance of WcmString or WcmException, for example:
private static final WcmString wsInstructions =
new WcmString("server.WcmInstructions.instructionsLink", "Instructions");
...
w.write("<a class='wcmInstructionLink' href=\"" +sFullEventURL = \"" +
wsInstructions.toString(locale) + "</a>");
WcmString and WcmException retrieve locale-specific UI strings from resource bundles using keys.
Property resource bundles are organized by key prefix and language.
A property resource bundle contains key/value pairs of string resources, for example:
server.MultiValuePageSelect_jsp.Available=Available Pages
server.WcmInstructions.instructionsLink=Instructions
server.PrefSiteGeneralInfoPage.application=Application
In the above diagram, a WcmString object is created with a key and a default string. The object's toString()
method gets the locale-specific string from an English language resource bundle. (If there is no matching key in the resource bundle, then the default string in the WcmString constructor is used.)
Note that if the locale passed to the toString()
method were Italy, then WcmString would attempt to get the locale-specific string from an Italian language resource bundle, for example:
server.WcmInstructions.instructionsLink=Istruzioni
WcmException is the functional equivalent of WcmString. Whereas WcmString retrieves locale-specific UI strings, WcmException retrieves locale-specific error strings from exception resource bundles. In the following code snippet, a WcmException object is created with a lookup key, a resource string, and an argument "{0}" to concatenate to the resource string:
if (nodeAttachment == null)
throw new WcmException(locale, "server.WcmEProcessUtil.noAttachment",
"Unknown attachment: {0}", attachmentName);
NOTE The above examples show the locale being passed to WcmString and WcmException. If you don't specify a locale in your calls, the server locale will be used.
Let's look more closely at resource bundles and the locale utility classes that access them.
Property Resource Bundles
- A property resource bundle is a property file that contains key / value pairs of string resources that are used for rendering in the client UI.
- A key is expressed with dot "
.
" syntax, as shown below. Each key is prefixed with a group name, such as "server
", and is followed by the name of the module in which the key is located, and then by a descriptive label.
PrefixModule where key is locatedDescriptive labelValue server
. WcmGeneralPropsInfoPage_xsl
. AliasLabel =
Alias
- A property resource bundle is locale-specific, where the values in the key / value pairs are in the language of a particular locale. However, the keys are in English for all languages.
- Web Application Toolkit includes ResourceParser, a Java utility that generates resource bundles from source code.
- The out-of-the-box resource bundles are generated from the base
Toolkit modules and the Workplace subclasses, and are organized
by the key group name, utility class type (WcmString or WcmException),
and language. For example,
server.strings.en.US.prb
contains key / value pairs of English language strings assigned to keys prefixed with "server
", and that are accessed by WcmString objects. The key / value pairs in theserver.strings.en.US.prb
bundle would be accessed by WcmException objects. - Property resource bundles are referenced in list files. WcmString-based bundles are listed in WcmStringConfiguration.en.US, and WcmException-based bundles are listed in WcmExceptionConfiguration.en.US—where the suffix indicates the locale.
- The out-of-the-box resource bundles, list files, and other string-related resources are located in com.filenet.wcm.toolkit.util, and packaged in WEB-INF/lib/p8workplaceResources.jar.
Locale Utility Classes
- WcmString and
WcmException
are utility classes that retrieve locale-specific UI strings from resource bundles using keys. Whereas WcmString retrieves locale-specific UI strings, WcmException retrieves locale-specific error strings. Note that these classes provide overloaded constructors and
toString
methods for passing or not passing the locale. If you don't pass the locale, the server locale will be used. - Underlying the WcmString and WcmException classes is WcmStringResources, which manages String resources for various locales. WcmString and WcmException retrieve locale-based Strings from
WcmStringResources.getStringResource(...)
andWcmStringResources.getExceptionResource(...)
. - On the first call to
getStringResource(...)
orgetExceptionResource(...)
with a new locale, a new resource map is loaded with the locale-appropriate bundle. - To load new resource maps, WcmStringResources provides
addXXXBundleToPath
methods. - The default behavior for locale lookups in the Toolkit is to get the Enumeration of Locale objects from the request, then to look for the first language support match in the Toolkit default resource bundles packaged in p8workplaceResources.jar. So the language/locale used is based on the language support provided in p8workplaceResources.jar.
- For custom resource bundles, WcmStringResources provides
getXXXBundle
methods for specifying resource bundles that are to get locale lookup priority. These methods are intended to be used during static initialization. - Each new locale specified gets its own new resource map based on the resource path. When new bundles are added to one of the paths, the cached resource maps are cleared so that they are reloaded the next time, including any new path entries.
- Resource maps are static, so multiple instances of WcmString and WcmException access the same maps.
Working with Locale Resources
This section provides guidelines and procedures for working with locale resource strings. Refer to the subsections applicable to your resource string requirements.
- To support client-based locales, see Obtaining the Client Locale and Specifying the Locale.
- To add locale resource strings or modify existing instances in the Toolkit, see Key-Naming Guidelines, Generating Resource Bundles, and Loading Resource Bundles at Runtime.
- To translate resource bundles to other languages, see Translating Resource Bundles.
- To work with user-defined strings in an XLIFF file, see XLIFF Files.
Obtaining the Client Locale
The controller framework does the work of getting the locale from a client request and provides methods for your application to retrieve it. We recommend three approaches based on the following module types: Java, JSP and Servlet, or XSL.
- Java - In UI and data provider modules, you can
obtain the client locale by calling
getClientLocale()
on WcmController. Make the call in theinitialize
method, for example:public void initialize() throws Exception { ... Locale clientLocale = getController().getClientLocale(); }
An alternative for UI and data provider modules is to implement subclasses of the base class, which defines a protected member variable named "locale" that represents the browser/client locale.
For non-module classes, if access to the controller is not available, pass in the Locale object as a parameter.
- JSP and Servlet - For servlets, or JSP pages to
which rendering is delegated, you can obtain the locale by passing the request
to a static method defined on WcmStringResources, as follows:
Locale clientLocale = WcmStringResources.getClientLocale(request);
- XSL - In XSLT-based rendering, you do not have to
explicitly obtain the locale because the superclass of your UI module,
WcmXSLModule, includes an inherited locale member. In the render phase of the
page cycle,
WcmXSLModule.render()
sets an XSL stylesheet parameter to the Locale object. This parameter is called "clientLocale"; you must include it as an XSL parameter in your stylesheet.
Specifying the Locale
You specify the client locale using the following constructors and methods in the WcmString and WcmException utility classes:
- Locale via constructors - Wherever practical, specify the locale in the WcmString or WcmException constructor.
- Locale via WcmString.localize - We recommend the static
WcmString.localize(…)
methods to retrieve locale-specific strings in XSL stylesheets. - Locale via toString - WcmString and WcmException objects
that are declared "
static final
" are shared between all users, and therefore, the objects should not contain locale information. At the rendering phase, pass the locale in thetoString(…)
method to return a locale-specific string, as shown in this code fragment.private static final WcmString wsInstructions = new WcmString ("server.WcmInstructions.instructionsLink", "Instructions"); ... w.write("<a class='wcmInstructionLink' href=\"" + sFullEventURL + "\">" + wsInstructions.toString(locale) + "</a>");
NOTE Due to a GlobalParser restriction,
the variable name for a locale used in constructors and the
WcmString.localize(…)
methods must be named locale.
Key-Naming Guidelines
To avoid duplicate locale keys in your source code, follow these key-naming guidelines for UI strings and exception strings in your source.
Specify your keys with dot ".
" syntax as follows:
groupName.className|fileName.label
where:
-
groupName identifies a logical grouping of keys. You can
create your own group names. You can also maintain these core group names used in the Web Application Toolkit and Workplace modules:
-
global
- a resource string shared by multiple classes. -
toolkit
- a resource string requested by classes in these subpackages: com.filenet.wcm.toolkit.server.* and com.filenet.wcm.toolkit.util. server
- a resource string requested by classes in the com.filenet.wcm.apps.server.* subpackages (FileNet P8 Workplace application).
-
-
className is the name of the class in which the string
request is made.
OR
fileName is the name of the XSL, XML, or JSP file in which the string request is made. Use the pattern filename_ext, with the underscore separating the filename and file extension. For filename, capitalize the first character of each word; make ext lower case. For example:
server.WcmMilestones_jsp.topic
-
label is a descriptive label for the string. The key should
start with lower case; if it consists of multiple words, start the
second and subsequent words with upper case, for example:
server.WcmInstructions.instructionsLink
Generating Resource Bundles
The Toolkit includes ResourceParser, a Java utility that generates the property resource bundles and property list files from all source files that request locale-specific UI and exception strings (Java, JSP, XML, and XSL files). You can generate property resource bundles for a specified source file or for all source files in a specified directory tree. The generated files are in the U.S. English language version.
ResourceParser creates and names the property resource bundles based on the key group name, in this dot syntax format:
groupName.strings.en.US.prb
AND groupName.exceptions.en.US.prb
where:
groupName is a developer-defined key prefix in the source. For
example, if your source requests UI and exception strings with keys
prefixed with "custom
", two of the property resource bundles generated by
ResourceParser would be custom.strings.en.US.prb and
custom.exceptions.en.US.prb.
The property list files generated by ResourceParser are WcmStringConfiguration.en.US and WcmExceptionConfiguration.en.US.
ResourceParser.class is in the tools package and is distributed in <app_root>/WEB-INF/lib/p8toolkit.jar.
To run ResourceParser:
From a command line window, enter the following Java command:
java tools.ResourceParser sourceRoot outputDir
where:
sourceRoot is the name of a single source file to be parsed,
or the top level of a directory tree, for example,
custom/source
. If you specify a directory, all source files
in the tree will be parsed.
outputDir is the location where the property resource bundles and the property list files will be created.
For example:
java -classpath p8toolkit.jar tools.ResourceParser java/src java/classes/com/filenet/wcm/toolkit/util
If there are existing property resource bundles and property list files in the target path, then ResourceParser will update the applicable property resource bundles with any new key / value pairs. If the key group name is new, ResourceParser will create new property resource bundles based on the key group name; it will also add the names of the new resource bundles to the property list files.
NOTE The resource bundles for the FileNet P8 Workplace application exist in the same package as WcmString.class and WcmException.class (com.filenet.wcm.toolkit.util), and are loaded statically (implicitly) at runtime. We recommend that you generate your custom resource bundles to a different package, and load them explicitly as described in Loading Resource Bundles at Runtime.
ResourceParser also generates report files, dupkeys.txt, dupvalues.txt, and allvalues.txt. The dupkeys.txt file identifies duplicated keys, that is, keys to which multiple values are assigned. For example, the following listing identifies a key—"server.DocumentPolicy.NoObject
"—to which two different values are assigned (the difference is the initial case of the word "object").
"server.DocumentPolicy.NoObject" values found: Invalid Object Invalid object
The dupvalues.txt file lists identical values that are assigned to more than one key. These values are potential "global" key strings. For example, the following listing identifies two keys to which the same value — "Move Selected Items Up" — is assigned.
"Move Selected Items Up" keys found: server.WcmMultiValueSelectXSL.MoveSelectedItemsUp server.WorkflowExpressionModuleXSL.MoveSelectedItemsUp
The allvalues.txt file is a comprehensive list of all of the UI and exception strings of the source parsed by ResourceParser.
Loading Resource Bundles at Runtime
If you generate custom resource bundles, you must explicitly load them. You can do this with your own static initializer that loads your custom bundles.
There are different ways to create a static initializer. If you are using the out-of-the-box ConfigurableController, you can subclass it and override the initializeStaticClasses()
method. Alternatively, you can configure the out-of-the-box ConfigurableController with the "staticInitializer" option in p8controller.xml. This option specifies a static initializer class that can supplement or supplant the WcmController.initializeStaticClasses() method.
The following code fragment shows the use of a static initializer class for which ConfigurableController would be configured to call. The bundlePath variable is set to the location of the custom resource bundles, and the getBundle
method returns the custom bundles as ResourceBundle objects. The addXXXBundleToPath
methods load the resource bundles for WcmString.class and for WcmException.class.
public class StaticInit extends ConfigurableController implements StaticInitializerInterface { ... public void initializeStaticClasses(WcmController c) throws Exception { super.initializeStaticClasses(); String localPath = (String)dataStore.getValue(BASE_LOCALPATH_KEY); String bundlePath = localPath + "WEB-INF" + File.separator + "resources"; ResourceBundle bundle = WcmStringResources.getBundle(bundlePath, "CustomStringConfiguration"); WcmStringResources.addStringBundleToPath(bundle); bundle = WcmStringResources.getBundle(bundlePath, "CustomExceptionConfiguration"); WcmStringResources.addExceptionBundleToPath(bundle); } ... }
If WcmStringResources cannot find the specified property list file, then WcmString and WcmException will use the English string in the constructor, for example:
new WcmString("custom.customModule.helpLink", "Help");
Translating Resource Bundles
If you translate property resource bundles:
- Name the resource bundle files to reflect the locale. The default file names are
key.strings.en.US.prb
andkey.exceptions.en.US.prb
, where key is the key type, for example,server
,toolkit
,global
. Change the locale and country codes to reflect the language, for example,server.strings.fr.FR.prb
. - Include a property list file that lists all of the matching and required resource "prb" files for the locale that you are translating to.
- Name the property list file to reflect the locale. Note that its prefix must match
the prefix of the list file that you are translating from. For example, if you are
translating
WcmStringResources.en.US
, the list file must start with "WcmStringResources" followed by the locale suffix (language), and, if desired, the country suffix.
XLIFF Files
XLIFF files (XML Localization Interchange File Format) are introduced in FileNet P8 4.0 to support displaying user-authored names in Workplace and other Toolkit-based applications. This file format is the industry-accepted XML specification standard for the exchange of locale-specific data. XLIFF files augment existing resource bundle files, which contain static strings, as opposed to real-time, user-authored strings.
A user-authored name string is supplied by the user while defining Process Engine (PE) configuration items and workflow definitions. The name strings are saved to the PE database and later used as keys for looking up locale-specific values of the strings in XLIFF files. In Workplace, user-authored names are employed by rosters, queues, milestones, steps, workflows, and various other fields. The name strings are used as keys into the XLIFF files to provide locale-specific string values for:
- Query fields in the Tasks pages.
- Fields in the Workflow Subscription Wizard.
- Fields in the Workflow Policy Wizard.
The PE Configuration Console is used to export the user-authored name strings to a language-specific XLIFF version 1.1 file.
The custom web application developer is responsible for providing the necessary translations for the user-authored name strings in the XLIFF files for the locales to be supported. The XLIFF files containing the locale-specific string values must be placed in the root path when added to the PEAuthoredNames.jar file. This file is deployed by the user to the web application(s), where it is accessed by the PE API or deployed to the client along with the other jar files. In Workplace, the jar file is deployed to the download and WEB-INF\lib directories.
The PEAuthoredNames.jar file can be created as follows:
- Create a staging directory. For example, C:\temp.
- Create the destination directory for the XLIFF files. For example, C:\temp\XLIFF.
- Copy the translated XLIFF files to the destination directory created in Step 2.
- From the staging directory created in Step 1, create the PEAuthoredNames.jar file. For example:
jar -cvf PEAuthoredNames.jar filenet
- Deploy the PEAuthoredNames.jar file to the download and WEB-INF\lib directories.
Workplace exposes the “Preferred Locale” user preference and passes the browser locale to the web application using WcmPlugInModule. At run-time, the application retrieves the browser locale and calls the setLocale() method on the VWSession object (Tasks pages and Step Processors). This causes the corresponding XLIFF file to be loaded (if it has not already been loaded). As the application retrieves information from the PE API objects, the locale-specific (translated) strings are retrieved from the XLIFF files using the user-authored name strings as keys. If a locale-specific string is not available, the user-authored name string is returned.
Feedback