KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > i18n > CmsAcceptLanguageHeaderParser


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/i18n/CmsAcceptLanguageHeaderParser.java,v $
3  * Date : $Date: 2006/07/20 13:46:39 $
4  * Version: $Revision: 1.16 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  *
31  * This file is based on:
32  * org.apache.fulcrum.localization.LocaleTokenizer
33  * from the Apache Fulcrum/Turbine project.
34  *
35  * The Apache Software License, Version 1.1
36  *
37  * Copyright (c) 2001 The Apache Software Foundation. All rights
38  * reserved.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  *
44  * 1. Redistributions of source code must retain the above copyright
45  * notice, this list of conditions and the following disclaimer.
46  *
47  * 2. Redistributions in binary form must reproduce the above copyright
48  * notice, this list of conditions and the following disclaimer in
49  * the documentation and/or other materials provided with the
50  * distribution.
51  *
52  * 3. The end-user documentation included with the redistribution,
53  * if any, must include the following acknowledgment:
54  * "This product includes software developed by the
55  * Apache Software Foundation (http://www.apache.org/)."
56  * Alternately, this acknowledgment may appear in the software itself,
57  * if and wherever such third-party acknowledgments normally appear.
58  *
59  * 4. The names "Apache" and "Apache Software Foundation" and
60  * "Apache Turbine" must not be used to endorse or promote products
61  * derived from this software without prior written permission. For
62  * written permission, please contact apache@apache.org.
63  *
64  * 5. Products derived from this software may not be called "Apache",
65  * "Apache Turbine", nor may "Apache" appear in their name, without
66  * prior written permission of the Apache Software Foundation.
67  *
68  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
69  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
70  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
72  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
73  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
74  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
75  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
77  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
78  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
79  * SUCH DAMAGE.
80  * ====================================================================
81  *
82  * This software consists of voluntary contributions made by many
83  * individuals on behalf of the Apache Software Foundation. For more
84  * information on the Apache Software Foundation, please see
85  * <http://www.apache.org/>.
86  */

87
88 package org.opencms.i18n;
89
90 import org.opencms.main.CmsIllegalArgumentException;
91 import org.opencms.main.CmsRuntimeException;
92 import org.opencms.main.OpenCms;
93 import org.opencms.util.CmsStringUtil;
94
95 import java.util.ArrayList JavaDoc;
96 import java.util.Collections JavaDoc;
97 import java.util.Iterator JavaDoc;
98 import java.util.List JavaDoc;
99 import java.util.Locale JavaDoc;
100 import java.util.NoSuchElementException JavaDoc;
101
102 import javax.servlet.http.HttpServletRequest JavaDoc;
103
104 /**
105  * Parses the HTTP <code>Accept-Language</code> header as per section 14.4 of RFC 2068
106  * (HTTP 1.1 header field definitions) and creates a sorted list of Locales from it.
107  *
108  * @author Daniel Rall
109  * @author Alexander Kandzior
110  *
111  * @version $Revision: 1.16 $
112  *
113  * @since 6.0.0
114  */

115 public class CmsAcceptLanguageHeaderParser implements Iterator JavaDoc {
116
117     /**
118      * Struct representing an element of the HTTP <code>Accept-Language</code> header.
119      */

120     class AcceptLanguage implements Comparable JavaDoc {
121
122         /** The language and country. */
123         Locale JavaDoc m_locale;
124
125         /** The m_quality of our m_locale (as values approach <code>1.0</code>, they indicate increased user preference). */
126         Float JavaDoc m_quality = DEFAULT_QUALITY;
127
128         /**
129          * @see java.lang.Comparable#compareTo(java.lang.Object)
130          */

131         public final int compareTo(Object JavaDoc acceptLang) {
132
133             return m_quality.compareTo(((AcceptLanguage)acceptLang).m_quality);
134         }
135     }
136
137     /** A constant for the HTTP <code>Accept-Language</code> header. */
138     public static final String JavaDoc ACCEPT_LANGUAGE = "Accept-Language";
139
140     /** The default m_quality value for an <code>AcceptLanguage</code> object. */
141     protected static final Float JavaDoc DEFAULT_QUALITY = new Float JavaDoc(1.0f);
142
143     /** Separates elements of the <code>Accept-Language</code> HTTP header. */
144     private static final char LOCALE_SEPARATOR = ',';
145
146     /** Separates m_locale from m_quality within elements. */
147     private static final char QUALITY_SEPARATOR = ';';
148
149     /** The parsed <code>Accept-Language</code> headers. */
150     private List JavaDoc m_acceptLanguage = new ArrayList JavaDoc(3);
151
152     /** The parsed locales. */
153     private List JavaDoc m_locales;
154
155     /**
156      * Parses the <code>Accept-Language</code> header from the provided request.<p>
157      *
158      * @param req the request to parse
159      * @param defaultLocale the default locale to use
160      */

161     public CmsAcceptLanguageHeaderParser(HttpServletRequest JavaDoc req, Locale JavaDoc defaultLocale) {
162
163         this(req.getHeader(ACCEPT_LANGUAGE), defaultLocale);
164     }
165
166     /**
167      * Parses the <code>Accept-Language</code> header.<p>
168      *
169      * @param header the <code>Accept-Language</code> header (i.e. <code>en, es;q=0.8, zh-TW;q=0.1</code>)
170      * @param defaultLocale the default locale to use
171      */

172     public CmsAcceptLanguageHeaderParser(String JavaDoc header, Locale JavaDoc defaultLocale) {
173
174         // check if there was a locale foud in the HTTP header.
175
// if not, use the default locale.
176
if (header == null) {
177             m_locales = new ArrayList JavaDoc();
178             m_locales.add(defaultLocale);
179         } else {
180             List JavaDoc tokens = CmsStringUtil.splitAsList(header, LOCALE_SEPARATOR, true);
181             Iterator JavaDoc it = tokens.iterator();
182             while (it.hasNext()) {
183                 AcceptLanguage acceptLang = new AcceptLanguage();
184                 String JavaDoc element = (String JavaDoc)it.next();
185                 int index;
186
187                 // Record and cut off any quality value that comes after a semi-colon.
188
index = element.indexOf(QUALITY_SEPARATOR);
189                 if (index != -1) {
190                     String JavaDoc q = element.substring(index);
191                     element = element.substring(0, index);
192                     index = q.indexOf('=');
193                     if (index != -1) {
194                         try {
195                             acceptLang.m_quality = Float.valueOf(q.substring(index + 1));
196                         } catch (NumberFormatException JavaDoc useDefault) {
197                             // noop
198
}
199                     }
200                 }
201
202                 element = element.trim();
203
204                 // Create a Locale from the language. A dash may separate the language from the country.
205
index = element.indexOf('-');
206                 if (index == -1) {
207                     // No dash means no country.
208
acceptLang.m_locale = new Locale JavaDoc(element, "");
209                 } else {
210                     acceptLang.m_locale = new Locale JavaDoc(element.substring(0, index), element.substring(index + 1));
211                 }
212
213                 m_acceptLanguage.add(acceptLang);
214             }
215
216             // sort by quality in descending order
217
Collections.sort(m_acceptLanguage, Collections.reverseOrder());
218
219             // store all calculated Locales in a List
220
m_locales = new ArrayList JavaDoc(m_acceptLanguage.size());
221             Iterator JavaDoc i = m_acceptLanguage.iterator();
222             while (i.hasNext()) {
223                 AcceptLanguage lang = (AcceptLanguage)i.next();
224                 m_locales.add(lang.m_locale);
225             }
226         }
227
228     }
229
230     /**
231      * Creates a value string for the HTTP Accept-Language header based on the default localed.<p>
232      *
233      * @return value string for the HTTP Accept-Language
234      */

235     public static String JavaDoc createLanguageHeader() {
236
237         String JavaDoc header;
238
239         // get the default accept-language header value
240
List JavaDoc defaultLocales = OpenCms.getLocaleManager().getDefaultLocales();
241         Iterator JavaDoc i = defaultLocales.iterator();
242         header = "";
243         while (i.hasNext()) {
244             Locale JavaDoc loc = (Locale JavaDoc)i.next();
245             header += loc.getLanguage() + ", ";
246         }
247         header = header.substring(0, header.length() - 2);
248         return header;
249     }
250
251     /**
252      * Returns the sorted list of accepted Locales.<p>
253      *
254      * @return the sorted list of accepted Locales
255      */

256     public List JavaDoc getAcceptedLocales() {
257
258         return m_locales;
259     }
260
261     /**
262      * @return Whether there are more locales.
263      */

264     public boolean hasNext() {
265
266         return !m_acceptLanguage.isEmpty();
267     }
268
269     /**
270      * Creates a <code>Locale</code> from the next element of the <code>Accept-Language</code> header.
271      *
272      * @return The next highest-rated <code>Locale</code>.
273      */

274     public Object JavaDoc next() {
275
276         if (m_acceptLanguage.isEmpty()) {
277             throw new NoSuchElementException JavaDoc();
278         }
279         return ((AcceptLanguage)m_acceptLanguage.remove(0)).m_locale;
280     }
281
282     /**
283      * Not implemented.
284      *
285      * @throws CmsIllegalArgumentException always to signal that remove is not implemented
286      * (<b>interface contract defines {@link UnsupportedOperationException}</b>)
287      */

288     public final void remove() throws CmsIllegalArgumentException {
289
290         throw new CmsRuntimeException(org.opencms.db.Messages.get().container(
291             org.opencms.db.Messages.ERR_UNSUPPORTED_OPERATION_2,
292             getClass().getName(),
293             "remove()"));
294     }
295 }
Popular Tags