 | As of WebWork 2.2, this interceptor is included with the normal distribution as the I18n Interceptor |
Consider adding transparent i18 with simple on-the-fly locale switching to your appliction via I18NInterceptor.
The main idea:
Interceptor could track locale switch requests, persist selection in current session and set locale for all (or appropriate) actions invoked.
package neuro.util.xwork;
import com.opensymphony.xwork.ActionSupport;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.Interceptor;
import java.util.Locale;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* I18nInterceptor
* @author Aleksei Gopachenko
*/
public class I18nInterceptor implements Interceptor
{
protected static final Log log = LogFactory.getLog(I18nInterceptor.class);
public static final String DEFAULT_SESSION_ATTRIBUTE = "WW_TRANS_I18N_LOCALE";
public static final String DEFAULT_PARAMETER = "request_locale";
protected String parameterName = DEFAULT_PARAMETER;
protected String attributeName = DEFAULT_SESSION_ATTRIBUTE;
/**
*/
public I18nInterceptor()
{
if(log.isDebugEnabled()) log.debug("new I18nInterceptor()");
}
public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}
public void setAttributeName(String attributeName) {
this.attributeName = attributeName;
}
/**
*/
public void init() {
if(log.isDebugEnabled()) log.debug("init()");
}
/**
*/
public void destroy() {
if(log.isDebugEnabled()) log.debug("destroy()");
}
/**
*/
public String intercept(ActionInvocation invocation) throws Exception {
if(log.isDebugEnabled()) log.debug("intercept '"
+invocation.getProxy().getNamespace()+"/"
+invocation.getProxy().getActionName()+"' { ");
Object requested_locale = invocation.getInvocationContext().getParameters().get(parameterName);
if(requested_locale!=null && requested_locale.getClass().isArray() && ((Object[])requested_locale).length==1) {
requested_locale=((Object[])requested_locale)[0];
}
if(log.isDebugEnabled()) log.debug("requested_locale="+requested_locale);
if (requested_locale!=null) {
Locale locale = (requested_locale instanceof Locale)?
(Locale) requested_locale : localeFromString(requested_locale.toString());
if(log.isDebugEnabled()) log.debug("store locale="+locale);
if(locale!=null)invocation.getInvocationContext().getSession().put(attributeName,locale);
}
Object locale = invocation.getInvocationContext().getSession().get(attributeName);
if (locale!=null && locale instanceof Locale) {
if(log.isDebugEnabled()) log.debug("apply locale="+locale);
invocation.getInvocationContext().setLocale((Locale)locale);
}
if(log.isDebugEnabled()) log.debug("before Locale="+((ActionSupport)invocation.getAction()).getLocale());
final String result = invocation.invoke();
if(log.isDebugEnabled()) log.debug("after Locale="+((ActionSupport)invocation.getAction()).getLocale());
if(log.isDebugEnabled()) log.debug("intercept } ");
return result;
}
Locale localeFromString(String localeStr) {
if ((localeStr == null) || (localeStr.trim().length() == 0) || (localeStr.equals("_"))) {
return Locale.getDefault();
}
int index = localeStr.indexOf('_');
if (index < 0) {
return new Locale(localeStr);
}
String language = localeStr.substring(0,index);
if (index == localeStr.length()) {
return new Locale(language);
}
localeStr = localeStr.substring(index +1);
index = localeStr.indexOf('_');
if (index < 0) {
return new Locale(language,localeStr);
}
String country = localeStr.substring(0,index);
if (index == localeStr.length()) {
return new Locale(language,country);
}
localeStr = localeStr.substring(index +1);
return new Locale(language,country,localeStr);
}
}
Can be enabled for whole package via something like:
<interceptor name="i18n" class="neuro.util.xwork.I18nInterceptor">
<!-- on which request parameter we should react, optional, defaults to "request_locale" ->
<param name="parameterName">set_locale</param>
<!- under which session attribute locale should be stored, optional, defaults to "WW_TRANS_I18N_LOCALE" ->
<param name="attributeName">ww_locale</param>
</interceptor>
<interceptor-stack name="i18nStack">
<interceptor-ref name="i18n"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
<default-interceptor-ref name="i18nStack"/>
...and invoked in web-app just by adding few links to menu:
<a href="?set_locale=en">EN</a>
<a href="?set_locale=ru">RU</a>
<!- etc -->
Of course you still need to move all explisitly defined messages or labels to appropriate ResourceBundles and make translations. Be sure to check out your
- Actions - to use getText(...)
- *-validation.xml files - to use <message key=...>
- results/views - to use WW i18n services by <webwork:text ...> tag, or directly by evaluating getText(...) OGNL expression on current stack.
If this Interceptor is generally useful, may be it should go into codebase?
This is being added to WebWork 2.2.