13.07.2015 Views

DB Resource Bundles Sample.pdf - developerWorks Lotus

DB Resource Bundles Sample.pdf - developerWorks Lotus

DB Resource Bundles Sample.pdf - developerWorks Lotus

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Utilizing Database <strong>Resource</strong> <strong>Bundles</strong> with IBMWebSphere Portlet Factory7/8/2009© Copyright International Business Machines Corporation 2009. All rights reserved.This article and accompanying sample demonstrates how to use IBM WebSpherePortlet Factory Version 6.1.2 and later (hereafter called Portlet Factory) to localizeportlets using content from a database or some other back-end server. It is intended fordevelopers writing portlets that must support multiple languages where languagetranslations are not stored as traditional file-based resource bundles.This article is one in a collection of articles and samples that illustrate techniques fordeveloping with Portlet Factory. See the Portlet Factory Wiki for a complete list. Foran introduction to developing with Portlet Factory, you should complete the introductorytutorials that are available both in the product help and on the Learning Roadmap.Prerequisites1. You must have a basic familiarity with Portlet Factory and be able to createprojects and run Portlet Factory models.2. You will need to define a J<strong>DB</strong>C data source in your application server and havethat data source be visible to your deployed Portlet Factory project.3. You should be familiar with the techniques for localizing Portlet Factory modelsusing traditional file-based resource bundles. A sample illustrating file-basedresource bundle localization is available on the Portlet Factory Wiki under the titleLocalizing Portlets with IBM WebSphere Portlet Factory.Portlet LocalizationPortlets that serve an international audience need to be translated into different languages.J2EE applications support translation by automatically substituting pre-translated stringsinto web pages returned to a user. These strings are taken from files selected by takinginto account the user’s preferred locale. This technique is known as “localization” usingresource bundles and is most useful when translating UI components such as labels, menuchoices, and list choices. Static text for short instructions or explanations is alsolocalized in this way.Another technique is to create translations of entire HTML or JSP files. This techniqueworks best when there is too much content for the previous technique to be practical. Aportlet’s Help page is a good example as it may contain several paragraphs of instructionsand other information. In these cases, the strings are simply too long to use file-basedresource bundles.


Implementing LocalizationThe Localized <strong>Resource</strong> builder is used to import translated strings into a model. Thebuilder references a resource bundle from the project and uses that bundle to populate avariable named LocaleData. This variable is an XML representation of the localizationcontent contained in the bundle. Other builders in the model that rely upon translatedcontent from the bundle get their strings through the LocaleData variable.<strong>Resource</strong> bundles are either text files with a .properties extension or Java classes.These files are typically found in the WEB-INF\work\source folder in a Portlet Factoryproject. This sample illustrates how to use a Java-based resource bundle with theLocalized <strong>Resource</strong> builder.All resource bundles are required to present their content as key-value pairs; the keys areused to logically represent the language-specific translations provided by the values.WebSphere Portlet Factory has several mechanisms for associating theses bundle keyswith UI strings in a portlet.Applying Localization Using High-Level BuildersPage automation builders such as Data Page and View & Form can automatically utilizetranslated strings imported by a Localized <strong>Resource</strong> builder. These page automationbuilders apply the translated strings in the LocaleData variable to one or more pages inthe model. For every page element whose name matches an element in LocaleData, thetranslated value for that resource key will be substituted.View & Form has an input labeled <strong>Resource</strong> Bundle Name. This input refers to theresource bundle providing the keys and translated values for the named elements in theschema used by the builder. For example, if the View & Form builder presents rows ofdata returned by a service call, and the field names in the data match the key names in theresource bundle, then View & Form will perform the necessary locale-based stringsubstitutions to translate field labels and column headings. The critical element is that thekey names from the resource bundle match the schema element names View & Form usesto present the data.<strong>Sample</strong> DescriptionThere are two models in this sample: Setup and ViewOrders. Setup is used to configurethe sample so that ViewOrders can run correctly and load bundle content from a databasetable via the Java-based resource bundle also provided as part of this sample.<strong>Resource</strong> <strong>Bundles</strong>There are two resource bundles in this sample; one is a traditional file-based bundlenamed design_time_bundle.properties and the other is a Java-based bundle namedDb<strong>Resource</strong>Bundle.java. The file-based bundle contains default English translationsthat will be used during server regen to localize labels in ViewOrders when appropriatebundle content cannot be loaded from the database by Db<strong>Resource</strong>Bundle.java. Thisdefault bundle is also used by Db<strong>Resource</strong>Bundle.java during Designer regen so thatViewOrders does not require access to the database from Designer.


Localization ProcessWhen ViewOrders regen occurs in Designer the Localized <strong>Resource</strong> builder in thatmodel is called upon to create and populate the LocaleData variable. The Localized<strong>Resource</strong> builder first creates an instance of Db<strong>Resource</strong>Bundle.java and then it callsseveral standard methods on the instance to obtain the key-value pairs used to populateLocaleData. Db<strong>Resource</strong>Bundle.java detects that regen is occurring in Designer and ituses design_time_bundle.properties as the bundle content.When ViewOrders regen occurs on the server the Localized <strong>Resource</strong> builder behaves inthe same way; it creates an instance of Db<strong>Resource</strong>Bundle.java and calls the samestandard methods to obtain bundle content. However, Db<strong>Resource</strong>Bundle.java detectsthat regen is occurring on the server and it attempts to connect to the database and loadbundle content appropriate for the user’s preferred locale. If appropriate content is found,then this content is cached and returned to the Localized <strong>Resource</strong> builder. OtherwiseDb<strong>Resource</strong>Bundle.java falls back to using design_time_bundle.properties as thebundle content.Overview of Db<strong>Resource</strong>Bundle.javaWhen using Java-based bundles you typically implement one class per supported locale(Db<strong>Resource</strong>Bundle_fr.java for French, Db<strong>Resource</strong>Bundle_es.java for Spanish,etc.). In this sample however, Db<strong>Resource</strong>Bundle.java is used to represent allsupported locales; it takes care of managing the various locales that the Localized<strong>Resource</strong> builder is called upon to support at regen.The Localized <strong>Resource</strong> builder in ViewOrders was profiled so that a user’s preferredlocale is provided to the builder at regen. After the Localized <strong>Resource</strong> builder creates aninstance of Db<strong>Resource</strong>Bundle.java it relays the user’s preferred locale to the instanceby calling setLocale. This locale is then used by the instance when the Localized<strong>Resource</strong> builder calls the getKeys and handleGetObject methods to fetch bundlecontent.The method named getBundleForServer is used to fetch and cache bundle content (orfall back to using design_time_bundle.properties if there is no content appropriatefor the user’s preferred locale). loadBundleFromDatabase provides the low-level J<strong>DB</strong>Cimplementation where the user’s preferred locale is applied to the WHERE clause of theSELECT statement that retrieves bundle content from the database.<strong>Sample</strong> FilesThe following table describes the various files included as part of this sample. When youimport the Portlet Factory archive into your project these files will be installed at thenoted paths. You should feel free to open these files in Designer and review their contentto familiarize yourself with how Db<strong>Resource</strong>Bundle.java is used by ViewOrders.


Table 1. Package contentsFile name and locationWEB-INF/models/samples/db_resource_bundles/Setup.modelWEB-INF/models/samples/db_resource_bundles/ViewOrders.modelWEB-INF/config/override.propertiesWEB-INF/work/source/com/ibm/samples/db_resource_bundles/Db<strong>Resource</strong>Bundle.javaWEB-INF/work/source/com/ibm/samples/db_resource_bundles/SetupUtility.javaWEB-INF/work/source/com/ibm/samples/db_resource_bundles/design_time_bundle.propertiesDescriptionModel used to create and populatethe database table used by thesample.Model used to demonstratelocalization using a Java-basedresource bundle.Properties file used to specify thedata source name to be used by theJava-based resource bundle.Java-based resource bundle thatdemonstrates pulling bundle contentfrom a database.LJO used by the Setup model tosupport configuration of the sample.The default resource bundle contentused by the Java-based resourcebundle if the database does notcontain content for the user’spreferred locale.Instructions for Configuring the <strong>Sample</strong>1. Create a J<strong>DB</strong>C data source:a. Use the administration feature of the target application server to define adata source for the database where the sample will store bundle content. Ifyou are using the version of WebSphere Community Edition (WASCE)that ships with Portlet Factory, then a sample Cloudscape database andJ<strong>DB</strong>C data source are already defined and may be used by the sample.2. Create a Portlet Factory project:a. If using WASCE: Create the project, but do not deploy a developmentWAR. Edit the deployment descriptors to make the selected data sourcevisible to the project when it’s deployed. Then deploy a developmentWAR for the project.b. If using WebSphere, then create the project and deploy a developmentWAR.3. Download the Portlet Factory archive containing the sample files and import itinto a project using the File > Import > WebSphere Portlet FactoryArchive command.4. Configure the Setup model to use the selected data source:a. Open the model named WEB-INF/models/samples/db_resource_bundles/Setup.model.b. Open the SQL DataSource builder named ds.c. Click the Fetch DataSource Names button.


d. Select the data source name you defined in step 1 and apply the changes.If you do not see the data source listed, then the deployed developmentWAR cannot see the data source created in step 1 and you should checkthe deployment descriptors to ensure they are correct.5. Configure the ViewOrders model to use the selected data source:a. Open the file named WEB-INF/config/override.properties and set theproperty name ibm.samples.db_resource_bundles.dataSourceNameto the name of the selected data source.b. Save and close override.properties.6. Redeploy a development WAR to ensure the updated version ofoverride.properties is picked up by the application server.7. Create and populate the sample database table:a. Run the Setup model. You will see a page such as the one in figure 1.b. Click the Create Table button to create and populate the requireddatabase table. You will now see a page such as the one in figure 2.Instructions for Running the ViewOrders1. Configure your browser to have a French preferred locale. Assuming InternetExplorer:a. From the Tools menu, choose Tools > Internet Optionsb. Click the Languages… button.c. In the Language Preference dialog box, click Add…d. Select French(France)[fr] and click OK.e. Use the Move Up button to put French at the top of the list. Click OK thenclick OK again to save these changes.2. Close the browser so that the next time it is used, French will be the preferredlanguage.3. Open the model named WEB-INF/models/samples/ db_resource_bundles/ViewOrders.model.4. Run the ViewOrders model. You will see a page such as the one in figure 3. Ifyou do not see the table columns in French, then the Java-based resource bundlewas not able to pull the French translations from the sample database table.5. Configure your browser to have an English preferred locale.6. Run the ViewOrders model again. You will see a page such as the one in figure 4where the table columns are in English.


Figure 1. This screen capture shows Setup run for the first time.


Figure 2. This screen capture shows Setup after creating the sample table.


Figure 3. This screen capture shows ViewOrders in French


Figure 4. This screen capture shows ViewOrders in EnglishAdditional Considerations1. The database table used by the sample is not normalized and therefore is notintended to be used for production deployments. If you decide to use this sampleas the basis for a production deployment, then you should create a normalizedversion of the table and appropriate indices and constraints to ensure data integrityand optimal runtime performance.2. The sample assumes that a single Localized <strong>Resource</strong> builder and implementationof Db<strong>Resource</strong>Bundle.java is sufficient to load all translated content required bya model. If you need to split translated content over multiple Localized <strong>Resource</strong>builders, then you must modify the Db<strong>Resource</strong>Bundle.java implementation tosupport being the target of multiple Localized <strong>Resource</strong> builders where eachbuilder has a unique default file-based resource bundle.3. One benefit of storing resource bundle content in a back-end system is the abilityto dynamically update the content and have those updates automatically apply tonew sessions without the need to update and redeploy the portlet WAR. Thesample Db<strong>Resource</strong>Bundle.java implementation does not detect databaseupdates, but this capability could be added by having the bundle cache expire


entries for locales. This would then allow Db<strong>Resource</strong>Bundle.java to reload thecontent for an expired locale and thereby discover the updated translations fornew sessions.Final NotesDb<strong>Resource</strong>Bundle.java has been instrumented with server statistics to track thedatabase operations performed by the class. These statistics can be a valuable resource indetermining whether the sample is behaving as you expect. The statistics are written toWEB-INF/logs/serverStats.txt in the deployed WAR and they all begin withDb<strong>Resource</strong>Bundle. For example, the following statistics show that the en_US localewas successfully loaded from the database in response to a server regen of theViewOrders model.Db<strong>Resource</strong>Bundle: 12 Latency: 2Db<strong>Resource</strong>Bundle/HandleGetObject: 9Db<strong>Resource</strong>Bundle/HandleGetObject/en_US: 9Db<strong>Resource</strong>Bundle/Create: 1 Latency: 15Db<strong>Resource</strong>Bundle/LoadBundleFromDatabase: 1Db<strong>Resource</strong>Bundle/LoadBundleFromDatabase/en_US: 1Db<strong>Resource</strong>Bundle/GetKeys: 1 Latency: 16Db<strong>Resource</strong>Bundle/GetKeys/en_US: 1 Latency: 16Db<strong>Resource</strong>Bundle.java will also log errors if it cannot load content from the database.The following error messages will be written to WEB-INF/logs/event.log in thedeployed WAR.Database provided no bundle content for locale en.to default resource bundle.Falling backError while retrieving bundle content for locale en.back to default resource bundle.FallingThe first message indicates that the SELECT statement returned no rows for the providedlocale while the second message indicates that the SELECT statement resulted in anexception. The exception trace will be included as part of the logged message.<strong>Resource</strong>sWebSphere Portlet Factory product documentationhttp://www.ibm.com/developerworks/websphere/zones/portal/portletfactory/proddoc.htmlWebSphere Portlet Factory supporthttp://www.ibm.com/software/genservers/portletfactory/support/<strong>developerWorks</strong> forumshttp://www.ibm.com/developerworks/forums/wsdd_forums.jsp


Trademarks <strong>DB</strong>2, IBM, <strong>Lotus</strong>, Tivoli, Rational, and WebSphere are trademarks or registeredtrademarks of IBM Corporation in the United States, other countries, or both. Windows and Windows NT are registered trademarks of Microsoft Corporation in theUnited States, other countries, or both. Java and all Java-based trademarks and logos are trademarks or registered trademarksof Sun Microsystems, Inc. in the United States, other countries, or both. Other company, product, and service names may be trademarks or service marks ofothers.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!