Hi All, Attached is version 1.1 already! :-) I've just removed the use of a helper class I had written to access the object model. This version should build cleanly now. Cheers, Marcus > Marcus Crafter wrote: > > Hi Konstantin, > > Attached is my first open cut of the LocaleAction. I've also cc'd > cocoon-dev for public review. > > As you know the code is based on LangSelect, but has been extended > to include full Locale support. Simple documentation is provided in the > javadoc output of this class. Basically, more variables and > configuration options are available to the user in the sitemap. > > I'll be updating the I18nTransformer today and will send in some > patches over the weekend. > > Let the comments and testing roll in! :-) > > Cheers, > > Marcus -- ..... ,,$$$$$$$$$, Marcus Crafter ;$' '$$$$: Computer Systems Engineer $: $$$$: Open Software Associates GmbH $ o_)$$$: 82-84 Mainzer Landstrasse ;$, _/\ &&:' 60327 Frankfurt Germany ' /( &&& \_&&&&' Email : [EMAIL PROTECTED] &&&&. Business Hours : +49 69 9757 200 &&&&&&&: After Hours : +49 69 49086750
/***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.cocoon.acting; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.cocoon.Constants; import org.apache.cocoon.acting.Action; import org.apache.cocoon.environment.Cookie; import org.apache.cocoon.environment.Redirector; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.Response; import org.apache.cocoon.environment.Session; import org.apache.cocoon.environment.SourceResolver; import org.apache.regexp.RE; /** * LocaleAction is a class which obtains the request's locale information * (language, country, variant) and makes it available to the * sitemap/pipeline. * * Definition in sitemap: * <pre> * <map:actions> * <map:action name="locale" src="org.apache.cocoon.acting.LocaleAction"/> * </map:actions> * </pre> * * Examples: * * <pre> * <map:match pattern="file"> * <map:act type="locale"> * <map:generate src="file_{lang}{country}{variant}.xml"/> * </map:act> * </map:match> * </pre> * * or * * <pre> * <map:match pattern="file"> * <map:act type="locale"> * <map:generate src="file.xml?locale={locale}"/> * </map:act> * </map:match> * </pre> * * <br> * * The variables <code>lang</code>, <code>country</code>, * <code>variant</code>, and <code>locale</code> are all available. Note that * <code>country</code> and <code>variant</code> can be empty, however * <code>lang</code> and <code>locale</code> will always contain a valid value. * * <br> * * The following search criteria are used in order when ascertaining locale * values: * * <ol> * <li>Request CGI parameter <i>locale</i></li> * <li>Session attribute <i>locale</i></li> * <li>First matching Cookie parameter <i>locale</i> * within each cookie sent with the current request</li> * <li>Locale setting of the requesting object</li> * </ol> * * (in the case of language, if the above cases do not yield a valid value * the locale value of the server is used) * * <br> * * The attribute names can be configured/customized at action definition * and/or usage time, using the paramters * {language,country,variant,locale}-attribute. * * eg. * * <pre> * <map:action name="locale" src="org.apache.cocoon.acting.LocaleAction"> * <language-attribute>lg</language-attribute> * </map:action> * </pre> * * or: * * <pre> * <map:act type="locale"> * <map:parameter name="language-attribute" value="lg"/> * </map:act> * </pre> * * <center>Code originated from org.apache.cocoon.acting.LangSelect</center> * * @author: <a href="mailto:[EMAIL PROTECTED]">Marcus Crafter</a> * @author: <a href="mailto:[EMAIL PROTECTED]">Konstantin Piroumian</a> * @author: <a href="mailto:[EMAIL PROTECTED]">Lassi Immonen</a> */ public class LocaleAction extends ComposerAction { /** * Constant representing the language parameter */ public static final String LANG = "lang"; /** * Constant representing the country parameter */ public static final String COUNTRY = "country"; /** * Constant representing the variant parameter */ public static final String VARIANT = "variant"; /** * Constant representing the locale parameter */ public static final String LOCALE = "locale"; /** * Constant representing the language configuration attribute */ public static final String LANG_ATTR = "language-attribute"; /** * Constant representing the country configuration attribute */ public static final String COUNTRY_ATTR = "country-attribute"; /** * Constant representing the variant configuration attribute */ public static final String VARIANT_ATTR = "variant-attribute"; /** * Constant representing the locale configuration attribute */ public static final String LOCALE_ATTR = "locale-attribute"; /** * Constant representing the request storage configuration attribute */ public static final String STORE_REQUEST = "store-in-request"; /** * Constant representing the session creation configuration attribute */ public static final String CREATE_SESSION = "create-session"; /** * Constant representing the session storage configuration attribute */ public static final String STORE_SESSION = "store-in-session"; /** * Constant representing the cookie storage configuration attribute */ public static final String STORE_COOKIE = "store-in-cookie"; /** * Configure this action. * * @param conf configuration information (if any) */ public void configure(Configuration conf) throws ConfigurationException { if (conf != null) { Configuration child = conf.getChild(STORE_REQUEST); storeInRequest = child.getValueAsBoolean(false); debug((storeInRequest ? "will" : "won't") + " set values in request"); child = conf.getChild(CREATE_SESSION); createSession = child.getValueAsBoolean(false); debug((createSession ? "will" : "won't") + " create session"); child = conf.getChild(STORE_SESSION); storeInSession = child.getValueAsBoolean(false); debug((storeInSession ? "will" : "won't") + " set values in session"); child = conf.getChild(STORE_COOKIE); storeInCookie = child.getValueAsBoolean(false); debug((storeInCookie ? "will" : "won't") + " set values in cookies"); child = conf.getChild(LANG_ATTR); langAttr = child.getValue(LANG); debug("global language attribute name is " + langAttr); child = conf.getChild(COUNTRY_ATTR); countryAttr = child.getValue(COUNTRY); debug("global country attribute name is " + countryAttr); child = conf.getChild(VARIANT_ATTR); variantAttr = child.getValue(VARIANT); debug("global variant attribute name is " + variantAttr); child = conf.getChild(LOCALE_ATTR); localeAttr = child.getValue(LOCALE); debug("global locale attribute name is " + localeAttr); } } /** * Action which obtains the current environments locale information, and * places it in the objectModel (and optionally in a session/cookie). */ public Map act( Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters par ) throws Exception { // obtain locale information (note, Locale.get* do not return null) String lc = getLocale(objectModel); String[] matches = new RE("_").split(lc); String l = matches.length > 0 ? matches[0] : Locale.getDefault().getLanguage(); String c = matches.length > 1 ? matches[1] : ""; String v = matches.length > 2 ? matches[2] : ""; debug("obtained locale information, locale = " + lc); debug("language = " + l + ", country = " + c + ", variant = " + v); checkParams(par); if (storeInRequest) { Request request = (Request) objectModel.get(Constants.REQUEST_OBJECT); request.setAttribute(langAttr, l); request.setAttribute(countryAttr, c); request.setAttribute(variantAttr, v); request.setAttribute(localeAttr, lc); debug("updated request"); } // store in session if so configured if (storeInSession) { Request request = (Request) objectModel.get(Constants.REQUEST_OBJECT); Session session = request.getSession(createSession); if (session != null) { session.setAttribute(langAttr, l); session.setAttribute(countryAttr, c); session.setAttribute(variantAttr, v); session.setAttribute(localeAttr, lc); debug("updated session"); } } // store in a cookie if so configured if (storeInCookie) { Response response = (Response) objectModel.get(Constants.RESPONSE_OBJECT); response.addCookie(response.createCookie(langAttr, l)); response.addCookie(response.createCookie(countryAttr, c)); response.addCookie(response.createCookie(variantAttr, v)); response.addCookie(response.createCookie(localeAttr, lc)); debug("created cookies"); } // set up a map for XPath Substituion Map map = new HashMap(); map.put(langAttr, l); map.put(countryAttr, c); map.put(variantAttr, v); map.put(localeAttr, lc); debug("returning map for XPath substitutions"); return map; } /** * Helper method to access Locale sub component values. * * @param objectModel requesting object's environment * @return locale value * @throws Exception should some error occur */ public static String getLocale(Map objectModel) throws Exception { String ret_val; // 1. Request CGI parameter 'locale' Request request = (Request) objectModel.get(Constants.REQUEST_OBJECT); if ((ret_val = request.getParameter(LOCALE)) != null) return ret_val; // 2. Session attribute 'locale' Session session = request.getSession(false); if (session != null && ((ret_val = (String) session.getAttribute(LOCALE)) != null) ) return ret_val; // 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(LOCALE)) return cookie.getValue(); } } // 4. Locale setting of the requesting object/server return request.getLocale().toString(); } /** * Method to check <map:act type="locale"/> invocations for local * customisation. * * eg. * * <pre> * <map:act type="locale"> * <map:parameter name="language-attribute" value="lg"/> * </map:act> * </pre> */ private void checkParams(Parameters par) { langAttr = par.getParameter(LANG_ATTR, langAttr); countryAttr = par.getParameter(COUNTRY_ATTR, countryAttr); variantAttr = par.getParameter(VARIANT_ATTR, variantAttr); localeAttr = par.getParameter(LOCALE_ATTR, localeAttr); storeInRequest = par.getParameterAsBoolean(STORE_REQUEST, storeInRequest); storeInSession = par.getParameterAsBoolean(STORE_SESSION, storeInSession); createSession = par.getParameterAsBoolean(CREATE_SESSION, createSession); storeInCookie = par.getParameterAsBoolean(STORE_COOKIE, storeInCookie); debug( "checking for local overrides, " + LANG_ATTR + " = " + langAttr + ", " + COUNTRY_ATTR + " = " + countryAttr + ", " + VARIANT_ATTR + " = " + variantAttr + ", " + LOCALE_ATTR + " = " + localeAttr + ", " + STORE_REQUEST + " = " + storeInRequest + ", " + STORE_SESSION + " = " + storeInSession + ", " + CREATE_SESSION + " = " + createSession + ", " + STORE_COOKIE + " = " + storeInCookie ); } /** * Helper debug method, prefixes all debug messages with the classes name * * @param msg debugging message */ private void debug(String msg) { getLogger().debug(getClass().getName() + ": " + msg); } // Store the lang in request. Default is not to do this. private boolean storeInRequest = false; // Store the lang in session, if available. Default is not to do this. private boolean storeInSession = false; // Should we create a session if needed. Default is not to do this. private boolean createSession = false; // Should we add a cookie with the lang. Default is not to do this. private boolean storeInCookie = false; // Configuration attributes. private String langAttr; private String countryAttr; private String variantAttr; private String localeAttr; }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]