KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > turbine > services > localization > LocaleTokenizer


1 package org.apache.turbine.services.localization;
2
3 /*
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License")
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Collections JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.Locale JavaDoc;
23 import java.util.NoSuchElementException JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25
26 /**
27  * Parses the HTTP <code>Accept-Language</code> header as per section
28  * 14.4 of RFC 2068 (HTTP 1.1 header field definitions).
29  *
30  * @author <a HREF="mailto:dlr@collab.net">Daniel Rall</a>
31  * @version $Id: LocaleTokenizer.java,v 1.3.2.2 2004/05/20 03:06:51 seade Exp $
32  */

33 public class LocaleTokenizer
34         implements Iterator JavaDoc
35 {
36     /**
37      * Separates elements of the <code>Accept-Language</code> HTTP
38      * header.
39      */

40     private static final String JavaDoc LOCALE_SEPARATOR = ",";
41
42     /**
43      * Separates locale from quality within elements.
44      */

45     private static final char QUALITY_SEPARATOR = ';';
46
47     /**
48      * The default quality value for an <code>AcceptLanguage</code>
49      * object.
50      */

51     private static final Float JavaDoc DEFAULT_QUALITY = new Float JavaDoc(1.0f);
52
53     /**
54      * The parsed locales.
55      */

56     private ArrayList JavaDoc locales = new ArrayList JavaDoc(3);
57
58     /**
59      * Parses the <code>Accept-Language</code> header.
60      *
61      * @param header The <code>Accept-Language</code> header
62      * (i.e. <code>en, es;q=0.8, zh-TW;q=0.1</code>).
63      */

64     public LocaleTokenizer(String JavaDoc header)
65     {
66         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(header, LOCALE_SEPARATOR);
67         while (tok.hasMoreTokens())
68         {
69             AcceptLanguage acceptLang = new AcceptLanguage();
70             String JavaDoc element = tok.nextToken().trim();
71             int index;
72
73             // Record and cut off any quality value that comes after a
74
// semi-colon.
75
if ((index = element.indexOf(QUALITY_SEPARATOR)) != -1)
76             {
77                 String JavaDoc q = element.substring(index);
78                 element = element.substring(0, index);
79                 if ((index = q.indexOf('=')) != -1)
80                 {
81                     try
82                     {
83                         acceptLang.quality =
84                                 Float.valueOf(q.substring(index + 1));
85                     }
86                     catch (NumberFormatException JavaDoc useDefault)
87                     {
88                     }
89                 }
90             }
91
92             element = element.trim();
93
94             // Create a Locale from the language. A dash may separate the
95
// language from the country.
96
if ((index = element.indexOf('-')) == -1)
97             {
98                 // No dash means no country.
99
acceptLang.locale = new Locale JavaDoc(element, "");
100             }
101             else
102             {
103                 acceptLang.locale = new Locale JavaDoc(element.substring(0, index),
104                         element.substring(index + 1));
105             }
106
107             locales.add(acceptLang);
108         }
109
110         // Sort by quality in descending order.
111
Collections.sort(locales, Collections.reverseOrder());
112     }
113
114     /**
115      * @return Whether there are more locales.
116      */

117     public boolean hasNext()
118     {
119         return !locales.isEmpty();
120     }
121
122     /**
123      * Creates a <code>Locale</code> from the next element of the
124      * <code>Accept-Language</code> header.
125      *
126      * @return The next highest-rated <code>Locale</code>.
127      * @throws NoSuchElementException No more locales.
128      */

129     public Object JavaDoc next()
130     {
131         if (locales.isEmpty())
132         {
133             throw new NoSuchElementException JavaDoc();
134         }
135         return ((AcceptLanguage) locales.remove(0)).locale;
136     }
137
138     /**
139      * Not implemented.
140      */

141     public final void remove()
142     {
143         throw new UnsupportedOperationException JavaDoc(getClass().getName() +
144                 " does not support remove()");
145     }
146
147     /**
148      * Struct representing an element of the HTTP
149      * <code>Accept-Language</code> header.
150      */

151     private class AcceptLanguage implements Comparable JavaDoc
152     {
153         /**
154          * The language and country.
155          */

156         Locale JavaDoc locale;
157
158         /**
159          * The quality of our locale (as values approach
160          * <code>1.0</code>, they indicate increased user preference).
161          */

162         Float JavaDoc quality = DEFAULT_QUALITY;
163
164         public final int compareTo(Object JavaDoc acceptLang)
165         {
166             return quality.compareTo(((AcceptLanguage) acceptLang).quality);
167         }
168     }
169 }
170
Popular Tags