Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public class I18nInterceptor extends AbstractInterceptor {

private Set<Locale> supportedLocale = Collections.emptySet();

protected enum Storage { COOKIE, SESSION, REQUEST, ACCEPT_LANGUAGE }
protected enum Storage {COOKIE, SESSION, REQUEST, ACCEPT_LANGUAGE}

public void setParameterName(String parameterName) {
this.parameterName = parameterName;
Expand Down Expand Up @@ -103,10 +103,14 @@ public void setLocaleStorage(String storageName) {
*/
public void setSupportedLocale(String supportedLocale) {
this.supportedLocale = TextParseUtil
.commaDelimitedStringToSet(supportedLocale)
.stream()
.map(Locale::new)
.collect(Collectors.toSet());
.commaDelimitedStringToSet(supportedLocale)
.stream()
.map(Locale::new)
.collect(Collectors.toSet());
}

protected boolean isLocaleSupported(Locale locale) {
return supportedLocale.isEmpty() || supportedLocale.contains(locale);
}

@Inject
Expand Down Expand Up @@ -222,8 +226,11 @@ protected void useLocale(ActionInvocation invocation, Locale locale) {
*/
protected interface LocaleHandler {
Locale find();

Locale read(ActionInvocation invocation);

Locale store(ActionInvocation invocation, Locale locale);

boolean shouldStore();
}

Expand All @@ -241,7 +248,10 @@ public Locale find() {

Parameter requestedLocale = findLocaleParameter(actionInvocation, requestOnlyParameterName);
if (requestedLocale.isDefined()) {
return getLocaleFromParam(requestedLocale.getValue());
Locale locale = getLocaleFromParam(requestedLocale.getValue());
if (locale != null && isLocaleSupported(locale)) {
return locale;
}
}

return null;
Expand Down Expand Up @@ -278,6 +288,11 @@ protected AcceptLanguageLocaleHandler(ActionInvocation invocation) {
@Override
@SuppressWarnings("rawtypes")
public Locale find() {
Locale requestOnlyLocale = super.find();
if (requestOnlyLocale != null) {
return requestOnlyLocale;
}

if (!supportedLocale.isEmpty()) {
Enumeration locales = actionInvocation.getInvocationContext().getServletRequest().getLocales();
while (locales.hasMoreElements()) {
Expand All @@ -287,7 +302,7 @@ public Locale find() {
}
}
}
return super.find();
return null;
}

}
Expand All @@ -300,20 +315,20 @@ protected SessionLocaleHandler(ActionInvocation invocation) {

@Override
public Locale find() {
Locale requestOnlyLocale = super.find();
Parameter requestedLocale = findLocaleParameter(actionInvocation, parameterName);
if (requestedLocale.isDefined()) {
Locale locale = getLocaleFromParam(requestedLocale.getValue());
if (locale != null && isLocaleSupported(locale)) {
return locale;
}
}

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;
}

LOG.debug("Searching locale in request under parameter {}", parameterName);
Parameter requestedLocale = findLocaleParameter(actionInvocation, parameterName);
if (requestedLocale.isDefined()) {
return getLocaleFromParam(requestedLocale.getValue());
}

return null;
}

Expand Down Expand Up @@ -344,7 +359,12 @@ public Locale read(ActionInvocation invocation) {
Object sessionLocale = invocation.getInvocationContext().getSession().get(attributeName);
if (sessionLocale instanceof Locale) {
locale = (Locale) sessionLocale;
LOG.debug("Applied session locale: {}", locale);
if (!isLocaleSupported(locale)) {
LOG.debug("Stored session locale {} is not supported, discarding", locale);
locale = null;
} else {
LOG.debug("Applied session locale: {}", locale);
}
}
}
}
Expand All @@ -368,17 +388,18 @@ protected CookieLocaleHandler(ActionInvocation invocation) {

@Override
public Locale find() {
Locale requestOnlySessionLocale = super.find();

if (requestOnlySessionLocale != null) {
shouldStore = false;
return requestOnlySessionLocale;
}

LOG.debug("Searching locale in request under parameter {}", requestCookieParameterName);
Parameter requestedLocale = findLocaleParameter(actionInvocation, requestCookieParameterName);
if (requestedLocale.isDefined()) {
return getLocaleFromParam(requestedLocale.getValue());
Locale locale = getLocaleFromParam(requestedLocale.getValue());
if (locale != null && isLocaleSupported(locale)) {
return locale;
}
}

Locale requestOnlyLocale = super.find();
if (requestOnlyLocale != null) {
shouldStore = false;
return requestOnlyLocale;
}

return null;
Expand All @@ -404,6 +425,10 @@ public Locale read(ActionInvocation invocation) {
for (Cookie cookie : cookies) {
if (attributeName.equals(cookie.getName())) {
locale = getLocaleFromParam(cookie.getValue());
if (locale != null && !isLocaleSupported(locale)) {
LOG.debug("Stored cookie locale {} is not supported, discarding", locale);
locale = null;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@
}

public void testRealLocalesInParams() throws Exception {
Locale[] locales = new Locale[] { Locale.CANADA_FRENCH };
Locale[] locales = new Locale[]{Locale.CANADA_FRENCH};
assertTrue(locales.getClass().isArray());
prepare(I18nInterceptor.DEFAULT_PARAMETER, locales);
interceptor.intercept(mai);
Expand Down Expand Up @@ -294,6 +294,66 @@
assertEquals(Locale.US, mai.getInvocationContext().getLocale());
}

public void testRequestLocaleWithSupportedLocale() throws Exception {
// given
interceptor.setSupportedLocale("en,de");
prepare(I18nInterceptor.DEFAULT_PARAMETER, "de");

// when
interceptor.intercept(mai);

// then
Locale german = new Locale("de");
assertEquals(german, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE));
assertEquals(german, mai.getInvocationContext().getLocale());
}

public void testUnsupportedRequestLocaleRejected() throws Exception {
// given
interceptor.setSupportedLocale("en,de");
prepare(I18nInterceptor.DEFAULT_PARAMETER, "fr");

// when
interceptor.intercept(mai);

// then - fr is not supported, should fall back to default
assertNull("unsupported locale should not be stored", session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE));
}

public void testStaleSessionLocaleRejected() throws Exception {
// given - session has a stored locale that is no longer supported
session.put(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE, Locale.FRENCH);
interceptor.setSupportedLocale("en,de");

// when
interceptor.intercept(mai);

// then - stored fr locale should be discarded since it's not in supportedLocale
assertFalse("stale session locale should be discarded",
Locale.FRENCH.equals(mai.getInvocationContext().getLocale()));
}

public void testCookieRequestLocaleWithSupportedLocale() throws Exception {
// given
interceptor.setSupportedLocale("en,de");
interceptor.setLocaleStorage(I18nInterceptor.Storage.COOKIE.name());
prepare(I18nInterceptor.DEFAULT_COOKIE_PARAMETER, "de");

final Cookie cookie = new Cookie(I18nInterceptor.DEFAULT_COOKIE_ATTRIBUTE, "de");
HttpServletResponse response = EasyMock.createMock(HttpServletResponse.class);
response.addCookie(CookieMatcher.eqCookie(cookie));
EasyMock.replay(response);
ac.put(StrutsStatics.HTTP_RESPONSE, response);

// when
interceptor.intercept(mai);

// then
EasyMock.verify(response);
Locale german = new Locale("de");
assertEquals(german, mai.getInvocationContext().getLocale());
}

private void prepare(String key, Serializable value) {
Map<String, Serializable> params = new HashMap<>();
params.put(key, value);
Expand All @@ -308,9 +368,9 @@
session = new HashMap<>();

ac = ActionContext.of()
.bind()
.withSession(session)
.withParameters(HttpParameters.create().build());
.bind()
.withSession(session)
.withParameters(HttpParameters.create().build());

request = new MockHttpServletRequest();
request.setSession(new MockHttpSession());
Expand Down Expand Up @@ -348,8 +408,8 @@
public boolean matches(Object argument) {
Cookie cookie = ((Cookie) argument);
return
(cookie.getName().equals(expected.getName()) &&
cookie.getValue().equals(expected.getValue()));
(cookie.getName().equals(expected.getName()) &&
cookie.getValue().equals(expected.getValue()));
}

public static Cookie eqCookie(Cookie ck) {
Expand All @@ -359,10 +419,10 @@

public void appendTo(StringBuffer buffer) {
buffer
.append("Received")
.append(expected.getName())
.append("/")
.append(expected.getValue());
.append("Received")
.append(expected.getName())
.append("/")
.append(expected.getValue());
}
}

Expand Down