ICU Accept Language API Proposal
"Steven R. Loomis" <[email protected]> Fri, 8 Oct 2004 18:35:52 -0700
| Newsgroups | gmane.comp.lib.icu.general |
|---|---|
| Message-ID | <[email protected]> |
Jitterbug #3591 [
http://www.jtcsv.com/cgibin/icu-bugs/others?id=3591 ]
Date: 8 October 2004
Expires: 13 October 2004
------------------------
Motivation / Background:
These APIs provide a function to negotiate the best locale to use for
an operation, given a user's list of acceptable locales, and the
application's list of available locales.
One of the intended uses of this API is with the HTTP Accept-Language:
field, see:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
Here is another article which describes some of the cautions about
using accept-language:
http://www.w3.org/International/questions/qa-accept-lang-locales
------------------------
Theory of operation:
Two input lists are passed to the function:
1. The "Accept List" is from the user/client preference, for example,
from the HTTP request header. It is ordered in decreasing order of
preference.
2. The "Available List" is from the application, for example, from the
list of installed locales. It is not ordered.
In the best-case situation, the earliest (preferred) locale from the
Accept list is matched to an exact match in the available list. In this
situation, a 'Valid' locale is returned.
Before failing completely, the ICU API will attempt a fallback from
the Accept list. Note that this differs from the HTTP specification,
and is noted appropriately in the return values of the API as a
'Fallback'.
To illustrate the fallback behavior, consider the following examples.
An input accept list of "de_LX, ja" behaves like "de_LX, ja, (de)",
with "de" being fallback behavior, only if the other two locales were
not found. Similarly, an input accept list of "de_LX_FOO, de_CH_BAR,
ja_JP" behaves like "de_LX_FOO, de_CH_BAR, ja_JP, (de_LX, de_CH, de,
ja)". The Fallback locales are considered in descending order of
length, following the requested locales.
The HTTP specification says that de_LX should not match de. As well,
HTTP spec says that 'de' in the accept-list should match 'de_LX'.
However, we assume that application and ICU locale bundles are
well-formed, so that if there is a 'de_LX' there will be 'de' and we
will match it. Therefore, we will not match an accept-locale of 'de'
to an available locale of 'de_LX'.
Two versions of the API are provided for C and Java. One is passed
the Accept-Language field from HTTP (as a single string), and the other
an array of Locales. Note that the numeric weights of the
Accept-Language are only used to order the accept list items, their
values are otherwise unimportant.
C
-
typedef enum {
ULOC_ACCEPT_VALID = 0, /* An exact match was found. */
ULOC_ACCEPT_FALLBACK = 1 /* A fallback was found, for
example, Accept list contained 'ja_JP'
which matched available locale 'ja'. */
} UAcceptResult;
/**
* @param httpAcceptLanguage - "Accept-Language:" header as per HTTP.
* @param availableLocales - owned by caller.
* @returns installed locale, or NULL on error. Note, result is valid
only
* until availableLocales enumeration is destroyed. (result is owned by
the
* UEnumeration.)
*/
const char*
uloc_acceptLanguageFromHTTP(const char *httpAcceptLanguage,
UEnumeration* availableLocales,
UAcceptResult *outResult,
UErrorCode *status);
const char*
uloc_acceptLanguage(const char *acceptList[],
UEnumeration* availableLocales,
UAcceptResult *outResult,
UErrorCode *status);
JAVA
----
static public final int ACCEPT_VALID = 0; /* An exact match
was found. */
static public final int ACCEPT_FALLBACK = 1 /* A fallback
was found, for example, Accept list contained 'ja_JP' which matched
available locale 'ja'. */
/**
* @param httpAcceptLanguage - "Accept-Language:" header as per HTTP.
* @param availableLocales - owned by caller.
* @returns an installed locale (from the availableLocales list)
*/
static
ULocale ULocale.acceptLanguageFromHTTP(String httpAcceptLanguage,
StringEnumeration availableLocales,
int outResult[]);
static
ULocale ULocale.acceptLanguage(ULocale acceptArray[],
StringEnumeration availableLocales,
int outResult[]);