| /* |
| * Copyright 1999-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.cocoon.i18n; |
| |
| import org.apache.avalon.framework.parameters.Parameters; |
| |
| import org.apache.cocoon.environment.Cookie; |
| import org.apache.cocoon.environment.ObjectModelHelper; |
| import org.apache.cocoon.environment.Request; |
| import org.apache.cocoon.environment.Session; |
| import org.apache.cocoon.environment.Response; |
| import org.apache.cocoon.transformation.I18nTransformer; |
| import org.apache.cocoon.util.Deprecation; |
| |
| import java.util.Enumeration; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| |
| /** |
| * A utility class for i18n formatting and parsing routing. |
| * |
| * @version $Id$ |
| */ |
| public class I18nUtils { |
| |
| // Locale string delimiter |
| private static final String LOCALE_DELIMITER = "_-@."; |
| |
| /** |
| * Did we already encountered an old namespace? This is static to ensure |
| * that the associated message will be logged only once. |
| */ |
| private static boolean deprecationFound = false; |
| |
| private I18nUtils() { |
| // Disable instantiation |
| } |
| |
| /** |
| * Parses given locale string to Locale object. If the string is null |
| * then the given locale is returned. |
| * |
| * @param localeString a string containing locale in |
| * <code>language_country_variant</code> format. |
| * @param defaultLocale returned if localeString is <code>null</code> |
| */ |
| public static Locale parseLocale(String localeString, Locale defaultLocale) { |
| if (localeString != null) { |
| StringTokenizer st = new StringTokenizer(localeString, |
| LOCALE_DELIMITER); |
| String l = st.hasMoreElements() ? st.nextToken() |
| : defaultLocale.getLanguage(); |
| String c = st.hasMoreElements() ? st.nextToken() : ""; |
| String v = st.hasMoreElements() ? st.nextToken() : ""; |
| return new Locale(l, c, v); |
| } |
| |
| return defaultLocale; |
| } |
| |
| /** |
| * Parses given locale string to Locale object. If the string is null |
| * then the VM default locale is returned. |
| * |
| * @param localeString a string containing locale in |
| * <code>language_country_variant</code> format. |
| * |
| * @see #parseLocale(String, Locale) |
| * @see java.util.Locale#getDefault() |
| */ |
| public static Locale parseLocale(String localeString) { |
| return parseLocale(localeString, Locale.getDefault()); |
| } |
| |
| |
| /** |
| * Callback interface for |
| * {@link I18nUtils#findLocale(Map, String, Parameters, Locale, boolean, boolean, boolean, I18nUtils.LocaleValidator)} |
| * @since 2.1.6 |
| */ |
| public interface LocaleValidator { |
| |
| /** |
| * @param name of the locale (for debugging) |
| * @param locale to test |
| * @return true if locale satisfies validator's criteria |
| */ |
| public boolean test(String name, Locale locale); |
| } |
| |
| /** |
| * Find a suitable locale from an objectModel. |
| * @since 2.1.6 |
| * @return locale found, or null if none found. |
| */ |
| public static Locale findLocale(Map objectModel, |
| String attribute, |
| Parameters parameters, |
| Locale defaultLocale, |
| boolean useLocale, |
| boolean useLocales, |
| boolean useBlankLocale, |
| LocaleValidator test) { |
| String localeStr; |
| Locale locale; |
| |
| Request request = ObjectModelHelper.getRequest(objectModel); |
| |
| // 1. Request parameter 'locale' |
| localeStr = request.getParameter(attribute); |
| if (localeStr != null) { |
| locale = parseLocale(localeStr); |
| if (test == null || test.test("request", locale)) { |
| return locale; |
| } |
| } |
| |
| // 2. Session attribute 'locale' |
| Session session = request.getSession(false); |
| if (session != null && |
| ((localeStr = (String) session.getAttribute(attribute)) != null)) { |
| locale = parseLocale(localeStr); |
| if (test == null || test.test("session", locale)) { |
| return locale; |
| } |
| } |
| |
| // 3. First matching cookie parameter 'locale' within each cookie sent |
| Cookie[] cookies = request.getCookies(); |
| if (cookies != null) { |
| for (int i = 0; i < cookies.length; i++) { |
| Cookie cookie = cookies[i]; |
| if (cookie.getName().equals(attribute)) { |
| localeStr = cookie.getValue(); |
| locale = parseLocale(localeStr); |
| if (test == null || test.test("cookie", locale)) { |
| return locale; |
| } |
| break; |
| } |
| } |
| } |
| |
| // 4. Sitemap parameter "locale" |
| if (parameters != null) { |
| localeStr = parameters.getParameter("locale", null); |
| if (localeStr != null) { |
| locale = parseLocale(localeStr); |
| if (test == null || test.test("sitemap", locale)) { |
| return locale; |
| } |
| } |
| } |
| |
| // 5. Locale setting of the requesting browser or server default |
| if (useLocale && !useLocales) { |
| locale = request.getLocale(); |
| if (test == null || test.test("request", locale)) { |
| return locale; |
| } |
| } |
| if (useLocales) { |
| Enumeration locales = request.getLocales(); |
| while (locales.hasMoreElements()) { |
| locale = (Locale)locales.nextElement(); |
| if (test == null || test.test("request", locale)) { |
| return locale; |
| } |
| } |
| } |
| |
| // 6. Default |
| if (defaultLocale != null) { |
| locale = defaultLocale; |
| if (test == null || test.test("default", locale)) { |
| return locale; |
| } |
| } |
| |
| // 7. Blank |
| if (useBlankLocale) { |
| locale = new Locale("", ""); |
| if (test == null || test.test("blank", locale)) { |
| return locale; |
| } |
| } |
| |
| // 8. Fail |
| return null; |
| } |
| |
| /** |
| * Find a suitable locale from an objectModel. |
| * @since 2.1.6 |
| * @return locale found, or server default (never null). |
| */ |
| public static Locale findLocale(Map objectModel, |
| String attribute, |
| Parameters parameters, |
| Locale defaultLocale, |
| boolean useLocale) { |
| return findLocale(objectModel, attribute, parameters, defaultLocale, useLocale, false, false, null); |
| } |
| |
| /** |
| * Store locale in request, session, or cookie. |
| * @since 2.1.6 |
| */ |
| public static void storeLocale(Map objectModel, |
| String attribute, |
| String locale, |
| boolean storeInRequest, |
| boolean storeInSession, |
| boolean storeInCookie, |
| boolean createSession) { |
| // store in a request if so configured |
| if (storeInRequest) { |
| Request request = ObjectModelHelper.getRequest(objectModel); |
| request.setAttribute(attribute, locale); |
| } |
| |
| // store in session if so configured |
| if (storeInSession) { |
| Request request = ObjectModelHelper.getRequest(objectModel); |
| Session session = request.getSession(createSession); |
| if (session != null) { |
| session.setAttribute(attribute, locale); |
| } |
| } |
| |
| // store in a cookie if so configured |
| if (storeInCookie) { |
| Response response = ObjectModelHelper.getResponse(objectModel); |
| response.addCookie(response.createCookie(attribute, locale)); |
| } |
| } |
| |
| public static boolean matchesI18nNamespace(String uri) { |
| if (I18nTransformer.I18N_NAMESPACE_URI.equals(uri)) { |
| return true; |
| } else if (I18nTransformer.I18N_OLD_NAMESPACE_URI.equals(uri)) { |
| if (!deprecationFound) { |
| deprecationFound = true; |
| Deprecation.logger.warn("The namespace <" + I18nTransformer.I18N_OLD_NAMESPACE_URI + |
| "> is deprecated, use: <" + I18nTransformer.I18N_NAMESPACE_URI + ">"); |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| } |