001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.tomcat.util.http;
018:
019: import java.util.Enumeration;
020: import java.util.Hashtable;
021: import java.util.Locale;
022: import java.util.StringTokenizer;
023: import java.util.Vector;
024:
025: /**
026: * Util to process the "Accept-Language" header. Used by facade to implement
027: * getLocale() and by StaticInterceptor.
028: *
029: * Not optimized - it's very slow.
030: *
031: * @author James Duncan Davidson [duncan@eng.sun.com]
032: * @author James Todd [gonzo@eng.sun.com]
033: * @author Jason Hunter [jch@eng.sun.com]
034: * @author Harish Prabandham
035: * @author costin@eng.sun.com
036: */
037: public class AcceptLanguage {
038:
039: public static Locale getLocale(String acceptLanguage) {
040: if (acceptLanguage == null)
041: return Locale.getDefault();
042:
043: Hashtable languages = new Hashtable();
044: Vector quality = new Vector();
045: processAcceptLanguage(acceptLanguage, languages, quality);
046:
047: if (languages.size() == 0)
048: return Locale.getDefault();
049:
050: Vector l = new Vector();
051: extractLocales(languages, quality, l);
052:
053: return (Locale) l.elementAt(0);
054: }
055:
056: public static Enumeration getLocales(String acceptLanguage) {
057: // Short circuit with an empty enumeration if null header
058: if (acceptLanguage == null) {
059: Vector v = new Vector();
060: v.addElement(Locale.getDefault());
061: return v.elements();
062: }
063:
064: Hashtable languages = new Hashtable();
065: Vector quality = new Vector();
066: processAcceptLanguage(acceptLanguage, languages, quality);
067:
068: if (languages.size() == 0) {
069: Vector v = new Vector();
070: v.addElement(Locale.getDefault());
071: return v.elements();
072: }
073: Vector l = new Vector();
074: extractLocales(languages, quality, l);
075: return l.elements();
076: }
077:
078: private static void processAcceptLanguage(String acceptLanguage,
079: Hashtable languages, Vector q) {
080: StringTokenizer languageTokenizer = new StringTokenizer(
081: acceptLanguage, ",");
082:
083: while (languageTokenizer.hasMoreTokens()) {
084: String language = languageTokenizer.nextToken().trim();
085: int qValueIndex = language.indexOf(';');
086: int qIndex = language.indexOf('q');
087: int equalIndex = language.indexOf('=');
088: Double qValue = new Double(1);
089:
090: if (qValueIndex > -1 && qValueIndex < qIndex
091: && qIndex < equalIndex) {
092: String qValueStr = language.substring(qValueIndex + 1);
093: language = language.substring(0, qValueIndex);
094: qValueStr = qValueStr.trim().toLowerCase();
095: qValueIndex = qValueStr.indexOf('=');
096: qValue = new Double(0);
097: if (qValueStr.startsWith("q") && qValueIndex > -1) {
098: qValueStr = qValueStr.substring(qValueIndex + 1);
099: try {
100: qValue = new Double(qValueStr.trim());
101: } catch (NumberFormatException nfe) {
102: }
103: }
104: }
105:
106: // XXX
107: // may need to handle "*" at some point in time
108:
109: if (!language.equals("*")) {
110: String key = qValue.toString();
111: Vector v;
112: if (languages.containsKey(key)) {
113: v = (Vector) languages.get(key);
114: } else {
115: v = new Vector();
116: q.addElement(qValue);
117: }
118: v.addElement(language);
119: languages.put(key, v);
120: }
121: }
122: }
123:
124: private static void extractLocales(Hashtable languages, Vector q,
125: Vector l) {
126: // XXX We will need to order by q value Vector in the Future ?
127: Enumeration e = q.elements();
128: while (e.hasMoreElements()) {
129: Vector v = (Vector) languages
130: .get(((Double) e.nextElement()).toString());
131: Enumeration le = v.elements();
132: while (le.hasMoreElements()) {
133: String language = (String) le.nextElement();
134: String country = "";
135: int countryIndex = language.indexOf("-");
136: if (countryIndex > -1) {
137: country = language.substring(countryIndex + 1)
138: .trim();
139: language = language.substring(0, countryIndex)
140: .trim();
141: }
142: l.addElement(new Locale(language, country));
143: }
144: }
145: }
146:
147: }
|