struts-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lukaszlen...@apache.org
Subject [18/57] [partial] struts git commit: Merges xwork packages into struts
Date Wed, 17 Jun 2015 21:09:18 GMT
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java
new file mode 100644
index 0000000..3c64622
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationActionValidatorManagerTest.java
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator;
+
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.AnnotatedTestBean;
+import com.opensymphony.xwork2.FileManager;
+import com.opensymphony.xwork2.FileManagerFactory;
+import com.opensymphony.xwork2.SimpleAction;
+import com.opensymphony.xwork2.SimpleAnnotationAction;
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.test.AnnotationDataAware2;
+import com.opensymphony.xwork2.test.AnnotationUser;
+import com.opensymphony.xwork2.test.SimpleAnnotationAction2;
+import com.opensymphony.xwork2.test.SimpleAnnotationAction3;
+import com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator;
+import com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator;
+import com.opensymphony.xwork2.validator.validators.EmailValidator;
+import com.opensymphony.xwork2.validator.validators.ExpressionValidator;
+import com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator;
+import com.opensymphony.xwork2.validator.validators.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.validators.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator;
+import com.opensymphony.xwork2.validator.validators.URLValidator;
+import org.easymock.EasyMock;
+
+import java.util.List;
+
+
+
+/**
+ * AnnotationActionValidatorManagerTest
+ *
+ * @author Rainer Hermanns
+ * @author Jason Carreira
+ * @author tm_jee ( tm_jee (at) yahoo.co.uk )
+ *         Created Jun 9, 2003 11:03:01 AM
+ */
+public class AnnotationActionValidatorManagerTest extends XWorkTestCase {
+
+    protected final String alias = "annotationValidationAlias";
+
+    AnnotationActionValidatorManager annotationActionValidatorManager;
+
+    @Override protected void setUp() throws Exception {
+        super.setUp();
+        annotationActionValidatorManager = (AnnotationActionValidatorManager) container.getInstance(ActionValidatorManager.class);
+
+        ActionConfig config = new ActionConfig.Builder("packageName", "name", "").build();
+        ActionInvocation invocation = EasyMock.createNiceMock(ActionInvocation.class);
+        ActionProxy proxy = EasyMock.createNiceMock(ActionProxy.class);
+
+        EasyMock.expect(invocation.getProxy()).andReturn(proxy).anyTimes();
+        EasyMock.expect(invocation.getAction()).andReturn(null).anyTimes();
+        EasyMock.expect(invocation.invoke()).andReturn(Action.SUCCESS).anyTimes();
+        EasyMock.expect(proxy.getMethod()).andReturn("execute").anyTimes();
+        EasyMock.expect(proxy.getConfig()).andReturn(config).anyTimes();
+
+
+        EasyMock.replay(invocation);
+        EasyMock.replay(proxy);
+
+        ActionContext.getContext().setActionInvocation(invocation);
+    }
+
+    @Override protected void tearDown() throws Exception {
+        annotationActionValidatorManager = null;
+        super.tearDown();
+    }
+
+    public void testBuildValidatorKey() {
+        String validatorKey = AnnotationActionValidatorManager.buildValidatorKey(SimpleAnnotationAction.class, "name");
+        assertEquals(SimpleAnnotationAction.class.getName() + "/packageName/name", validatorKey);
+    }
+
+    public void testBuildsValidatorsForAlias() {
+        List validatorList = annotationActionValidatorManager.getValidators(SimpleAnnotationAction.class, alias);
+
+        // 17 in the class level + 0 in the alias
+        // TODO: add alias tests
+        assertEquals(17, validatorList.size());
+    }
+
+    public void testGetValidatorsForGivenMethodNameWithoutReloading() throws ValidationException {
+        FileManager fileManager = container.getInstance(FileManagerFactory.class).getFileManager();
+        List validatorList = annotationActionValidatorManager.getValidators(SimpleAnnotationAction.class, alias, "execute");
+
+        //disable configuration reload/devmode
+        fileManager.setReloadingConfigs(false);
+
+        //17 in the class level + 0 in the alias
+        assertEquals(12, validatorList.size());
+        
+        validatorList = annotationActionValidatorManager.getValidators(SimpleAnnotationAction.class, alias, "execute");
+
+        //expect same number of validators
+        assertEquals(12, validatorList.size());
+    }
+    
+    public void testDefaultMessageInterpolation() {
+        // get validators
+        List validatorList = annotationActionValidatorManager.getValidators(AnnotatedTestBean.class, "beanMessageBundle");
+        assertEquals(3, validatorList.size());
+
+        try {
+            AnnotatedTestBean bean = new AnnotatedTestBean();
+            bean.setName("foo");
+            bean.setCount(99);
+
+            ValidatorContext context = new GenericValidatorContext(bean);
+            annotationActionValidatorManager.validate(bean, "beanMessageBundle", context);
+            assertTrue(context.hasErrors());
+            assertTrue(context.hasFieldErrors());
+
+            List<String> l = context.getFieldErrors().get("count");
+            assertNotNull(l);
+            assertEquals(1, l.size());
+            assertEquals("Smaller Invalid Count: 99", l.get(0));
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+
+    public void testGetValidatorsForInterface() {
+        List validatorList = annotationActionValidatorManager.getValidators(AnnotationDataAware2.class, alias);
+
+        // 1 in interface hierarchy, 2 from parent interface (1 default + 1 context)
+        assertEquals(3, validatorList.size());
+
+        final FieldValidator dataValidator1 = (FieldValidator) validatorList.get(0);
+        assertEquals("data", dataValidator1.getFieldName());
+        assertTrue(dataValidator1 instanceof RequiredFieldValidator);
+
+        final FieldValidator dataValidator2 = (FieldValidator) validatorList.get(1);
+        assertEquals("data", dataValidator2.getFieldName());
+        assertTrue(dataValidator2 instanceof RequiredStringValidator);
+
+        final FieldValidator blingValidator = (FieldValidator) validatorList.get(2);
+        assertEquals("bling", blingValidator.getFieldName());
+        assertTrue(blingValidator instanceof RequiredStringValidator);
+    }
+
+    public void no_testGetValidatorsFromInterface() {
+        List validatorList = annotationActionValidatorManager.getValidators(SimpleAnnotationAction3.class, alias);
+
+        // 17 in the class hierarchy + 1 in the interface + 1 in interface alias
+        assertEquals(19, validatorList.size());
+
+        final FieldValidator v = (FieldValidator) validatorList.get(0);
+        assertEquals("bar", v.getFieldName());
+        assertTrue(v instanceof RequiredFieldValidator);
+
+        final FieldValidator v1 = (FieldValidator) validatorList.get(1);
+        assertEquals("bar", v1.getFieldName());
+        assertTrue(v1 instanceof IntRangeFieldValidator);
+
+        final FieldValidator vdouble = (FieldValidator) validatorList.get(2);
+        assertEquals("percentage", vdouble.getFieldName());
+        assertTrue(vdouble instanceof DoubleRangeFieldValidator);
+
+        final FieldValidator v2 = (FieldValidator) validatorList.get(3);
+        assertEquals("baz", v2.getFieldName());
+        assertTrue(v2 instanceof IntRangeFieldValidator);
+
+        final FieldValidator v3 = (FieldValidator) validatorList.get(4);
+        assertEquals("date", v3.getFieldName());
+        assertTrue(v3 instanceof DateRangeFieldValidator);
+
+        // action-level validator comes first
+        final Validator v4 = (Validator) validatorList.get(5);
+        assertTrue(v4 instanceof ExpressionValidator);
+
+        // action-level validator comes first
+        final Validator v5 = (Validator) validatorList.get(6);
+        assertTrue(v5 instanceof ExpressionValidator);
+
+        // action-level validator comes first
+        final Validator v6 = (Validator) validatorList.get(7);
+        assertTrue(v6 instanceof ExpressionValidator);
+
+        // action-level validator comes first
+        final Validator v7 = (Validator) validatorList.get(8);
+        assertTrue(v7 instanceof ExpressionValidator);
+
+        // action-level validator comes first
+        final Validator v8 = (Validator) validatorList.get(9);
+        assertTrue(v8 instanceof ExpressionValidator);
+
+        final FieldValidator v9 = (FieldValidator) validatorList.get(10);
+        assertEquals("datefield", v9.getFieldName());
+        assertTrue(v9 instanceof DateRangeFieldValidator);
+
+        final FieldValidator v10 = (FieldValidator) validatorList.get(11);
+        assertEquals("emailaddress", v10.getFieldName());
+        assertTrue(v10 instanceof EmailValidator);
+
+        final FieldValidator v11 = (FieldValidator) validatorList.get(12);
+        assertEquals("intfield", v11.getFieldName());
+        assertTrue(v11 instanceof IntRangeFieldValidator);
+
+        final FieldValidator v12 = (FieldValidator) validatorList.get(13);
+        assertEquals("customfield", v12.getFieldName());
+        assertTrue(v12 instanceof RequiredFieldValidator);
+
+        final FieldValidator v13 = (FieldValidator) validatorList.get(14);
+        assertEquals("stringisrequired", v13.getFieldName());
+        assertTrue(v13 instanceof RequiredStringValidator);
+
+        final FieldValidator v14 = (FieldValidator) validatorList.get(15);
+        assertEquals("needstringlength", v14.getFieldName());
+        assertTrue(v14 instanceof StringLengthFieldValidator);
+
+        final FieldValidator v15 = (FieldValidator) validatorList.get(16);
+        assertEquals("hreflocation", v15.getFieldName());
+        assertTrue(v15 instanceof URLValidator);
+
+        final FieldValidator v16 = (FieldValidator) validatorList.get(17);
+        assertEquals("data", v16.getFieldName());
+        assertTrue(v16 instanceof RequiredFieldValidator);
+
+        final FieldValidator v17 = (FieldValidator) validatorList.get(18);
+        assertEquals("data", v17.getFieldName());
+        assertTrue(v17 instanceof RequiredStringValidator);
+
+    }
+
+    public void testMessageInterpolation() {
+        // get validators
+        List validatorList = annotationActionValidatorManager.getValidators(AnnotatedTestBean.class, "beanMessageBundle");
+        assertEquals(3, validatorList.size());
+
+        try {
+            AnnotatedTestBean bean = new AnnotatedTestBean();
+            bean.setName("foo");
+            bean.setCount(150);
+
+            ValidatorContext context = new GenericValidatorContext(bean);
+            annotationActionValidatorManager.validate(bean, "beanMessageBundle", context);
+            assertTrue(context.hasErrors());
+            assertTrue(context.hasFieldErrors());
+
+            List<String> l = context.getFieldErrors().get("count");
+            assertNotNull(l);
+            assertEquals(1, l.size());
+            assertEquals("Count must be between 1 and 100, current value is 150.", l.get(0));
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+
+    public void testSameAliasWithDifferentClass() {
+        List validatorList = annotationActionValidatorManager.getValidators(SimpleAnnotationAction.class, alias);
+        List validatorList2 = annotationActionValidatorManager.getValidators(SimpleAnnotationAction2.class, alias);
+        assertFalse(validatorList.size() == validatorList2.size());
+    }
+
+    public void testSameAliasWithAliasWithSlashes() {
+        List validatorList = annotationActionValidatorManager.getValidators(SimpleAction.class, "some/alias");
+        assertNotNull(validatorList);
+        assertEquals(11, validatorList.size());
+    }
+
+    public void testSkipUserMarkerActionLevelShortCircuit() {
+        // get validators
+        List validatorList = annotationActionValidatorManager.getValidators(AnnotationUser.class, null);
+        assertEquals(10, validatorList.size());
+
+        try {
+            AnnotationUser user = new AnnotationUser();
+            user.setName("Mark");
+            user.setEmail("bad_email");
+            user.setEmail2("bad_email");
+
+            ValidatorContext context = new GenericValidatorContext(user);
+            annotationActionValidatorManager.validate(user, null, context);
+            assertTrue(context.hasFieldErrors());
+
+            // check field errors
+            List<String> l = context.getFieldErrors().get("email");
+            assertNotNull(l);
+            assertEquals(1, l.size());
+            assertEquals("Not a valid e-mail.", l.get(0));
+            l = context.getFieldErrors().get("email2");
+            assertNotNull(l);
+            assertEquals(2, l.size());
+            assertEquals("Not a valid e-mail2.", l.get(0));
+            assertEquals("Email2 not from the right company.", l.get(1));
+
+            // check action errors
+            assertTrue(context.hasActionErrors());
+            l = (List<String>) context.getActionErrors();
+            assertNotNull(l);
+            assertEquals(2, l.size()); // both expression test failed see AnnotationUser-validation.xml
+            assertEquals("Email does not start with mark", l.get(0));
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+
+    public void testSkipAllActionLevelShortCircuit2() {
+        // get validators
+        List validatorList = annotationActionValidatorManager.getValidators(AnnotationUser.class, null);
+        assertEquals(10, validatorList.size());
+
+        try {
+            AnnotationUser user = new AnnotationUser();
+            user.setName("Mark");
+            // * mark both email to starts with mark to get pass the action-level validator,
+            // so we could concentrate on testing the field-level validators (AnnotationUser-validation.xml)
+            // * make both email the same to pass the action-level validator at 
+            // AnnotationUserMarker-validation.xml
+            user.setEmail("mark_bad_email_for_field_val@foo.com");
+            user.setEmail2("mark_bad_email_for_field_val@foo.com");
+
+            ValidatorContext context = new GenericValidatorContext(user);
+            annotationActionValidatorManager.validate(user, null, context);
+            assertTrue(context.hasFieldErrors());
+
+            // check field errors
+            // we have an error in this field level, email does not ends with mycompany.com
+            List l = (List) context.getFieldErrors().get("email");
+            assertNotNull(l);
+            assertEquals(1, l.size()); // because email-field-val is short-circuit
+            assertEquals("Email not from the right company.", l.get(0));
+
+            
+            // check action errors
+            l = (List) context.getActionErrors();
+            assertFalse(context.hasActionErrors());
+            assertEquals(0, l.size());
+            
+            
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+
+    
+    public void testActionLevelShortCircuit() throws Exception {
+    	
+    	List validatorList = annotationActionValidatorManager.getValidators(AnnotationUser.class, null);
+        assertEquals(10, validatorList.size());
+        
+        AnnotationUser user = new AnnotationUser();
+        // all fields will trigger error, but sc of action-level, cause it to not appear
+        user.setName(null);		
+
+        user.setEmail("rainerh(at)example.com");
+        user.setEmail("rainer_h(at)example.com");
+
+
+        ValidatorContext context = new GenericValidatorContext(user);
+        annotationActionValidatorManager.validate(user, null, context);
+    	
+    	// check field level errors
+        // shouldn't have any because action error prevents validation of anything else
+        List l = (List) context.getFieldErrors().get("email2");
+        assertNull(l);
+    	
+    	
+        // check action errors
+        assertTrue(context.hasActionErrors());
+        l = (List) context.getActionErrors();
+        assertNotNull(l);
+        // we only get one, because AnnotationUserMarker-validation.xml action-level validator
+        // already sc it   :-)
+        assertEquals(1, l.size()); 
+        assertEquals("Email not the same as email2", l.get(0));
+    }
+    
+    
+    public void testShortCircuitNoErrors() {
+        // get validators
+        List validatorList = annotationActionValidatorManager.getValidators(AnnotationUser.class, null);
+        assertEquals(10, validatorList.size());
+
+        try {
+            AnnotationUser user = new AnnotationUser();
+            user.setName("Mark");
+            user.setEmail("mark@mycompany.com");
+            user.setEmail2("mark@mycompany.com");
+
+            ValidatorContext context = new GenericValidatorContext(user);
+            annotationActionValidatorManager.validate(user, null, context);
+            assertFalse(context.hasErrors());
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
new file mode 100644
index 0000000..6dbb429
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
@@ -0,0 +1,70 @@
+package com.opensymphony.xwork2.validator;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.validator.annotations.ConditionalVisitorFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.ConversionErrorFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.CustomValidator;
+import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.DoubleRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.EmailValidator;
+import com.opensymphony.xwork2.validator.annotations.ExpressionValidator;
+import com.opensymphony.xwork2.validator.annotations.FieldExpressionValidator;
+import com.opensymphony.xwork2.validator.annotations.IntRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.ShortRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.UrlValidator;
+import com.opensymphony.xwork2.validator.annotations.ValidationParameter;
+import com.opensymphony.xwork2.validator.annotations.VisitorFieldValidator;
+
+/**
+ * Sets up all available validation annotations
+ */
+public class AnnotationValidationAction extends ActionSupport {
+
+    @RegexFieldValidator(regex = "foo", message = "Foo doesn't match!", key = "regex.key",
+            fieldName = "bar", shortCircuit = true, trim = false, caseSensitive = false,
+            messageParams = {"one", "two", "three"})
+    @ConditionalVisitorFieldValidator(expression = "foo+bar", context = "some", appendPrefix = false, fieldName = "bar",
+            key = "conditional.key", message = "Foo doesn't match!", shortCircuit = true,
+            messageParams = {"one", "two", "three"})
+    @ConversionErrorFieldValidator(fieldName = "bar", key = "conversion.key", message = "Foo conversion error!",
+            shortCircuit = true, repopulateField = true, messageParams = {"one", "three"})
+    @CustomValidator(type = "myValidator", fieldName = "foo", key = "foo.invalid", message = "Foo is invalid!",
+            shortCircuit = true, messageParams = {"one", "two", "three"},
+            parameters = {
+                    @ValidationParameter(name = "value", value = "1")
+            }
+    )
+    @DateRangeFieldValidator(fieldName = "foo", key = "date.foo", max = "2012", min = "2011", dateFormat = "yyyy",
+            message = "Foo isn't in range!", shortCircuit = true, messageParams = {"one", "two", "three"})
+    @DoubleRangeFieldValidator(minExclusive = "1.2", maxExclusive = "1.4", minInclusive = "0", maxInclusive = "0.1",
+            fieldName = "foo", key = "double.key", message = "Foo is out of range!", shortCircuit = true,
+            messageParams = {"one", "two", "three"})
+    @EmailValidator(message = "Foo isn't a valid e-mail!", fieldName = "foo", key = "email.key",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @ExpressionValidator(expression = "true", message = "Is not true!", key = "expression.key",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @FieldExpressionValidator(expression = "true", fieldName = "foo", key = "fieldexpression.key", message = "It is not true!",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @IntRangeFieldValidator(fieldName = "foo", key = "int.key", message = "Foo is out of range!", max = "10", min = "1",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @RequiredFieldValidator(fieldName = "foo", key = "required.key", message = "Foo is required!",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @RequiredStringValidator(fieldName = "foo", key = "requiredstring.key", message = "Foo is required!",
+            messageParams = {"one", "two", "three"}, shortCircuit = true, trim = false)
+    @ShortRangeFieldValidator(fieldName = "foo", key = "short.key", message = "Foo is out of range!", min = "1", max = "10",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @StringLengthFieldValidator(fieldName = "foo", key = "stringlength.key", message = "Foo is too long!",
+            maxLength = "10", minLength = "1", shortCircuit = true, trim = false, messageParams = {"one", "two", "three"})
+    @UrlValidator(fieldName = "foo", key = "url.key", message = "Foo isn't a valid URL!", shortCircuit = true,
+            messageParams = {"one", "two", "three"})
+    @VisitorFieldValidator(message = "Foo isn't valid!", key = "visitorfield.key", fieldName = "foo", appendPrefix = false,
+            shortCircuit = true, messageParams = {"one", "two", "three"})
+    public String execute() {
+        return SUCCESS;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
new file mode 100644
index 0000000..da6df01
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
@@ -0,0 +1,309 @@
+package com.opensymphony.xwork2.validator;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.DefaultActionInvocation;
+import com.opensymphony.xwork2.XWorkConstants;
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.config.ConfigurationProvider;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.entities.PackageConfig;
+import com.opensymphony.xwork2.inject.ContainerBuilder;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+import com.opensymphony.xwork2.util.location.LocatableProperties;
+import com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator;
+import com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator;
+import com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator;
+import com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator;
+import com.opensymphony.xwork2.validator.validators.EmailValidator;
+import com.opensymphony.xwork2.validator.validators.ExpressionValidator;
+import com.opensymphony.xwork2.validator.validators.FieldExpressionValidator;
+import com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator;
+import com.opensymphony.xwork2.validator.validators.RegexFieldValidator;
+import com.opensymphony.xwork2.validator.validators.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.validators.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator;
+import com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator;
+import com.opensymphony.xwork2.validator.validators.URLValidator;
+import com.opensymphony.xwork2.validator.validators.VisitorFieldValidator;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Simple test to check if validation Annotations match given validator class
+ */
+public class AnnotationValidationConfigurationBuilderTest extends XWorkTestCase {
+
+    public void testValidationAnnotation() throws Exception {
+        // given
+        AnnotationActionValidatorManager manager = createValidationManager(AnnotationValidationAction.class, Locale.US);
+
+        // when
+        List<Validator> validators = manager.getValidators(AnnotationValidationAction.class, null);
+
+        // then
+        assertEquals(validators.size(), 16);
+        for (Validator validator : validators) {
+            validate(validator);
+        }
+    }
+
+    public void testValidationAnnotationExpParams() throws Exception {
+        // given
+        AnnotationActionValidatorManager manager = createValidationManager(AnnotationValidationExpAction.class, Locale.US);
+
+        // when
+        List<Validator> validators = manager.getValidators(AnnotationValidationExpAction.class, null);
+
+        // then
+        ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
+        valueStack.push(new AnnotationValidationExpAction());
+
+        assertEquals(validators.size(), 16);
+        for (Validator validator : validators) {
+            validator.setValueStack(valueStack);
+            validate(validator);
+        }
+    }
+
+    private void validate(Validator validator) throws Exception {
+        if (validator.getValidatorType().equals("regex")) {
+            validateRegexValidator((RegexFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("conditionalvisitor")) {
+            validateConditionalFieldVisitorValidator((ConditionalVisitorFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("conversion")) {
+            validateConversionFieldErrorVisitorValidator((ConversionErrorFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("myValidator")) {
+            validateMyValidator((MyValidator) validator);
+        } else if (validator.getValidatorType().equals("date")) {
+            validateDateRangeFieldValidator((DateRangeFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("double")) {
+            validateDoubleRangeFieldValidator((DoubleRangeFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("email")) {
+            validateEmailValidator((EmailValidator) validator);
+        } else if (validator.getValidatorType().equals("expression")) {
+            validateExpressionValidator((ExpressionValidator) validator);
+        } else if (validator.getValidatorType().equals("fieldexpression")) {
+            validateFieldExpressionValidator((FieldExpressionValidator) validator);
+        } else if (validator.getValidatorType().equals("int")) {
+            validateIntRangeFieldValidator((IntRangeFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("required")) {
+            validateRequiredFieldValidator((RequiredFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("requiredstring")) {
+            validateRequiredStringValidator((RequiredStringValidator) validator);
+        } else if (validator.getValidatorType().equals("short")) {
+            validateShortRangeFieldValidator((ShortRangeFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("stringlength")) {
+            validateStringLengthFieldValidator((StringLengthFieldValidator) validator);
+        } else if (validator.getValidatorType().equals("url")) {
+            validateUrlValidator((URLValidator) validator);
+        } else if (validator.getValidatorType().equals("visitor")) {
+            validateVisitorFieldValidator((VisitorFieldValidator) validator);
+        }
+    }
+
+    private void validateVisitorFieldValidator(VisitorFieldValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("visitorfield.key", validator.getMessageKey());
+        assertEquals("Foo isn't valid!", validator.getDefaultMessage());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(false, validator.isAppendPrefix());
+        assertEquals(true, validator.isShortCircuit());
+    }
+
+    private void validateUrlValidator(URLValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("Foo isn't a valid URL!", validator.getDefaultMessage());
+        assertEquals("url.key", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+    }
+
+    private void validateStringLengthFieldValidator(StringLengthFieldValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("stringlength.key", validator.getMessageKey());
+        assertEquals("Foo is too long!", validator.getDefaultMessage());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(1, validator.getMinLength());
+        assertEquals(10, validator.getMaxLength());
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(false, validator.isTrim());
+    }
+
+    private void validateShortRangeFieldValidator(ShortRangeFieldValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("Foo is out of range!", validator.getDefaultMessage());
+        assertEquals("short.key", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(Short.valueOf("10"), validator.getMax());
+        assertEquals(Short.valueOf("1"), validator.getMin());
+        assertEquals(true, validator.isShortCircuit());
+    }
+
+    private void validateRequiredStringValidator(RequiredStringValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("requiredstring.key", validator.getMessageKey());
+        assertEquals("Foo is required!", validator.getDefaultMessage());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(false, validator.isTrim());
+    }
+
+    private void validateRequiredFieldValidator(RequiredFieldValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("Foo is required!", validator.getDefaultMessage());
+        assertEquals("required.key", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+    }
+
+    private void validateIntRangeFieldValidator(IntRangeFieldValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("int.key", validator.getMessageKey());
+        assertEquals("Foo is out of range!", validator.getDefaultMessage());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(Integer.valueOf(10), validator.getMax());
+        assertEquals(Integer.valueOf(1), validator.getMin());
+    }
+
+    private void validateFieldExpressionValidator(FieldExpressionValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("It is not true!", validator.getDefaultMessage());
+        assertEquals("fieldexpression.key", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals("true", validator.getExpression());
+        assertEquals(true, validator.isShortCircuit());
+    }
+
+    private void validateExpressionValidator(ExpressionValidator validator) {
+        assertEquals("expression.key", validator.getMessageKey());
+        assertEquals("Is not true!", validator.getDefaultMessage());
+        assertEquals("true", validator.getExpression());
+        assertEquals(true, validator.isShortCircuit());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+    }
+
+    private void validateEmailValidator(EmailValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals(EmailValidator.EMAIL_ADDRESS_PATTERN, validator.getRegex());
+        assertEquals("Foo isn't a valid e-mail!", validator.getDefaultMessage());
+        assertEquals("email.key", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(false, validator.isCaseSensitive());
+        assertEquals(true, validator.isTrimed());
+    }
+
+    private void validateDoubleRangeFieldValidator(DoubleRangeFieldValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("double.key", validator.getMessageKey());
+        assertEquals("Foo is out of range!", validator.getDefaultMessage());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(1.4, validator.getMaxExclusive());
+        assertEquals(1.2, validator.getMinExclusive());
+        assertEquals(0.1, validator.getMaxInclusive());
+        assertEquals(0.0, validator.getMinInclusive());
+    }
+
+    private void validateDateRangeFieldValidator(DateRangeFieldValidator validator) throws ParseException {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("Foo isn't in range!", validator.getDefaultMessage());
+        assertEquals("date.foo", validator.getMessageKey());
+        assertEquals(true, validator.isShortCircuit());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(new SimpleDateFormat("yyyy").parse("2011"), validator.getMin());
+        assertEquals(new SimpleDateFormat("yyyy").parse("2012"), validator.getMax());
+    }
+
+    private void validateMyValidator(MyValidator validator) {
+        assertEquals("Foo is invalid!", validator.getDefaultMessage());
+        assertEquals("foo", validator.getFieldName());
+        assertEquals("foo.invalid", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(1, validator.getValue());
+    }
+
+    private void validateConversionFieldErrorVisitorValidator(ConversionErrorFieldValidator validator) {
+        assertEquals("bar", validator.getFieldName());
+        assertEquals("conversion.key", validator.getMessageKey());
+        assertEquals("Foo conversion error!", validator.getDefaultMessage());
+        assertEquals(true, validator.isRepopulateField());
+        assertEquals(true, validator.isShortCircuit());
+        assertTrue(Arrays.equals(new String[]{"one", "three"}, validator.getMessageParameters()));
+    }
+
+    private void validateConditionalFieldVisitorValidator(ConditionalVisitorFieldValidator validator) {
+        assertEquals("foo+bar", validator.getExpression());
+        assertEquals("some", validator.getContext());
+        assertEquals("Foo doesn't match!", validator.getDefaultMessage());
+        assertEquals("bar", validator.getFieldName());
+        assertEquals(false, validator.isAppendPrefix());
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals("conditional.key", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+    }
+
+    private void validateRegexValidator(RegexFieldValidator validator) {
+        assertEquals("foo", validator.getRegex());
+        assertEquals("Foo doesn't match!", validator.getDefaultMessage());
+        assertEquals("regex.key", validator.getMessageKey());
+        assertEquals("bar", validator.getFieldName());
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(false, validator.isTrimed());
+        assertEquals(false, validator.isCaseSensitive());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+    }
+
+    private AnnotationActionValidatorManager createValidationManager(final Class<? extends ActionSupport> actionClass, Locale locale) throws Exception {
+        loadConfigurationProviders(new ConfigurationProvider() {
+            public void destroy() {
+
+            }
+
+            public void init(Configuration configuration) throws ConfigurationException {
+                configuration.addPackageConfig("default", new PackageConfig.Builder("default")
+                        .addActionConfig("annotation", new ActionConfig.Builder("", "annotation", actionClass.getName()).build())
+                        .build());
+            }
+
+            public boolean needsReload() {
+                return false;
+            }
+
+            public void loadPackages() throws ConfigurationException {
+
+            }
+
+            public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
+                builder.constant(XWorkConstants.DEV_MODE, true);
+            }
+        });
+
+        // ActionContext is destroyed during rebuilding configuration
+        ActionContext.getContext().setLocale(locale);
+
+        ActionInvocation invocation = new DefaultActionInvocation(ActionContext.getContext().getContextMap(), true);
+        container.inject(invocation);
+        invocation.init(actionProxyFactory.createActionProxy("", "annotation", null, ActionContext.getContext().getContextMap()));
+
+        AnnotationActionValidatorManager manager = new AnnotationActionValidatorManager();
+        container.inject(manager);
+
+        ValidatorFactory vf = container.getInstance(ValidatorFactory.class);
+        vf.registerValidator("myValidator", MyValidator.class.getName());
+
+        return manager;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java
new file mode 100644
index 0000000..c7c91ff
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationExpAction.java
@@ -0,0 +1,139 @@
+package com.opensymphony.xwork2.validator;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.validator.annotations.ConditionalVisitorFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.ConversionErrorFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.CustomValidator;
+import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.DoubleRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.EmailValidator;
+import com.opensymphony.xwork2.validator.annotations.ExpressionValidator;
+import com.opensymphony.xwork2.validator.annotations.FieldExpressionValidator;
+import com.opensymphony.xwork2.validator.annotations.IntRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RegexFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.ShortRangeFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.UrlValidator;
+import com.opensymphony.xwork2.validator.annotations.ValidationParameter;
+import com.opensymphony.xwork2.validator.annotations.VisitorFieldValidator;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Sets up all available validation annotations with params as expressions
+ */
+public class AnnotationValidationExpAction extends ActionSupport {
+
+    @RegexFieldValidator(regexExpression = "${foo}", message = "Foo doesn't match!", key = "regex.key",
+            fieldName = "bar", shortCircuit = true, trimExpression = "${trim}", caseSensitiveExpression = "${caseSensitive}",
+            messageParams = {"one", "two", "three"})
+    @ConditionalVisitorFieldValidator(expression = "foo+bar", context = "some", appendPrefix = false, fieldName = "bar",
+            key = "conditional.key", message = "Foo doesn't match!", shortCircuit = true,
+            messageParams = {"one", "two", "three"})
+    @ConversionErrorFieldValidator(fieldName = "bar", key = "conversion.key", message = "Foo conversion error!",
+            shortCircuit = true, repopulateField = true, messageParams = {"one", "three"})
+    @CustomValidator(type = "myValidator", fieldName = "foo", key = "foo.invalid", message = "Foo is invalid!",
+            shortCircuit = true, messageParams = {"one", "two", "three"},
+            parameters = {
+                    @ValidationParameter(name = "value", value = "1")
+            }
+    )
+    @DateRangeFieldValidator(fieldName = "foo", key = "date.foo", maxExpression = "${dateMax}", minExpression = "${dateMin}", dateFormat = "yyyy",
+            message = "Foo isn't in range!", shortCircuit = true, messageParams = {"one", "two", "three"})
+    @DoubleRangeFieldValidator(minExclusiveExpression = "${doubleMinExclusiveExpression}", maxExclusiveExpression = "${doubleMaxExclusiveExpression}",
+            minInclusiveExpression = "${doubleMinInclusiveExpression}", maxInclusiveExpression = "${doubleMaxInclusiveExpression}",
+            fieldName = "foo", key = "double.key", message = "Foo is out of range!", shortCircuit = true,
+            messageParams = {"one", "two", "three"})
+    @EmailValidator(message = "Foo isn't a valid e-mail!", fieldName = "foo", key = "email.key",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @ExpressionValidator(expression = "true", message = "Is not true!", key = "expression.key",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @FieldExpressionValidator(expression = "true", fieldName = "foo", key = "fieldexpression.key", message = "It is not true!",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @IntRangeFieldValidator(fieldName = "foo", key = "int.key", message = "Foo is out of range!",
+            maxExpression = "${intMax}", minExpression = "${intMin}",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @RequiredFieldValidator(fieldName = "foo", key = "required.key", message = "Foo is required!",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @RequiredStringValidator(fieldName = "foo", key = "requiredstring.key", message = "Foo is required!",
+            messageParams = {"one", "two", "three"}, shortCircuit = true, trim = false)
+    @ShortRangeFieldValidator(fieldName = "foo", key = "short.key", message = "Foo is out of range!",
+            minExpression = "${shortMin}", maxExpression = "${shortMax}",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @StringLengthFieldValidator(fieldName = "foo", key = "stringlength.key", message = "Foo is too long!",
+            maxLengthExpression = "${maxLength}", minLengthExpression = "${minLength}", shortCircuit = true, trimExpression = "${false}",
+            messageParams = {"one", "two", "three"})
+    @UrlValidator(fieldName = "foo", key = "url.key", message = "Foo isn't a valid URL!", shortCircuit = true,
+            messageParams = {"one", "two", "three"})
+    @VisitorFieldValidator(message = "Foo isn't valid!", key = "visitorfield.key", fieldName = "foo", appendPrefix = false,
+            shortCircuit = true, messageParams = {"one", "two", "three"})
+    public String execute() {
+        return SUCCESS;
+    }
+
+    public String getFoo() {
+        return "foo";
+    }
+
+    public boolean getTrim() {
+        return false;
+    }
+
+    public boolean getCaseSensitive() {
+        return false;
+    }
+
+    public Date getDateMin() throws ParseException {
+        return new SimpleDateFormat("yyyy").parse("2011");
+    }
+
+    public Date getDateMax() throws ParseException {
+        return new SimpleDateFormat("yyyy").parse("2012");
+    }
+
+    public Double getDoubleMinExclusiveExpression() {
+        return 1.2;
+    }
+
+    public Double getDoubleMaxExclusiveExpression() {
+        return 1.4;
+    }
+
+    public Double getDoubleMinInclusiveExpression() {
+        return 0.0;
+    }
+
+    public Double getDoubleMaxInclusiveExpression() {
+        return 0.1;
+    }
+
+    public int getIntMax() {
+        return 10;
+    }
+
+    public int getIntMin() {
+        return 1;
+    }
+
+    public short getShortMin() {
+        return 1;
+    }
+
+    public short getShortMax() {
+        return 10;
+    }
+
+    public int getMaxLength() {
+        return 10;
+    }
+
+    public int getMinLength() {
+        return 1;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/ConversionErrorFieldValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/ConversionErrorFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/ConversionErrorFieldValidatorTest.java
new file mode 100644
index 0000000..ab22d48
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/ConversionErrorFieldValidatorTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ValidationAware;
+import com.opensymphony.xwork2.ValidationAwareSupport;
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * ConversionErrorFieldValidatorTest
+ *
+ * @author Jason Carreira
+ *         Date: Nov 28, 2003 3:45:37 PM
+ */
+public class ConversionErrorFieldValidatorTest extends XWorkTestCase {
+
+    private static final String defaultFooMessage = "Invalid field value for field \"foo\".";
+
+
+    private ConversionErrorFieldValidator validator;
+    private ValidationAware validationAware;
+
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        ActionContext context = new ActionContext(stack.getContext());
+
+        Map<String, Object> conversionErrors = new HashMap<>();
+        conversionErrors.put("foo", "bar");
+        context.setConversionErrors(conversionErrors);
+        validator = new ConversionErrorFieldValidator();
+        validationAware = new ValidationAwareSupport();
+
+        DelegatingValidatorContext validatorContext = new DelegatingValidatorContext(validationAware);
+        stack.push(validatorContext);
+        validator.setValidatorContext(validatorContext);
+        validator.setFieldName("foo");
+        validator.setValueStack(ActionContext.getContext().getValueStack());
+        assertEquals(0, validationAware.getFieldErrors().size());
+    }
+
+    public void testConversionErrorMessageUsesProvidedMessage() throws ValidationException {
+        String message = "default message";
+        validator.setDefaultMessage(message);
+        validator.validate(validationAware);
+
+
+        Map fieldErrors = validationAware.getFieldErrors();
+        assertTrue(fieldErrors.containsKey("foo"));
+        assertEquals(message, ((List) fieldErrors.get("foo")).get(0));
+    }
+
+    public void testConversionErrorsAreAddedToFieldErrors() throws ValidationException {
+        validator.validate(validationAware);
+
+        Map fieldErrors = validationAware.getFieldErrors();
+        assertTrue(fieldErrors.containsKey("foo"));
+        assertEquals(defaultFooMessage, ((List) fieldErrors.get("foo")).get(0));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java
new file mode 100644
index 0000000..a937292
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.ValidationAware;
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.config.providers.MockConfigurationProvider;
+import com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator;
+
+import java.util.*;
+
+
+/**
+ * DateRangeValidatorTest
+ *
+ * @author Jason Carreira
+ *         Created Feb 9, 2003 1:25:42 AM
+ */
+public class DateRangeValidatorTest extends XWorkTestCase {
+
+    /**
+     * Tests whether the date range validation is working. Should produce an validation error,
+     * because the action config sets date to 12/20/2002 while expected range is Dec 22-25.
+     */
+    public void testRangeValidation() throws Exception {
+        Calendar date = Calendar.getInstance();
+        date.set(2002, Calendar.NOVEMBER, 20);
+        Map<String, Object> context = new HashMap<>();
+        HashMap<String, Object> params = new HashMap<>();
+        params.put("date", date.getTime());
+        context.put(ActionContext.PARAMETERS, params);
+
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, context);
+        proxy.execute();
+        assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
+
+        Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
+
+        List<String> errorMessages = errors.get("date");
+        assertNotNull("Expected date range validation error message.", errorMessages);
+        assertEquals(1, errorMessages.size());
+
+        String errorMessage = errorMessages.get(0);
+        assertEquals("The date must be between 12-22-2002 and 12-25-2002.", errorMessage);
+    }
+
+    public void testGetSetMinMax() throws Exception {
+        DateRangeFieldValidator val = new DateRangeFieldValidator();
+        Date max = new Date();
+        val.setMax(max);
+        assertEquals(max, val.getMax());
+
+        Date min = new Date();
+        val.setMin(min);
+        assertEquals(min, val.getMin());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        loadConfigurationProviders(new MockConfigurationProvider());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java
new file mode 100644
index 0000000..8a5e62d
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator;
+
+import com.mockobjects.dynamic.C;
+import com.mockobjects.dynamic.Mock;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.FileManagerFactory;
+import com.opensymphony.xwork2.SimpleAction;
+import com.opensymphony.xwork2.StubValueStack;
+import com.opensymphony.xwork2.TestBean;
+import com.opensymphony.xwork2.XWorkException;
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.config.ConfigurationException;
+import com.opensymphony.xwork2.test.DataAware2;
+import com.opensymphony.xwork2.test.SimpleAction2;
+import com.opensymphony.xwork2.test.SimpleAction3;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.fs.DefaultFileManager;
+import com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+
+/**
+ * DefaultActionValidatorManagerTest
+ *
+ * @author Jason Carreira
+ * @author tm_jee 
+ * @version $Date$ $Id$
+ */
+public class DefaultActionValidatorManagerTest extends XWorkTestCase {
+
+    protected final String alias = "validationAlias";
+
+    DefaultActionValidatorManager actionValidatorManager;
+    Mock mockValidatorFileParser;
+    Mock mockValidatorFactory;
+    ValueStack stubValueStack;
+
+    @Override
+    protected void setUp() throws Exception {
+        actionValidatorManager = new DefaultActionValidatorManager();
+        super.setUp();
+        mockValidatorFileParser = new Mock(ValidatorFileParser.class);
+        actionValidatorManager.setValidatorFileParser((ValidatorFileParser)mockValidatorFileParser.proxy());
+
+        mockValidatorFactory = new Mock(ValidatorFactory.class);
+        actionValidatorManager.setValidatorFactory((ValidatorFactory)mockValidatorFactory.proxy());
+
+        stubValueStack = new StubValueStack();
+        ActionContext.setContext(new ActionContext(new HashMap<String, Object>()));
+        ActionContext.getContext().setValueStack(stubValueStack);
+
+        DefaultFileManagerFactory factory = new DefaultFileManagerFactory();
+        factory.setContainer(container);
+        factory.setFileManager(new DefaultFileManager());
+        actionValidatorManager.setFileManagerFactory(factory);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        actionValidatorManager = null;
+        super.tearDown();
+        mockValidatorFactory = null;
+        mockValidatorFileParser = null;
+    }
+
+
+    public void testBuildValidatorKey() {
+        String validatorKey = DefaultActionValidatorManager.buildValidatorKey(SimpleAction.class, alias);
+        assertEquals(SimpleAction.class.getName() + "/" + alias, validatorKey);
+    }
+
+    public void testBuildsValidatorsForAlias() {
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/SimpleAction-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/SimpleAction-validationAlias-validation.xml")),
+                new ArrayList());
+         actionValidatorManager.getValidators(SimpleAction.class, alias);
+        mockValidatorFileParser.verify();
+    }
+
+    public void testBuildsValidatorsForAliasError() {
+        boolean pass = false;
+        try {
+            mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/TestBean-validation.xml")),
+                new ArrayList());
+            mockValidatorFileParser.expectAndThrow("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/TestBean-badtest-validation.xml")),
+                new ConfigurationException());
+            List validatorList = actionValidatorManager.getValidators(TestBean.class, "badtest");
+        } catch (XWorkException ex) {
+            pass = true;
+        }
+        mockValidatorFileParser.verify();
+        assertTrue("Didn't throw exception on load failure", pass);
+    }
+
+
+    public void testGetValidatorsForInterface() {
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/test/DataAware-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/test/DataAware-validationAlias-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/test/DataAware2-validation.xml")),
+                new ArrayList());
+        actionValidatorManager.getValidators(DataAware2.class, alias);
+        mockValidatorFileParser.verify();
+    }
+
+    public void testGetValidatorsFromInterface() {
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/SimpleAction-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/SimpleAction-validationAlias-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/test/DataAware-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/test/DataAware-validationAlias-validation.xml")),
+                new ArrayList());
+        actionValidatorManager.getValidators(SimpleAction3.class, alias);
+        mockValidatorFileParser.verify();
+    }
+
+    public void testSameAliasWithDifferentClass() {
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/SimpleAction-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/SimpleAction-validationAlias-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/test/SimpleAction2-validation.xml")),
+                new ArrayList());
+        mockValidatorFileParser.expectAndReturn("parseActionValidatorConfigs",
+                C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/test/SimpleAction2-validationAlias-validation.xml")),
+                new ArrayList());
+        actionValidatorManager.getValidators(SimpleAction.class, alias);
+        actionValidatorManager.getValidators(SimpleAction2.class, alias);
+        mockValidatorFileParser.verify();
+    }
+
+    /**
+     * Test to verify WW-3850.
+     *
+     * @since 2.3.5
+     */
+    public void testBuildsValidatorsForClassError() {
+        // for this test we need to have a file manager with reloadingConfigs to true
+        container.getInstance(FileManagerFactory.class).getFileManager().setReloadingConfigs(true);
+        // no validator found, but no check on file since it is not in cache
+        actionValidatorManager.getValidators(List.class, null);
+        // this second call will try reload a not existing file
+        // and causes a NPE (see WW-3850)
+        try {
+            actionValidatorManager.getValidators(List.class, null);
+        } catch (Exception e) {
+            fail("Exception occurred " + e);
+        }
+    }
+
+    /*
+    // TODO: this all need to be converted to real unit tests
+
+    public void testSkipUserMarkerActionLevelShortCircuit() {
+        // get validators
+        List validatorList = actionValidatorManager.getValidators(User.class, null);
+        assertEquals(10, validatorList.size());
+
+        try {
+            User user = new User();
+            user.setName("Mark");
+            user.setEmail("bad_email");
+            user.setEmail2("bad_email");
+
+            ValidatorContext context = new GenericValidatorContext(user);
+            actionValidatorManager.validate(user, null, context);
+            assertTrue(context.hasFieldErrors());
+
+            // check field errors
+            List l = (List) context.getFieldErrors().get("email");
+            assertNotNull(l);
+            assertEquals(1, l.size());
+            assertEquals("Not a valid e-mail.", l.get(0));
+            l = (List) context.getFieldErrors().get("email2");
+            assertNotNull(l);
+            assertEquals(2, l.size());
+            assertEquals("Not a valid e-mail2.", l.get(0));
+            assertEquals("Email2 not from the right company.", l.get(1));
+
+            // check action errors
+            assertTrue(context.hasActionErrors());
+            l = (List) context.getActionErrors();
+            assertNotNull(l);
+            assertEquals(2, l.size()); // both expression test failed see User-validation.xml
+            assertEquals("Email does not start with mark", l.get(0));
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+
+    public void testSkipAllActionLevelShortCircuit2() {
+        // get validators
+        List validatorList = actionValidatorManager.getValidators(User.class, null);
+        assertEquals(10, validatorList.size());
+
+        try {
+            User user = new User();
+            user.setName("Mark");
+            // * mark both email to starts with mark to get pass the action-level validator,
+            // so we could concentrate on testing the field-level validators (User-validation.xml)
+            // * make both email the same to pass the action-level validator at 
+            // UserMarker-validation.xml
+            user.setEmail("mark_bad_email_for_field_val@foo.com");
+            user.setEmail2("mark_bad_email_for_field_val@foo.com");
+
+            ValidatorContext context = new GenericValidatorContext(user);
+            actionValidatorManager.validate(user, null, context);
+            assertTrue(context.hasFieldErrors());
+
+            // check field errors
+            // we have an error in this field level, email does not ends with mycompany.com
+            List l = (List) context.getFieldErrors().get("email");
+            assertNotNull(l);
+            assertEquals(1, l.size()); // because email-field-val is short-circuit
+            assertEquals("Email not from the right company.", l.get(0));
+
+            
+            // check action errors
+            l = (List) context.getActionErrors();
+            assertFalse(context.hasActionErrors());
+            assertEquals(0, l.size());
+            
+            
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+
+    
+    public void testActionLevelShortCircuit() throws Exception {
+    	
+    	List validatorList = actionValidatorManager.getValidators(User.class, null);
+        assertEquals(10, validatorList.size());
+        
+        User user = new User();
+        // all fields will trigger error, but sc of action-level, cause it to not appear
+        user.setName(null);		
+        user.setEmail("tmjee(at)yahoo.co.uk");
+        user.setEmail("tm_jee(at)yahoo.co.uk");
+        
+        ValidatorContext context = new GenericValidatorContext(user);
+        actionValidatorManager.validate(user, null, context);
+    	
+    	// check field level errors
+        // shouldn't have any because action error prevents validation of anything else
+        List l = (List) context.getFieldErrors().get("email2");
+        assertNull(l);
+    	
+    	
+        // check action errors
+        assertTrue(context.hasActionErrors());
+        l = (List) context.getActionErrors();
+        assertNotNull(l);
+        // we only get one, because UserMarker-validation.xml action-level validator
+        // already sc it   :-)
+        assertEquals(1, l.size()); 
+        assertEquals("Email not the same as email2", l.get(0));
+    }
+    
+    
+    public void testShortCircuitNoErrors() {
+        // get validators
+        List validatorList = actionValidatorManager.getValidators(User.class, null);
+        assertEquals(10, validatorList.size());
+
+        try {
+            User user = new User();
+            user.setName("Mark");
+            user.setEmail("mark@mycompany.com");
+            user.setEmail2("mark@mycompany.com");
+
+            ValidatorContext context = new GenericValidatorContext(user);
+            actionValidatorManager.validate(user, null, context);
+            assertFalse(context.hasErrors());
+        } catch (ValidationException ex) {
+            ex.printStackTrace();
+            fail("Validation error: " + ex.getMessage());
+        }
+    }
+    
+    public void testFieldErrorsOrder() throws Exception {
+    	ValidationOrderAction action = new ValidationOrderAction();
+    	actionValidatorManager.validate(action, "actionContext");
+    	Map fieldErrors = action.getFieldErrors();
+    	Iterator i = fieldErrors.entrySet().iterator();
+    	
+    	assertNotNull(fieldErrors);
+    	assertEquals(fieldErrors.size(), 12);
+    	
+    	
+    	Map.Entry e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "username");
+    	assertEquals(((List)e.getValue()).get(0), "username required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "password");
+    	assertEquals(((List)e.getValue()).get(0), "password required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "confirmPassword");
+    	assertEquals(((List)e.getValue()).get(0), "confirm password required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "firstName");
+    	assertEquals(((List)e.getValue()).get(0), "first name required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "lastName");
+    	assertEquals(((List)e.getValue()).get(0), "last name required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "city");
+    	assertEquals(((List)e.getValue()).get(0), "city is required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "province");
+    	assertEquals(((List)e.getValue()).get(0), "province is required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "country");
+    	assertEquals(((List)e.getValue()).get(0), "country is required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "postalCode");
+    	assertEquals(((List)e.getValue()).get(0), "postal code is required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "email");
+    	assertEquals(((List)e.getValue()).get(0), "email is required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "website");
+    	assertEquals(((List)e.getValue()).get(0), "website is required");
+    	
+    	e = (Map.Entry) i.next();
+    	assertEquals(e.getKey(), "passwordHint");
+    	assertEquals(((List)e.getValue()).get(0), "password hint is required");
+    	
+    }
+    */
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFactoryTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFactoryTest.java
new file mode 100644
index 0000000..7cb10dd
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFactoryTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator;
+
+import com.mockobjects.dynamic.C;
+import com.mockobjects.dynamic.Mock;
+import junit.framework.TestCase;
+
+/**
+ * <code>DefaultValidatorFactoryTest</code>
+ *
+ * @author <a href="mailto:hermanns@aixcept.de">Rainer Hermanns</a>
+ * @version $Id$
+ */
+public class DefaultValidatorFactoryTest extends TestCase {
+
+    public void testParseValidators() {
+        Mock mockValidatorFileParser = new Mock(ValidatorFileParser.class);
+        mockValidatorFileParser.expect("parseValidatorDefinitions", C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("com/opensymphony/xwork2/validator/validators/default.xml")));
+        mockValidatorFileParser.expect("parseValidatorDefinitions", C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("validators.xml")));
+        mockValidatorFileParser.expect("parseValidatorDefinitions", C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("myOther-validators.xml")));
+        mockValidatorFileParser.expect("parseValidatorDefinitions", C.args(C.IS_NOT_NULL, C.IS_NOT_NULL, C.eq("my-validators.xml")));
+        DefaultValidatorFactory factory = new DefaultValidatorFactory(null, (ValidatorFileParser) mockValidatorFileParser.proxy());
+    }
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParserTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParserTest.java
new file mode 100644
index 0000000..b900b55
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultValidatorFileParserTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2002-2003,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator;
+
+import com.mockobjects.dynamic.C;
+import com.mockobjects.dynamic.Mock;
+import com.opensymphony.xwork2.XWorkException;
+import com.opensymphony.xwork2.util.ClassLoaderUtil;
+import com.opensymphony.xwork2.validator.validators.*;
+import junit.framework.TestCase;
+
+import java.io.InputStream;
+import java.util.List;
+
+
+/**
+ * DefaultValidatorFileParserTest
+ * <p/>
+ * Created : Jan 20, 2003 3:41:26 PM
+ *
+ * @author Jason Carreira
+ * @author James House
+ * @author tm_jee ( tm_jee (at) yahoo.co.uk )
+ * @author Martin Gilday
+ */
+public class DefaultValidatorFileParserTest extends TestCase {
+
+    private static final String testFileName = "com/opensymphony/xwork2/validator/validator-parser-test.xml";
+    private static final String testFileName2 = "com/opensymphony/xwork2/validator/validator-parser-test2.xml";
+    private static final String testFileName3 = "com/opensymphony/xwork2/validator/validator-parser-test3.xml";
+    private static final String testFileName4 = "com/opensymphony/xwork2/validator/validator-parser-test4.xml";
+    private static final String testFileName5 = "com/opensymphony/xwork2/validator/validator-parser-test5.xml";
+    private static final String testFileName6 = "com/opensymphony/xwork2/validator/validator-parser-test6.xml";
+    private static final String testFileNameFail = "com/opensymphony/xwork2/validator/validators-fail.xml";
+    private Mock mockValidatorFactory;
+    private ValidatorFileParser parser;
+
+    public void testParserActionLevelValidatorsShouldBeBeforeFieldLevelValidators() throws Exception {
+        InputStream is = ClassLoaderUtil.getResourceAsStream(testFileName2, this.getClass());
+
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("expression")), ExpressionValidator.class.getName());
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("required")), RequiredFieldValidator.class.getName());
+        List configs = parser.parseActionValidatorConfigs((ValidatorFactory) mockValidatorFactory.proxy(), is, testFileName2);
+        mockValidatorFactory.verify();
+
+        ValidatorConfig valCfg0 = (ValidatorConfig) configs.get(0);
+        ValidatorConfig valCfg1 = (ValidatorConfig) configs.get(1);
+
+        assertNotNull(configs);
+        assertEquals(configs.size(), 2);
+
+        assertEquals("expression", valCfg0.getType());
+        assertFalse(valCfg0.isShortCircuit());
+        assertEquals(valCfg0.getDefaultMessage(), "an expression error message");
+        assertEquals(valCfg0.getParams().get("expression"), "false");
+
+        assertEquals("required", valCfg1.getType());
+        assertFalse(valCfg1.isShortCircuit());
+        assertEquals(valCfg1.getDefaultMessage(), "a field error message");
+    }
+
+
+    public void testParser() {
+        InputStream is = ClassLoaderUtil.getResourceAsStream(testFileName, this.getClass());
+
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("expression")), ExpressionValidator.class.getName());
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("expression")), ExpressionValidator.class.getName());
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("required")), RequiredFieldValidator.class.getName());
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("required")), RequiredFieldValidator.class.getName());
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("int")), IntRangeFieldValidator.class.getName());
+        mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("regex")), RegexFieldValidator.class.getName());
+        List configs = parser.parseActionValidatorConfigs((ValidatorFactory) mockValidatorFactory.proxy(), is, testFileName);
+        mockValidatorFactory.verify();
+
+
+        assertNotNull(configs);
+        assertEquals(6, configs.size());
+
+
+        ValidatorConfig cfg = (ValidatorConfig) configs.get(0);
+        assertEquals("expression", cfg.getType());
+        assertFalse(cfg.isShortCircuit());
+
+        cfg = (ValidatorConfig) configs.get(1);
+        assertEquals("expression", cfg.getType());
+        assertTrue(cfg.isShortCircuit());
+
+        cfg = (ValidatorConfig) configs.get(2);
+        assertEquals("required", cfg.getType());
+        assertEquals("foo", cfg.getParams().get("fieldName"));
+        assertEquals("You must enter a value for foo.", cfg.getDefaultMessage());
+        assertEquals(4, cfg.getLocation().getLineNumber());
+
+        cfg = (ValidatorConfig) configs.get(3);
+        assertEquals("required", cfg.getType());
+        assertTrue(cfg.isShortCircuit());
+
+        cfg = (ValidatorConfig) configs.get(4);
+        assertEquals("int", cfg.getType());
+        assertFalse(cfg.isShortCircuit());
+
+        cfg = (ValidatorConfig) configs.get(5);
+        assertEquals("regex", cfg.getType());
+        assertFalse(cfg.isShortCircuit());
+        assertEquals("([aAbBcCdD][123][eEfFgG][456])", cfg.getParams().get("expression"));
+    }
+
+    public void testParserWithBadValidation() {
+        InputStream is = ClassLoaderUtil.getResourceAsStream(testFileName3, this.getClass());
+
+        boolean pass = false;
+        try {
+            parser.parseActionValidatorConfigs((ValidatorFactory) mockValidatorFactory.proxy(), is, testFileName3);
+        } catch (XWorkException ex) {
+            assertTrue("Wrong line number", 3 == ex.getLocation().getLineNumber());
+            pass = true;
+        }
+        assertTrue("Validation file should have thrown exception", pass);
+    }
+
+    public void testParserWithBadXML() {
+        InputStream is = ClassLoaderUtil.getResourceAsStream(testFileName4, this.getClass());
+
+        boolean pass = false;
+        try {
+            parser.parseActionValidatorConfigs((ValidatorFactory) mockValidatorFactory.proxy(), is, testFileName4);
+        } catch (XWorkException ex) {
+            assertTrue("Wrong line number: " + ex.getLocation(), 13 == ex.getLocation().getLineNumber());
+            pass = true;
+        }
+        assertTrue("Validation file should have thrown exception", pass);
+    }
+
+    public void testParserWithBadXML2() {
+        InputStream is = ClassLoaderUtil.getResourceAsStream(testFileNameFail, this.getClass());
+
+        boolean pass = false;
+        try {
+            parser.parseActionValidatorConfigs((ValidatorFactory) mockValidatorFactory.proxy(), is, testFileNameFail);
+        } catch (XWorkException ex) {
+            assertTrue("Wrong line number: " + ex.getLocation(), 8 == ex.getLocation().getLineNumber());
+            pass = true;
+        }
+        assertTrue("Validation file should have thrown exception", pass);
+    }
+
+    public void testValidatorDefinitionsWithBadClassName() {
+        InputStream is = ClassLoaderUtil.getResourceAsStream(testFileName5, this.getClass());
+
+        boolean pass = false;
+        try {
+            parser.parseActionValidatorConfigs((ValidatorFactory) mockValidatorFactory.proxy(), is, testFileName5);
+        } catch (XWorkException ex) {
+            assertTrue("Wrong line number", 3 == ex.getLocation().getLineNumber());
+            pass = true;
+        }
+        assertTrue("Validation file should have thrown exception", pass);
+    }
+
+    public void testValidatorWithI18nMessage() throws Exception {
+        try (InputStream is = ClassLoaderUtil.getResourceAsStream(testFileName6, this.getClass())) {
+            mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("requiredstring")), RequiredStringValidator.class.getName());
+            mockValidatorFactory.expectAndReturn("lookupRegisteredValidatorType", C.args(C.eq("requiredstring")), RequiredStringValidator.class.getName());
+
+            List validatorConfigs = parser.parseActionValidatorConfigs((ValidatorFactory) mockValidatorFactory.proxy(), is, "-//OpenSymphony Group//XWork Validator 1.0.3//EN");
+            mockValidatorFactory.verify();
+
+            assertEquals(validatorConfigs.size(), 2);
+
+            assertEquals(((ValidatorConfig)validatorConfigs.get(0)).getParams().get("fieldName"), "name");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(0)).getMessageParams().length, 0);
+            assertEquals(((ValidatorConfig)validatorConfigs.get(0)).getMessageKey(), "error.name");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(0)).getDefaultMessage(), "default message 1");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(0)).getParams().size(), 1);
+            assertEquals(((ValidatorConfig)validatorConfigs.get(0)).getType(), "requiredstring");
+
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getParams().get("fieldName"), "address");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getMessageParams().length, 5);
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getMessageParams()[0], "'tmjee'");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getMessageParams()[1], "'phil'");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getMessageParams()[2], "'rainer'");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getMessageParams()[3], "'hopkins'");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getMessageParams()[4], "'jimmy'");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getMessageKey(), "error.address");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getDefaultMessage(), "The Default Message");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getParams().size(), 3);
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getParams().get("trim"), "true");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getParams().get("anotherParam"), "anotherValue");
+            assertEquals(((ValidatorConfig)validatorConfigs.get(1)).getType(), "requiredstring");
+        }
+    }
+
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mockValidatorFactory = new Mock(ValidatorFactory.class);
+        parser = new DefaultValidatorFileParser();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mockValidatorFactory = null;
+        parser = null;
+    }
+}


Mime
View raw message