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 @@ -108,6 +108,10 @@ public void setSupportedLocale(String supportedLocale) {
.collect(Collectors.toSet());
}

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

@Inject
public void setLocaleProviderFactory(LocaleProviderFactory localeProviderFactory) {
this.localeProviderFactory = localeProviderFactory;
Expand Down Expand Up @@ -277,16 +281,21 @@ protected AcceptLanguageLocaleHandler(ActionInvocation invocation) {
@Override
@SuppressWarnings("rawtypes")
public Locale find() {
Locale locale = super.find();
if (locale != null) {
return locale;
}

if (!supportedLocale.isEmpty()) {
Enumeration locales = actionInvocation.getInvocationContext().getServletRequest().getLocales();
while (locales.hasMoreElements()) {
Locale locale = (Locale) locales.nextElement();
if (supportedLocale.contains(locale)) {
return locale;
Locale acceptLocale = (Locale) locales.nextElement();
if (supportedLocale.contains(acceptLocale)) {
return acceptLocale;
}
}
}
return super.find();
return null;
}

}
Expand All @@ -299,20 +308,23 @@ protected SessionLocaleHandler(ActionInvocation invocation) {

@Override
public Locale find() {
Locale requestOnlyLocale = super.find();
LOG.debug("Searching locale in request under parameter {}", parameterName);
Parameter requestedLocale = findLocaleParameter(actionInvocation, parameterName);
if (requestedLocale.isDefined()) {
Locale locale = getLocaleFromParam(requestedLocale.getValue());
if (locale != null && isLocaleSupported(locale)) {
return locale;
}
LOG.debug("Requested locale {} is not supported, ignoring", requestedLocale.getValue());
}

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 @@ -348,6 +360,11 @@ public Locale read(ActionInvocation invocation) {
}
}

if (locale != null && !isLocaleSupported(locale)) {
LOG.debug("Stored session locale {} is not in supportedLocale, ignoring", locale);
locale = null;
}

if (locale == null) {
LOG.debug("No Locale defined in session, fetching from current request and it won't be stored in session!");
shouldStore = false;
Expand All @@ -367,19 +384,22 @@ protected CookieLocaleHandler(ActionInvocation invocation) {

@Override
public Locale find() {
Locale requestOnlySessionLocale = super.find();
LOG.debug("Searching locale in request under parameter {}", requestCookieParameterName);
Parameter requestedLocale = findLocaleParameter(actionInvocation, requestCookieParameterName);
if (requestedLocale.isDefined()) {
Locale locale = getLocaleFromParam(requestedLocale.getValue());
if (locale != null && isLocaleSupported(locale)) {
return locale;
}
LOG.debug("Requested cookie locale {} is not supported, ignoring", requestedLocale.getValue());
}

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

return null;
}

Expand Down Expand Up @@ -407,6 +427,11 @@ public Locale read(ActionInvocation invocation) {
}
}

if (locale != null && !isLocaleSupported(locale)) {
LOG.debug("Stored cookie locale {} is not in supportedLocale, ignoring", locale);
locale = null;
}

if (locale == null) {
LOG.debug("No Locale defined in cookie, fetching from current request and it won't be stored!");
shouldStore = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -205,7 +206,7 @@ public void testRealLocaleObjectInParams() throws Exception {
}

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 @@ -278,6 +279,69 @@ public void testAcceptLanguageBasedLocale() throws Exception {
assertEquals(new Locale("pl"), mai.getInvocationContext().getLocale());
}

public void testSupportedLocaleWithRequestLocale() throws Exception {
// given - supportedLocale configured + request_locale param with SESSION storage
request.setPreferredLocales(Arrays.asList(new Locale("en")));
interceptor.setSupportedLocale("en,fr");
prepare(I18nInterceptor.DEFAULT_PARAMETER, "fr");

// when
interceptor.intercept(mai);

// then - request_locale wins over Accept-Language
assertEquals(new Locale("fr"), session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE));
assertEquals(new Locale("fr"), mai.getInvocationContext().getLocale());
}

public void testSupportedLocaleRejectsUnsupportedRequestLocale() throws Exception {
// given - request_locale=es but supportedLocale="en,fr"
request.setPreferredLocales(Arrays.asList(new Locale("en")));
interceptor.setSupportedLocale("en,fr");
prepare(I18nInterceptor.DEFAULT_PARAMETER, "es");

// when
interceptor.intercept(mai);

// then - es rejected, falls back to Accept-Language match (en)
assertNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE));
assertEquals(new Locale("en"), mai.getInvocationContext().getLocale());
}

public void testSupportedLocaleRevalidatesSessionLocale() throws Exception {
// given - session has stored locale "de" but supportedLocale changed to "en,fr"
session.put(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE, new Locale("de"));
request.setPreferredLocales(Arrays.asList(new Locale("fr")));
interceptor.setSupportedLocale("en,fr");

// when
interceptor.intercept(mai);

// then - stored "de" rejected, falls back to Accept-Language match (fr)
assertEquals(new Locale("fr"), mai.getInvocationContext().getLocale());
}

public void testSupportedLocaleWithCookieStorage() throws Exception {
// given - supportedLocale configured + request_cookie_locale param with COOKIE storage
prepare(I18nInterceptor.DEFAULT_COOKIE_PARAMETER, "fr");
request.setPreferredLocales(Arrays.asList(new Locale("en")));
interceptor.setSupportedLocale("en,fr");

final Cookie cookie = new Cookie(I18nInterceptor.DEFAULT_COOKIE_ATTRIBUTE, "fr");
HttpServletResponse response = EasyMock.createMock(HttpServletResponse.class);
response.addCookie(CookieMatcher.eqCookie(cookie));
EasyMock.replay(response);

ac.put(StrutsStatics.HTTP_RESPONSE, response);
interceptor.setLocaleStorage(I18nInterceptor.Storage.COOKIE.name());

// when
interceptor.intercept(mai);

// then - request_cookie_locale=fr wins
EasyMock.verify(response);
assertEquals(new Locale("fr"), mai.getInvocationContext().getLocale());
}

public void testAcceptLanguageBasedLocaleWithFallbackToDefault() throws Exception {
// given
request.setPreferredLocales(Arrays.asList(new Locale("da_DK"), new Locale("es")));
Expand Down Expand Up @@ -308,9 +372,9 @@ public void setUp() throws Exception {
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 +412,8 @@ static class CookieMatcher implements IArgumentMatcher {
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 +423,10 @@ public static Cookie eqCookie(Cookie ck) {

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
Loading
Loading