Omaha Java Users Group Java Internationalization Presented by Jason Shepherd 16-May-2005 6:30 PM.
-
Upload
martin-fletcher -
Category
Documents
-
view
221 -
download
0
Transcript of Omaha Java Users Group Java Internationalization Presented by Jason Shepherd 16-May-2005 6:30 PM.
Omaha Java Users GroupJava Internationalization
Presented by Jason Shepherd16-May-20056:30 PM
Outline
Concepts and terminologyInternationalization in J2SEInternationalization in J2EE (JSTL,
Struts)Internationalization in XSLTThe Process of Internationalization
(Project Plan)
Terms
Internationalization process of creating an application so it
can be adapted to different languages and countries without coding changes
also known as “i18n” (since there are 18 characters between the i and n in Unicode)
Terms (cont)
Characteristics of an i18n application By adding localized text, the app can
display information in any language/country
Textual elements are not hard-coded; they are stored externally and retrieved at run-time
Terms (cont)
Characteristics of an i18n application (cont) Support for new languages/countries
does not require re-compilation Culturally dependent data (dates,
currencies, etc.) conforms to user’s language/country
Can be localized quickly
Terms (cont)
Localization process of adapting software for a
specific language/country by adding locale-specific components and text translations
sometimes abbreviated as l10n (10 letters between L and N in Unicode)
Terms (cont)
Localizing an application text translation is the most time-consuming
phase of l10n (the human element) sounds and images may need localized if they
are culturally sensitive (red is “purity” in India, but “danger” in the U.S… likewise the icon of a mailbox isn’t familiar outside the U.S., and instead a mail envelope icon should be used)
formatting of numbers, dates, and currencies may impact the UI layout strategy
Terms (cont)
Object central to l10n is the user’s locale
Locale political, cultural, and region-specific
elements (in Java, expressed as a language code and country code)
Terms
Locale (cont) has the form xx_YY xx is two-character language code (ISO-
639) YY is two-character country code (ISO-3166) Examples:
en_US - United States Englishen_GB - Great Britain Englishes_MX - Mexico Spanish (Espanol)
java.util.Locale
Locale enUSLocale = new Locale(“en”, “US”);Locale frCALocale = new Locale(“fr”, “CA”);Locale locale = Locale.US;
Locale.getDefault().toString()// “en_US”locale.getLanguage() // “en”locale.getCountry() // “US”locale.getDisplayName() // “English (United States)”locale.getDisplayLanguage()// “English”
Locale.setDefault( Locale.FRANCE );locale.getDisplayName() // “anglais (Etats-Unis)”
* Display names are shown according to the default locale
Internationalization in J2SE
Create properties files externalized locale-specific UI messages
Create the localeCreate a resource bundle (using the
locale)Retrieve UI messages from the
resource bundle
J2SE
Creating properties files Plain text file Will reside in classpath One file for each locale (filename
convention) When paired with a locale, the closest
matching file will be selectedMessagesBundle.propertiesMessagesBundle_en.propertiesMessagesBundle_en_US.propertiesMessagesBundle_fr_FR.properties
default
J2SE
Creating properties files (cont)
greetings = Hello.farewell = Goodbye.inquiry = How are you?
greetings = Bonjour.farewell = Au revoir.inquiry = Comment allez-vous?
MessagesBundle_en_US.properties
MessagesBundle_fr_FR.properties
J2SE
Create the locale and resource bundle
Retrieve UI messages from the resource bundle
Locale currentLocale = new Locale("fr", “FR", "UNIX");
ResourceBundle messages = ResourceBundle.getBundle(“MessagesBundle", currentLocale);
System.out.println( messages.getString(“greetings”) );
Eclipse is Almost Helpful
The “Externalize Strings” option gets you part-way to i18n
DEMO!!
J2SE Side Notes
Properties files and resource bundle keys should follow human-readable naming conventions (not “key1”, “key2”, etc.)
Some UI generation engines for thick clients (e.g. SwiXML) have support for i18n; something to consider if you’re creating a Swing app
Internationalization in J2EE
Locale stored in HTTP sessionResource bundles stored in properties
files; told to load in web.xmlLocale-specific messages accessed in the
Web tier (generally) using tag librariesJSTL versus Struts tag librariesWe’ll refer to Struts for the remainder of
the presentation
J2EE (w/ Struts)
Ensure your properties files are visible on the classpath special attention must be paid if using
Ant or Maven to build your application must be placed somewhere that all
classes will be able to find it (e.g. a “library” jar file or possibly in the WAR file under WEB-INF/classes)
J2EE (w/ Struts)
Configure web.xml to load the properties files
<!-- Web App Framework Action Servlet Configuration --><servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>application</param-name> <param-value>MessagesBundle</param-value> </init-param> <init-param> <param-name>locale</param-name> <param-value>true</param-value> </init-param>
J2EE (w/ Struts)
Accessing the resource bundles in a JSPFirst, include the Struts “bean” tag
library <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"
%>
Then, replace any hard-coded messages <b>Hello</b> <b><bean:message key=“hello.message” /></b>
J2EE (w/ Struts)
Accessing outside of a JSP e.g. back-end translation code (locale
passed through to data tier) e.g. JavaScript messages At UPRR, we wrote a utility class to load
the properties files and retrieve messagesLocale locale = (Locale)
session.getAttribute(org.apache.struts.action.Action.LOCALE_KEY);
String message = ResourceBundleUtil.getMessage( locale, “hello.message”);
* this class comes in handy later on in the presentation… stay tuned!
J2EE Apps: The Database Dilemma
Translating values that come out of a database
If DB is not shared between applications, localized strings can be stored in the DB DB must be Unicode-enabled and have plenty
of extra disk spaceIf localized messages cannot be stored in
the DB, keys can be stored in the DB that refer to values in the properties files
Storing localized text in the database: Pros
Truly dynamic localizationOne table for supported localesOther tables for translationCan correct translation errors on-the-
fly Good when translation error looks
silly/unprofessional, or worse yet, offensive
Storing localized text in the database: Cons
Requires more database accesses Very bad for high volume sites where
database connections must be managed carefully
Might require complex joins in a well-normalized DB schema
Could be considered bad design to store presentation tier artifacts in the data tier??
J2EE Side Notes
Properties files for Struts can be HTML escape encoded (á) or Unicode encoded (\u0000)… Struts is encoding-aware
The content type in your resulting HTML page must be set correctly
Internationalization in XSLT
Some J2EE applications deliver their data to the Web tier as XML and then render the UI using XSLT (or a combination of JSP and XSLT)
No way in XSLT to natively access your properties files
XSLT
Different approaches to i18n in this case: Option 1: Not try to use properties files; instead,
make a separate XSLT stylesheet for each locale (yuck! Must be maintained and manually synchronized with the properties files)
Option 2: Write code to insert the locale into the stylesheet as an XSL variable. Then use Java from within your stylesheet to extract the resource bundle messages (Xalan-Java extensions)
XSLT
XSLT stylesheets can be localized the same way JSPs are.
But, XSLT stylesheets don't have access to the Java HTTP session object that stores the user’s locale information
The locale must be inserted into the XSLT and passed to the Xalan-Java objects
XSLT: An i18n (not l10n yet) Stylesheet
<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:inl="http://www.insightnl.com"xmlns:message="http://xml.apache.org/xalan/java/com.uprr.app.inl.util.ResourceBundleUtil" version="0.1"> <!-- $locale gets inserted here --> <xsl:template match="/"> <!-- Do some fancy HTML --> <xsl:value-of select="message:getMessage($locale,’hello.message’)"/> <!-- Do some more fancy HTML --></xsl:template></xsl:stylesheet>
XSLT: Retrieving the Stylesheet and Inserting the Locale
* Note: we store our XSLT in the DB
XSLT: Retrieving the Stylesheet and Inserting the Locale
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"indent="yes"/>
<xsl:template match="xsl:stylesheet"><xsl:element name="xsl:stylesheet">
<xsl:element name="xsl:variable"><xsl:attribute
name="name">locale</xsl:attribute><xsl:text>en_US</xsl:text>
</xsl:element><xsl:apply-templates/>
</xsl:element></xsl:template>
<xsl:template match="*|@*|text()"><xsl:copy>
<xsl:apply-templates select="*|@*|text()"/></xsl:copy>
</xsl:template></xsl:stylesheet>
i18nXSLT
locale insertXSLT
l10nXSLT
The Process of i18n
i18n (create properties files and remove hard-coded values)
Send translations to translatorsReceive translations and perform
l10nDeploy and have customers
acceptance test
Recap
Terms: i18n, l10n, localeJ2SE support for i18nJ2EE support for i18nHow internationalizing a J2EE can
impact XSLT-based front-endsThe Process
Questions?
Questions, comments, taunts, or exclamations?
I’ll give you an exclamation:
Flippin’ sweet!