001: /*
002: * Copyright (c) 2002-2006 by OpenSymphony
003: * All rights reserved.
004: */
005:
006: package com.opensymphony.xwork.interceptor;
007:
008: import com.opensymphony.xwork.ActionInvocation;
009: import com.opensymphony.xwork.util.LocalizedTextUtil;
010: import org.apache.commons.logging.Log;
011: import org.apache.commons.logging.LogFactory;
012:
013: import java.util.Locale;
014: import java.util.Map;
015:
016: /**
017: * <!-- START SNIPPET: description -->
018: *
019: * An interceptor that handles setting the locale specified in a session as the locale for the current action request.
020: * In addition, this interceptor will look for a specific HTTP request parameter and set the locale to whatever value is
021: * provided. This means that this interceptor can be used to allow for your application to dynamically change the locale
022: * for the user's session. This is very useful for applications that require multi-lingual support and want the user to
023: * be able to set his or her language preference at any point. The locale parameter is removed during the execution of
024: * this interceptor, ensuring that properties aren't set on an action (such as request_locale) that have no typical
025: * corresponding setter in your action.
026: *
027: * <p/>For example, using the default parameter name, a request to <b>foo.action?request_locale=en_US</b>, then the
028: * locale for US English is saved in the user's session and will be used for all future requests.
029: *
030: * <!-- END SNIPPET: description -->
031: *
032: * <p/> <u>Interceptor parameters:</u>
033: *
034: * <!-- START SNIPPET: parameters -->
035: *
036: * <ul>
037: *
038: * <li>parameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to and save
039: * in the session. By default this is <b>request_locale</b></li>
040: *
041: * <li>attributeName (optional) - the name of the session key to store the selected locale. By default this is
042: * <b>WW_TRANS_I18N_LOCALE</b></li>
043: *
044: * </ul>
045: *
046: * <!-- END SNIPPET: parameters -->
047: *
048: * <p/> <u>Extending the interceptor:</u>
049: *
050: * <p/>
051: *
052: * <!-- START SNIPPET: extending -->
053: *
054: * There are no known extensions points for this interceptor.
055: *
056: * <!-- END SNIPPET: extending -->
057: *
058: * <p/> <u>Example code:</u>
059: *
060: * <pre>
061: * <!-- START SNIPPET: example -->
062: * <action name="someAction" class="com.examples.SomeAction">
063: * <interceptor-ref name="i18n"/>
064: * <interceptor-ref name="basicStack"/>
065: * <result name="success">good_result.ftl</result>
066: * </action>
067: * <!-- END SNIPPET: example -->
068: * </pre>
069: *
070: * @author Aleksei Gopachenko
071: */
072: public class I18nInterceptor implements Interceptor {
073: protected static final Log log = LogFactory
074: .getLog(I18nInterceptor.class);
075:
076: public static final String DEFAULT_SESSION_ATTRIBUTE = "WW_TRANS_I18N_LOCALE";
077: public static final String DEFAULT_PARAMETER = "request_locale";
078:
079: protected String parameterName = DEFAULT_PARAMETER;
080: protected String attributeName = DEFAULT_SESSION_ATTRIBUTE;
081:
082: public I18nInterceptor() {
083: if (log.isDebugEnabled()) {
084: log.debug("new I18nInterceptor()");
085: }
086: }
087:
088: public void setParameterName(String parameterName) {
089: this .parameterName = parameterName;
090: }
091:
092: public void setAttributeName(String attributeName) {
093: this .attributeName = attributeName;
094: }
095:
096: public void init() {
097: if (log.isDebugEnabled())
098: log.debug("init()");
099: }
100:
101: public void destroy() {
102: if (log.isDebugEnabled())
103: log.debug("destroy()");
104: }
105:
106: public String intercept(ActionInvocation invocation)
107: throws Exception {
108: if (log.isDebugEnabled()) {
109: log.debug("intercept '"
110: + invocation.getProxy().getNamespace() + "/"
111: + invocation.getProxy().getActionName() + "' { ");
112: }
113: //get requested locale
114: Map params = invocation.getInvocationContext().getParameters();
115: Object requested_locale = params.remove(parameterName);
116: if (requested_locale != null
117: && requested_locale.getClass().isArray()
118: && ((Object[]) requested_locale).length == 1) {
119: requested_locale = ((Object[]) requested_locale)[0];
120: }
121:
122: if (log.isDebugEnabled()) {
123: log.debug("requested_locale=" + requested_locale);
124: }
125:
126: //save it in session
127: Map session = invocation.getInvocationContext().getSession();
128: if (session != null) {
129: if (requested_locale != null) {
130: Locale locale = (requested_locale instanceof Locale) ? (Locale) requested_locale
131: : LocalizedTextUtil.localeFromString(
132: requested_locale.toString(), null);
133: if (log.isDebugEnabled()) {
134: log.debug("store locale=" + locale);
135: }
136:
137: if (locale != null) {
138: session.put(attributeName, locale);
139: }
140: }
141:
142: //set locale for action
143: Object locale = session.get(attributeName);
144: if (locale != null && locale instanceof Locale) {
145: if (log.isDebugEnabled()) {
146: log.debug("apply locale=" + locale);
147: }
148:
149: saveLocale(invocation, (Locale) locale);
150: }
151: }
152:
153: if (log.isDebugEnabled()) {
154: log.debug("before Locale="
155: + invocation.getStack().findValue("locale"));
156: }
157:
158: final String result = invocation.invoke();
159: if (log.isDebugEnabled()) {
160: log.debug("after Locale="
161: + invocation.getStack().findValue("locale"));
162: }
163:
164: if (log.isDebugEnabled()) {
165: log.debug("intercept } ");
166: }
167:
168: return result;
169: }
170:
171: /**
172: * Save the given locale to the ActionInvocation.
173: *
174: * @param invocation The ActionInvocation.
175: * @param locale The locale to save.
176: */
177: protected void saveLocale(ActionInvocation invocation, Locale locale) {
178: invocation.getInvocationContext().setLocale(locale);
179: }
180:
181: }
|