diff --git a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
index f5a778dc1..c30182a1f 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
@@ -66,7 +66,7 @@ import java.util.Map;
* in the session. By default this is request_locale
*
*
requestCookieParameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to
- * and save in a cookien. By default this is request_cookie_locale
+ * and save in a cookie. By default this is request_cookie_locale
*
* requestOnlyParameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to
* for the current request only, without saving it in the session. By default this is request_only_locale
@@ -148,113 +148,53 @@ public class I18nInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
- LOG.debug("Intercept '{}/{}'",
- invocation.getProxy().getNamespace(), invocation.getProxy().getActionName());
+ LOG.debug("Intercept '{}/{}'", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName());
+
+ LocaleHandler localeHandler = getLocaleHandler(invocation);
+ Locale locale = localeHandler.find();
+
+ if (locale == null) {
+ locale = localeHandler.read(invocation);
+ }
+
+ if (localeHandler.shouldStore()) {
+ locale = localeHandler.store(invocation, locale);
+ }
- RequestOnlyLocaleFinder localeFinder = getLocaleFinder(invocation);
- Locale locale = getLocaleFromParam(localeFinder.find());
- locale = storeLocale(invocation, locale);
useLocale(invocation, locale);
if (LOG.isDebugEnabled()) {
LOG.debug("Before action invocation Locale={}", invocation.getStack().findValue("locale"));
}
- final String result = invocation.invoke();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("After action invocation Locale={}", invocation.getStack().findValue("locale"));
+ try {
+ return invocation.invoke();
+ } finally {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("After action invocation Locale={}", invocation.getStack().findValue("locale"));
+ }
}
-
- return result;
}
- protected RequestOnlyLocaleFinder getLocaleFinder(ActionInvocation invocation) {
- RequestOnlyLocaleFinder localeFinder;
+ /**
+ * Override this method to use your own implementation of {@link LocaleHandler}
+ *
+ * @param invocation current action invocation context
+ * @return instance of {@link LocaleHandler}
+ */
+ protected LocaleHandler getLocaleHandler(ActionInvocation invocation) {
+ LocaleHandler localeHandler;
+
if (this.storage == Storage.COOKIE) {
- localeFinder = new CookieLocaleFinder(invocation);
+ localeHandler = new CookieLocaleHandler(invocation);
} else if (this.storage == Storage.SESSION) {
- localeFinder = new SessionLocaleFinder(invocation);
+ localeHandler = new SessionLocaleHandler(invocation);
} else {
- localeFinder = new RequestOnlyLocaleFinder(invocation);
+ localeHandler = new RequestOnlyLocaleHandler(invocation);
}
- LOG.debug("Using LocaleFinder implementation {}", localeFinder.getClass().getName());
- return localeFinder;
- }
-
- /**
- * Store the locale to the chosen storage, like f. e. the session
- *
- * @param invocation the action invocation
- * @param locale the locale to store
- *
- * @return the locale
- */
- protected Locale storeLocale(ActionInvocation invocation, Locale locale) {
- if (locale == null) {
- storage = Storage.NONE;
- locale = readStoredLocale(invocation);
- }
-
- if (storage == Storage.COOKIE) {
- storeLocaleInCookie(invocation, locale);
- }
-
- if (Storage.SESSION == storage) {
- storeLocaleInSession(invocation, locale);
- }
-
- return locale;
- }
-
- protected void storeLocaleInCookie(ActionInvocation ignore, Locale locale) {
- HttpServletResponse response = ServletActionContext.getResponse();
-
- Cookie cookie = new Cookie(DEFAULT_COOKIE_ATTRIBUTE, locale.toString());
- cookie.setMaxAge(1209600); // two weeks
- response.addCookie(cookie);
- }
-
- protected void storeLocaleInSession(ActionInvocation invocation, Locale locale) {
- //save it in session
- Map session = invocation.getInvocationContext().getSession();
-
- if (session != null) {
- String sessionId = ServletActionContext.getRequest().getSession().getId();
- synchronized (sessionId.intern()) {
- session.put(attributeName, locale);
- }
- }
- }
-
- /**
- * Reads the locale from the session or from a cookie and if not found
- * from the current invocation (=browser)
- *
- * @param invocation the current invocation
- * @return the read locale
- */
- protected Locale readStoredLocale(ActionInvocation invocation) {
- Locale locale;
- if (storage == Storage.SESSION) {
- locale = readStoredLocalFromSession(invocation);
- if (locale != null) {
- LOG.debug("Found stored Locale {} in session, using it!", locale);
- return locale;
- }
- }
-
- if (storage == Storage.COOKIE) {
- locale = readStoredLocaleFromCookie(invocation);
- if (locale != null) {
- LOG.debug("Found stored Locale {} in cookie, using it!", locale);
- return locale;
- }
- }
-
- LOG.debug("Neither locale was in session nor in cookies, searching current Invocation context");
- return readStoredLocaleFromCurrentInvocation(invocation);
+ LOG.debug("Using LocaleFinder implementation {}", localeHandler.getClass().getName());
+ return localeHandler;
}
/**
@@ -276,7 +216,7 @@ public class I18nInterceptor extends AbstractInterceptor {
}
}
if (locale != null) {
- LOG.debug("Applied request locale: {}", locale);
+ LOG.debug("Found locale: {}", locale);
}
}
@@ -289,46 +229,8 @@ public class I18nInterceptor extends AbstractInterceptor {
return locale;
}
- protected Locale readStoredLocalFromSession(ActionInvocation invocation) {
- // check session for saved locale
- Map session = invocation.getInvocationContext().getSession();
-
- if (session != null) {
- String sessionId = ServletActionContext.getRequest().getSession().getId();
- synchronized (sessionId.intern()) {
- Object sessionLocale = session.get(attributeName);
- if (sessionLocale != null && sessionLocale instanceof Locale) {
- Locale locale = (Locale) sessionLocale;
- LOG.debug("Applied session locale: {}", locale);
- return locale;
- }
- }
- }
- return null;
- }
-
- protected Locale readStoredLocaleFromCookie(ActionInvocation ignore) {
- Cookie[] cookies = ServletActionContext.getRequest().getCookies();
- if (cookies != null) {
- for (Cookie cookie : cookies) {
- if (DEFAULT_COOKIE_ATTRIBUTE.equals(cookie.getName())) {
- return getLocaleFromParam(cookie.getValue());
- }
- }
- }
- return null;
- }
-
- protected Locale readStoredLocaleFromCurrentInvocation(ActionInvocation invocation) {
- // no overriding locale definition found, stay with current invocation (=browser) locale
- Locale locale = invocation.getInvocationContext().getLocale();
- if (locale != null) {
- LOG.debug("Applied invocation context locale: {}", locale);
- }
- return locale;
- }
-
- protected Parameter findLocaleParameter(HttpParameters params, String parameterName) {
+ protected Parameter findLocaleParameter(ActionInvocation invocation, String parameterName) {
+ HttpParameters params = invocation.getInvocationContext().getParameters();
Parameter requestedLocale = params.get(parameterName);
params.remove(parameterName);
if (requestedLocale.isDefined()) {
@@ -347,75 +249,182 @@ public class I18nInterceptor extends AbstractInterceptor {
invocation.getInvocationContext().setLocale(locale);
}
- protected class RequestOnlyLocaleFinder {
+ /**
+ * Uses to handle reading/storing Locale from/in different locations
+ */
+ protected interface LocaleHandler {
+ Locale find();
+ Locale read(ActionInvocation invocation);
+ Locale store(ActionInvocation invocation, Locale locale);
+ boolean shouldStore();
+ }
+
+ protected class RequestOnlyLocaleHandler implements LocaleHandler {
protected ActionInvocation actionInvocation = null;
+ protected boolean shouldStore = true;
- protected RequestOnlyLocaleFinder(ActionInvocation invocation) {
+ protected RequestOnlyLocaleHandler(ActionInvocation invocation) {
actionInvocation = invocation;
}
- public String find() {
- HttpParameters params = actionInvocation.getInvocationContext().getParameters();
+ public Locale find() {
+ LOG.debug("Searching locale in request under parameter {}", requestOnlyParameterName);
- Parameter requestedLocale = findLocaleParameter(params, requestOnlyParameterName);
+ Parameter requestedLocale = findLocaleParameter(actionInvocation, requestOnlyParameterName);
if (requestedLocale.isDefined()) {
- storage = Storage.NONE;
- return requestedLocale.getValue();
+ return getLocaleFromParam(requestedLocale.getValue());
}
return null;
}
+
+ @Override
+ public Locale store(ActionInvocation invocation, Locale locale) {
+ return locale;
+ }
+
+ @Override
+ public Locale read(ActionInvocation invocation) {
+ LOG.debug("Searching current Invocation context");
+ // no overriding locale definition found, stay with current invocation (=browser) locale
+ Locale locale = invocation.getInvocationContext().getLocale();
+ if (locale != null) {
+ LOG.debug("Applied invocation context locale: {}", locale);
+ }
+ return locale;
+ }
+
+ @Override
+ public boolean shouldStore() {
+ return shouldStore;
+ }
}
- protected class SessionLocaleFinder extends RequestOnlyLocaleFinder {
+ protected class SessionLocaleHandler extends RequestOnlyLocaleHandler {
- protected SessionLocaleFinder(ActionInvocation invocation) {
+ protected SessionLocaleHandler(ActionInvocation invocation) {
super(invocation);
}
- public String find() {
- String requestOnlyLocale = super.find();
+ public Locale find() {
+ Locale requestOnlyLocale = super.find();
if (requestOnlyLocale != null) {
+ LOG.debug("Found locale under request only param, it won't be stored in session!");
+ shouldStore = false;
return requestOnlyLocale;
}
- HttpParameters params = actionInvocation.getInvocationContext().getParameters();
-
- Parameter requestedLocale = findLocaleParameter(params, parameterName);
+ LOG.debug("Searching locale in request under parameter {}", parameterName);
+ Parameter requestedLocale = findLocaleParameter(actionInvocation, parameterName);
if (requestedLocale.isDefined()) {
- return requestedLocale.getValue();
+ return getLocaleFromParam(requestedLocale.getValue());
}
- return requestedLocale.getValue();
+ return null;
}
+ @Override
+ public Locale store(ActionInvocation invocation, Locale locale) {
+ //save it in session
+ Map session = invocation.getInvocationContext().getSession();
+
+ if (session != null) {
+ String sessionId = ServletActionContext.getRequest().getSession().getId();
+ synchronized (sessionId.intern()) {
+ session.put(attributeName, locale);
+ }
+ }
+ return locale;
+ }
+
+ @Override
+ public Locale read(ActionInvocation invocation) {
+ Locale locale = null;
+
+ LOG.debug("Checks session for saved locale");
+ Map session = invocation.getInvocationContext().getSession();
+
+ if (session != null) {
+ String sessionId = ServletActionContext.getRequest().getSession().getId();
+ synchronized (sessionId.intern()) {
+ Object sessionLocale = session.get(attributeName);
+ if (sessionLocale != null && sessionLocale instanceof Locale) {
+ locale = (Locale) sessionLocale;
+ LOG.debug("Applied session locale: {}", locale);
+ }
+ }
+ }
+
+ if (locale == null) {
+ LOG.debug("No Locale defined in session, fetching from current request and it won't be stored in session!");
+ shouldStore = false;
+ locale = super.read(invocation);
+ } else {
+ LOG.debug("Found stored Locale {} in session, using it!", locale);
+ }
+
+ return locale;
+ }
}
- protected class CookieLocaleFinder extends RequestOnlyLocaleFinder {
- protected CookieLocaleFinder(ActionInvocation invocation) {
+ protected class CookieLocaleHandler extends RequestOnlyLocaleHandler {
+ protected CookieLocaleHandler(ActionInvocation invocation) {
super(invocation);
}
@Override
- public String find() {
- String requestOnlySessionLocale = super.find();
+ public Locale find() {
+ Locale requestOnlySessionLocale = super.find();
if (requestOnlySessionLocale != null) {
+ shouldStore = false;
return requestOnlySessionLocale;
}
- HttpParameters params = actionInvocation.getInvocationContext().getParameters();
-
- Parameter requestedLocale = findLocaleParameter(params, requestCookieParameterName);
+ LOG.debug("Searching locale in request under parameter {}", requestCookieParameterName);
+ Parameter requestedLocale = findLocaleParameter(actionInvocation, requestCookieParameterName);
if (requestedLocale.isDefined()) {
- storage = Storage.COOKIE;
- return requestedLocale.getValue();
+ return getLocaleFromParam(requestedLocale.getValue());
}
return null;
}
+
+ @Override
+ public Locale store(ActionInvocation invocation, Locale locale) {
+ HttpServletResponse response = ServletActionContext.getResponse();
+
+ Cookie cookie = new Cookie(attributeName, locale.toString());
+ cookie.setMaxAge(1209600); // two weeks
+ response.addCookie(cookie);
+
+ return locale;
+ }
+
+ @Override
+ public Locale read(ActionInvocation invocation) {
+ Locale locale = null;
+
+ Cookie[] cookies = ServletActionContext.getRequest().getCookies();
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if (attributeName.equals(cookie.getName())) {
+ locale = getLocaleFromParam(cookie.getValue());
+ }
+ }
+ }
+
+ if (locale == null) {
+ LOG.debug("No Locale defined in cookie, fetching from current request and it won't be stored!");
+ shouldStore = false;
+ locale = super.read(invocation);
+ } else {
+ LOG.debug("Found stored Locale {} in cookie, using it!", locale);
+ }
+ return locale;
+ }
}
}