WW-4677 Exyends LocaleProvider to be used to validate Locale

This commit is contained in:
Lukasz Lenart
2016-09-19 09:45:16 +02:00
parent c570a2b2bd
commit ea92e95461
19 changed files with 146 additions and 36 deletions
@@ -63,14 +63,19 @@ public class ActionSupport implements Action, Validateable, ValidationAware, Tex
return validationAware.getFieldErrors();
}
@Override
public Locale getLocale() {
ActionContext ctx = ActionContext.getContext();
if (ctx != null) {
return ctx.getLocale();
} else {
LOG.debug("Action context not initialized");
return null;
}
return container.getInstance(LocaleProvider.class).getLocale();
}
@Override
public boolean isValidLocaleString(String localeStr) {
return container.getInstance(LocaleProvider.class).isValidLocaleString(localeStr);
}
@Override
public boolean isValidLocale(Locale locale) {
return container.getInstance(LocaleProvider.class).isValidLocale(locale);
}
public boolean hasKey(String key) {
@@ -1,8 +1,10 @@
package com.opensymphony.xwork2;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;
import java.util.Locale;
/**
@@ -22,4 +24,13 @@ public class DefaultLocaleProvider implements LocaleProvider {
}
}
@Override
public boolean isValidLocaleString(String localeStr) {
return isValidLocale(LocalizedTextUtil.localeFromString(localeStr, getLocale()));
}
@Override
public boolean isValidLocale(Locale locale) {
return locale != null && Arrays.asList(Locale.getAvailableLocales()).contains(locale);
}
}
@@ -39,4 +39,20 @@ public interface LocaleProvider {
*/
Locale getLocale();
/**
* Validates if provided string is a valid {@link Locale}
*
* @param localeStr a String representing locale, e.g. en_EN
* @return true if valid
*/
boolean isValidLocaleString(String localeStr);
/**
* Validates if provided {@link Locale} is value
*
* @param locale instance of {@link Locale} to validate
* @return true if valid
*/
boolean isValidLocale(Locale locale);
}
@@ -107,6 +107,16 @@ public class DelegatingValidatorContext implements ValidatorContext {
return localeProvider.getLocale();
}
@Override
public boolean isValidLocaleString(String localeStr) {
return localeProvider.isValidLocaleString(localeStr);
}
@Override
public boolean isValidLocale(Locale locale) {
return localeProvider.isValidLocale(locale);
}
public boolean hasKey(String key) {
return textProvider.hasKey(key);
}
@@ -257,7 +267,17 @@ public class DelegatingValidatorContext implements ValidatorContext {
*/
private static class ActionContextLocaleProvider implements LocaleProvider {
public Locale getLocale() {
return ActionContext.getContext().getLocale();
return ActionContext.getContext().getInstance(LocaleProvider.class).getLocale();
}
@Override
public boolean isValidLocaleString(String localeStr) {
return ActionContext.getContext().getInstance(LocaleProvider.class).isValidLocaleString(localeStr);
}
@Override
public boolean isValidLocale(Locale locale) {
return ActionContext.getContext().getInstance(LocaleProvider.class).isValidLocale(locale);
}
}
@@ -22,6 +22,8 @@ package org.apache.struts2.interceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import org.apache.logging.log4j.LogManager;
@@ -102,6 +104,8 @@ public class I18nInterceptor extends AbstractInterceptor {
protected String requestOnlyParameterName = DEFAULT_REQUESTONLY_PARAMETER;
protected String attributeName = DEFAULT_SESSION_ATTRIBUTE;
protected LocaleProvider localeProvider;
// Request-Only = None
protected enum Storage { COOKIE, SESSION, NONE }
@@ -123,6 +127,11 @@ public class I18nInterceptor extends AbstractInterceptor {
this.attributeName = attributeName;
}
@Inject
public void setLocaleProvider(LocaleProvider localeProvider) {
this.localeProvider = localeProvider;
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
if (LOG.isDebugEnabled()) {
@@ -225,17 +234,25 @@ public class I18nInterceptor extends AbstractInterceptor {
protected Locale getLocaleFromParam(Object requestedLocale) {
Locale locale = null;
if (requestedLocale != null) {
locale = (requestedLocale instanceof Locale) ?
(Locale) requestedLocale :
LocalizedTextUtil.localeFromString(requestedLocale.toString(), null);
if (requestedLocale instanceof Locale) {
locale = (Locale) requestedLocale;
} else {
String localeStr = requestedLocale.toString();
if (localeProvider.isValidLocaleString(localeStr)) {
locale = LocalizedTextUtil.localeFromString(requestedLocale.toString(), null);
}
}
if (locale != null) {
LOG.debug("Applied request locale: {}", locale);
}
}
if (locale != null && !Arrays.asList(Locale.getAvailableLocales()).contains(locale)) {
locale = Locale.getDefault();
if (!localeProvider.isValidLocale(locale)) {
Locale defaultLocale = localeProvider.getLocale();
LOG.debug("Provided locale {} isn't valid, fallback to default locale", locale, defaultLocale);
locale = defaultLocale;
}
return locale;
}
@@ -27,11 +27,18 @@ import java.util.*;
public class ActionSupportTest extends XWorkTestCase {
private ActionSupport as;
private MyActionSupport mas;
@Override
protected void setUp() throws Exception {
super.setUp();
as = new ActionSupport();
container.inject(as);
ActionContext.getContext().setLocale(new Locale("da"));
mas = new MyActionSupport();
container.inject(mas);
}
@Override
@@ -153,9 +160,6 @@ public class ActionSupportTest extends XWorkTestCase {
}
public void testMyActionSupport() throws Exception {
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
assertEquals("santa", mas.execute());
assertNotNull(mas.getTexts());
@@ -165,9 +169,6 @@ public class ActionSupportTest extends XWorkTestCase {
}
public void testSimpleGetTexts() throws Exception {
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
checkGetTexts(mas);
}
@@ -199,9 +200,6 @@ public class ActionSupportTest extends XWorkTestCase {
}
public void testGetTextsWithArgs() throws Exception {
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
assertEquals("Hello World", mas.getText("hello", "this is default", "from me")); // no args in bundle
assertEquals("Hello World from me", mas.getText("hello.0", "this is default", "from me"));
assertEquals("this is default", mas.getText("not.in.bundle", "this is default", "from me"));
@@ -211,9 +209,6 @@ public class ActionSupportTest extends XWorkTestCase {
}
public void testGetTextsWithListArgs() throws Exception {
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
List<Object> args = new ArrayList<>();
args.add("Santa");
args.add("loud");
@@ -236,9 +231,6 @@ public class ActionSupportTest extends XWorkTestCase {
}
public void testGetTextsWithArrayArgs() throws Exception {
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
String[] args = {"Santa", "loud"};
assertEquals("Hello World", mas.getText("hello", "this is default", args)); // no args in bundle
assertEquals("Hello World Santa", mas.getText("hello.0", "this is default", args)); // only 1 arg in bundle
@@ -293,16 +285,11 @@ public class ActionSupportTest extends XWorkTestCase {
}
public void testGetBundle() throws Exception {
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
ResourceBundle rb = ResourceBundle.getBundle(MyActionSupport.class.getName(), new Locale("da"));
assertEquals(rb, mas.getTexts(MyActionSupport.class.getName()));
}
public void testFormattingSupport() throws Exception {
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
ActionContext.getContext().getValueStack().push(mas);
mas.setVal(234d);
@@ -316,6 +303,7 @@ public class ActionSupportTest extends XWorkTestCase {
ActionContext.getContext().getConversionErrors().put("val", new String[]{"4567def"});
ActionContext.getContext().setLocale(new Locale("da"));
MyActionSupport mas = new MyActionSupport();
container.inject(mas);
ActionContext.getContext().getValueStack().push(mas);
mas.setVal(234d);
@@ -82,12 +82,32 @@ public class CompositeTextProviderTest extends XWorkTestCase {
public Locale getLocale() {
return Locale.ENGLISH;
}
@Override
public boolean isValidLocaleString(String localeStr) {
return true;
}
@Override
public boolean isValidLocale(Locale locale) {
return true;
}
}),
new TextProviderSupport(ResourceBundle.getBundle("com.opensymphony.xwork2.validator.CompositeTextProviderTestResourceBundle2"),
new LocaleProvider() {
public Locale getLocale() {
return Locale.ENGLISH;
}
@Override
public boolean isValidLocaleString(String localeStr) {
return true;
}
@Override
public boolean isValidLocale(Locale locale) {
return true;
}
})
});
@@ -112,6 +112,16 @@ public class TextProviderSupportTest extends XWorkTestCase {
public Locale getLocale() {
return Locale.ENGLISH;
}
@Override
public boolean isValidLocaleString(String localeStr) {
return true;
}
@Override
public boolean isValidLocale(Locale locale) {
return true;
}
});
}
@@ -159,6 +159,8 @@ public class AnnotationXWorkConverterTest extends XWorkTestCase {
public void testFindConversionErrorMessage() {
ModelDrivenAnnotationAction action = new ModelDrivenAnnotationAction();
container.inject(action);
ValueStack stack = ActionContext.getContext().getValueStack();
stack.push(action);
stack.push(action.getModel());
@@ -200,6 +200,8 @@ public class XWorkConverterTest extends XWorkTestCase {
public void testFindConversionErrorMessage() {
ModelDrivenAction action = new ModelDrivenAction();
container.inject(action);
stack.push(action);
stack.push(action.getModel());
@@ -54,6 +54,7 @@ public class LocalizedTextUtilTest extends XWorkTestCase {
public void testActionGetTextWithNullObject() throws Exception {
MyAction action = new MyAction();
container.inject(action);
Mock mockActionInvocation = new Mock(ActionInvocation.class);
mockActionInvocation.expectAndReturn("getAction", action);
@@ -78,6 +79,8 @@ public class LocalizedTextUtilTest extends XWorkTestCase {
public void testActionGetText() throws Exception {
ModelDrivenAction2 action = new ModelDrivenAction2();
container.inject(action);
TestBean2 bean = (TestBean2) action.getModel();
Bar bar = new Bar();
bean.setBarObj(bar);
@@ -100,6 +103,7 @@ public class LocalizedTextUtilTest extends XWorkTestCase {
LocalizedTextUtil.addDefaultResourceBundle("com/opensymphony/xwork2/util/FindMe");
SimpleAction action = new SimpleAction();
container.inject(action);
Mock mockActionInvocation = new Mock(ActionInvocation.class);
mockActionInvocation.expectAndReturn("getAction", action);
@@ -150,7 +150,10 @@ public class SimpleActionValidationTest extends XWorkTestCase {
String messageKey = "does.not.exist";
validator.setMessageKey(messageKey);
ValidatorContext validatorContext = new DelegatingValidatorContext(new SimpleAction());
SimpleAction action = new SimpleAction();
container.inject(action);
ValidatorContext validatorContext = new DelegatingValidatorContext(action);
validator.setValidatorContext(validatorContext);
validator.validate(this);
assertTrue(validatorContext.hasActionErrors());
@@ -154,6 +154,8 @@ public class StringLengthFieldValidatorTest extends XWorkTestCase {
super.setUp();
action = new InternalActionSupport();
container.inject(action);
ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.push(action);
@@ -36,6 +36,7 @@ public class VisitorFieldValidatorTest extends XWorkTestCase {
super.setUp();
action = new VisitorValidatorTestAction();
container.inject(action);
TestBean bean = action.getBean();
Calendar cal = new GregorianCalendar(1900, 01, 01);
@@ -307,6 +307,7 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
assertTrue(ServletFileUpload.isMultipartContent(req));
MyFileupAction action = new MyFileupAction();
container.inject(action);
MockActionInvocation mai = new MockActionInvocation();
mai.setAction(action);
mai.setResultCode("success");
@@ -363,6 +364,8 @@ public class FileUploadInterceptorTest extends StrutsInternalTestCase {
protected void setUp() throws Exception {
super.setUp();
action = new TestAction();
container.inject(action);
interceptor = new FileUploadInterceptor();
container.inject(interceptor);
tempDir = File.createTempFile("struts", "fileupload");
@@ -23,6 +23,7 @@ package org.apache.struts2.interceptor;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.DefaultLocaleProvider;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import junit.framework.TestCase;
import org.apache.struts2.ServletActionContext;
@@ -181,8 +182,7 @@ public class I18nInterceptorTest extends TestCase {
interceptor.intercept(mai);
Locale locale = (Locale) session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE);
assertNull(locale); // should not be stored here
locale = mai.getInvocationContext().getLocale();
assertNotNull(locale);
assertEquals(locale1, locale);
}
@@ -195,6 +195,7 @@ public class I18nInterceptorTest extends TestCase {
public void setUp() throws Exception {
interceptor = new I18nInterceptor();
interceptor.setLocaleProvider(new DefaultLocaleProvider());
interceptor.init();
session = new HashMap();
@@ -86,6 +86,8 @@ public abstract class AbstractTagTest extends StrutsInternalTestCase {
protected void createMocks() throws Exception {
action = this.getAction();
container.inject(action);
stack = ActionContext.getContext().getValueStack();
context = stack.getContext();
stack.push(action);
@@ -227,6 +227,7 @@ public class TextTagTest extends AbstractTagTest {
ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack();
newStack.getContext().put(ActionContext.CONTAINER, container);
TestAction testAction = new TestAction();
container.inject(testAction);
testAction.setResult("bar");
newStack.push(testAction);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack);
@@ -247,6 +248,7 @@ public class TextTagTest extends AbstractTagTest {
ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack();
newStack.getContext().put(ActionContext.CONTAINER, container);
TestAction testAction = new TestAction();
container.inject(testAction);
testAction.setResult("bar");
newStack.push(testAction);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack);
@@ -227,6 +227,7 @@ public class OptGroupTest extends AbstractUITagTest {
selectTag.setListValueKey("valueKey");
LocaleTestAction localeTestAction = new LocaleTestAction();
container.inject(localeTestAction);
localeTestAction.setText("LocaleKeyValueTest.ONE","Edno");
localeTestAction.setText("LocaleKeyValueTest.TWO","Dve");