Flylib.com

Books Software

 
 
 

Internationalizing Tiles Applications


Internationalizing Tiles Applications

In Chapter 7 you saw how to use Tiles to organize your JSP pages. The Tiles framework provides an easy way to add tiles or templates to a JSP page to present content in a dynamic fashion. The Tiles framework, just like Struts can be localized to provide different tiles based on a user ‚ s preferred locale. For example, the header tile in Chapter 7 could be replaced with a different header that corresponds to a specific locale. It could contain an area-specific flag for instance or simply a different background color .

A Tiles application has a Tiles definition file (e.g.: /WEB-INF/tiles-defs.xml ) that defines the structure of a JSP page using various tiles, for the header, menu, body, footer etc. In the case of a localized Tiles application, there will one such file per locale along with the default tiles-defs.xml file. For example, if your application supports US English and French, there will be two definition files, one for each locale as well as a default one ‚ tiles-defs_fr.xml , tiles-defs_en.xml and tiles-defs.xml

The naming conventions for the Tiles definition files are the same as for a java.util.ResourceBundle class as explained earlier in the chapter. Again, just as in a localized Struts application, the session attribute Action.LOCALE_KEY is looked up for a user ‚ s preferred or default locale and the appropriate definition file are loaded. For instance, if the default file tiles-defs.xml is:

<tiles-definitions>
  <definition name="foo.bar" path="MybankLayout.jsp">
      <put name="title"  value="My Bank example" />
      <put name="header" value="/header.jsp" />
      <put name="menu"   value="/menu.jsp" />
      <put name="footer" value="/footer.jsp" />
      <put name="body"   value="/body.jsp" />
  </definition>
</tiles-definitions>

Then the localized Tiles definition file for French is:

<tiles-definitions>
  <definition name="foo.bar" path="MybankLayout.jsp">
      <put name="title"  value="Mon exemple de ma banque"/>
      <put name="header" value="/header.jsp" />
      <put name="menu"   value="/menu.jsp" />
      <put name="footer" value="/footer.jsp" />
      <put name="body"   value="/body.jsp" />
  </definition>
</tiles-definitions>

This approach is justified if you use different JSPs per locale. However if the JSPs themselves are fully I18N capable, meaning the single JSP can adapt itself to render local sensitive UI, then the only difference between the two tiles definition for the two locales, is the title. The need for different definition files in that case could be eliminated if there was a mechanism to specify the key to the message resource bundle in the < put > element above. Unfortunately such a mechanism doesn ‚ t seem to exist at the time of writing and hence you are left with creating definitions for each locale.



Processing Localized Input

Localized input is data input in a native language using locale specific formats. How does your back-end Java code process data input in a native language? Let us consider a simple form with two fields, fullName and monthlySalary as shown below.

public class CustomerForm extends ActionForm {
    private String fullName = null;
    private double monthlySalary = 0.0;
...
}

John Doe enters his monthly salary as 5431.52 and submits the form. That ‚ s it, the form fields are populated nicely and the application works without a hitch. The conversion of the monthly salary from a String to a double is automatically taken care of by Struts and John Doe won ‚ t have any problems with the application.

What happens if the same application is viewed by a user in France and he decides to enter the same amount in the French format as 5 431,52? When the French user submits the application, the monthlySalary attribute in CustomerForm ends up being populated with 0.0 instead of 5431.52. Why so? When the form is submitted, the RequestProcessor populates the JavaBeans properties of the ActionForm with the request parameters by using the RequestUtils and BeanUtils classes. The actual population is done by the BeanUtils.populate() method. That method tries to parse the String ‚“5 431,52 ‚½ and assign it to monthlySalary ‚ a double field without caring much for the Locale of the user. This obviously throws an exception on which the default action is to set 0.0 in the monthlySalary field.

What is the solution then? How can you make the Struts applications process localized input? Since the BeanUtils class does not check the locale at the time of populating the form, the only way out of this situation is to make the monthlySalary field a String instead of a double . Now, the BeanUtils does not try to parse a double from the String. Instead the value is assigned AS IS. A customized routine has to be written to convert the String into a double in a Locale dependent manner.