Editor: Erik van der Poel
Last Modified: Nov. 20, 1997
This document was written for the Xena (Navigator in Java) project. It is provided here for historical interest, it does not represent the current thinking for Mozilla.org.
Introduction
A locale is a specific geographical, political or cultural region. Today's operating systems allow the user to set the locale either in a coarse-grained manner (e.g. Japan, or French-speaking portion of Switzerland), or in a fine-grained manner (e.g. personal customization of date/time format). See, for example, the Windows Regional Settings control panel. Applications use these settings when presenting data to the user or when performing locale-sensitive operations. For example, menu/dialog text, date/time format, numeric format, currency format, and sorting order.Non-Global Locales
The ANSI C locale model is widely believed to be inadequate due to its global nature. When the locale is set, it affects all subsequent locale-sensitive C library calls.Java (JDK 1.1) takes a step in the right direction with its Locale class and set of locale-sensitive classes. An object can store its own Locale and carry out locale-sensitive operations using that Locale.
It is also important to distinguish between user locale settings, the locale (or language) of data, and locale settings set by applications. The user locale settings are per-user settings set in preference dialogs (similar to the Windows control panel). Personalized user locale settings also allow the user to use a locale other than that of the particular localized OS hosting the application. Data can also have an associated locale (e.g. text with language tags in HTML). Finally, applications can use their own locale settings (for example, to display a temperature in both Fahrenheit and Celsius at the same time).
JDK Locale Class
The JDK Locale class has several issues:- No personal preferences. The JDK Locale object only stores a language name and country name. These are standard ISO names, used to look up locale tables in e.g. the date formatter. We cannot support customizations using simple language and country names.
- Locale.getDefault() is bad. This method returns the locale of the VM, which in turn is based on the locale of the host OS. Since we want to implement the Location Independence feature (see below), we cannot use Locale.getDefault().
Location Independence
The client's Location Independence feature allows users to "log in" from any remote location. The user profile is stored on an LDAP server. This means that locale preferences should also be stored in LDAP.Offline
The client's Offline feature allows users to use the client without being connected to the network. In this case, the locale preferences cannot be retrieved from the LDAP server; the preferences must be stored in a local file.Locale Model
Several locales can be distinguished in the context of our products:- client locale: client user's locale
- client OS locale: locale of OS where client is running
- data locale: locale of data (content), e.g. HTML, plain text file
- embedded object locale: locale of embedded object such as applet, plug-in
- server admin locale: server administrator's locale
- server OS locale: locale of OS where server is running
Similarly, an applet embedded in a German HTML document can use the German locale if the HTML document passes the locale as a parameter.
Now, there may be situations where objects want to use a locale other than the inherited locale. For example, an applet may want to spawn an entirely new top-level window, in the locale of the user. We will need to come up with an interface to obtain this locale.
Code that runs on the server on behalf of the client user must use the locale of the user, which can be passed to the server through e.g. the HTTP Accept-Language header.
The Plan
We already have a prototype that implements the following:- Locale preferences object
- Collation
- Number, currency, percent format
- Date, time format
- String resources
-
Review and improve existing code
- Write our own I* interfaces for e.g. date/time format to insulate ourselves from JDK
- Move collation and other non-customizable locale-sensitive operations out of LocalePreferences object, to be replaced by methods to query the Locale for those operations
-
Add more locale-sensitive operations
- toUpperCase, toLowerCase
- BreakIterator
- MessageFormat
- Calendar
-
Location independence: investigation, design, implementation
- Review current hash table initializer for LocalePreferences object, and replace with appropriate stuff for location independence
- Offline: investigation, design, implementation
Appendix A: JDK Classes that use Locale
- java.applet.Applet: getLocale
- java.awt.Component: getLocale, setLocale (JDK 1.2)
- java.awt.Font: getFamily, getFontName (JDK 1.2)
- java.awt.Window: getLocale (JDK 1.2)
- java.awt.im.InputContext: selectInputMethod (JDK 1.2)
- java.beans.beancontext.BeanContextSupport: BeanContextSupport, setLocale, getLocale, fireVetoLocaleChange, fireLocaleChanged (JDK 1.2)
- java.lang.String: toLowerCase, toUpperCase
- java.text.BreakIterator: getWordInstance, getLineInstance, getCharacterInstance, getSentenceInstance, getAvailableLocales
- java.text.Collator: getInstance, getAvailableLocales
- java.text.DateFormat: getTimeInstance, getDateInstance, getDateTimeInstance, getAvailableLocales
- java.text.DateFormatSymbols: DateFormatSymbols
- java.text.DecimalFormat: DecimalFormat
- java.text.DecimalFormatSymbols: DecimalFormatSymbols
- java.text.MessageFormat: setLocale, getLocale, getIntegerFormat
- java.text.NumberFormat: getInstance, getNumberInstance, getCurrencyInstance, getPercentInstance, getAvailableLocales
- java.text.SimpleDateFormat: SimpleDateFormat
- java.text.resources.LocaleData: getAvailableLocales
- java.util.Calendar: Calendar, getInstance, getAvailableLocales
- java.util.Date: toLocaleString, toString, toGMTString
- java.util.GregorianCalendar: GregorianCalendar
- java.util.Locale
- java.util.ResourceBundle: getBundle
- sun.applet.AppletCopyright: load (JDK 1.2)
- sun.awt.im.InputContext: selectInputMethod (JDK 1.2)
- sun.awt.im.InputMethod: setLocale (JDK 1.2)
Appendix B: Locale-Sensitive Operations
- date/time format
- time zone(?)
- calendar
- number format
- currency format
- collation (sorting)
- character, word, line and sentence breaking
- converting to lower or upper case
- locale of UI (e.g. text in error messages, menus, dialogs, buttons, etc; images; audio; video; etc)
- keyboard layout
- paper size (letter vs A4)
- measurement (US vs metric)
- list separator (",")
- telephone (international access, country code, area code, outside line access, etc)
Appendix C: Future Considerations
- Dynamic language switching. Some applications require the ability to change locale settings dynamically. This means that we will need some kind of notification or event mechanism which alerts all objects that wish to be alerted. For example, some kiosk applications may require dynamic language switching. When one user finishes using the kiosk, and another user walks up to it, the language may need to be changed.
- Personal customization of locale-related preferences. For example, customization of date/time format a la Windows control panel.
- Clients and servers might not have the same sets of locales. If you're using IIOP, say, and you pass a JDK Locale object from the client to the server, there is no guarantee that the server will have the code and data needed to honor the language and country codes in the Locale object.
- Locale Preferences: Our Platform vs Underlying Platform. We should use underlying platform's locale preferences (e.g. Windows control panel) as defaults?