You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2017/04/19 07:42:15 UTC

[01/13] struts git commit: WW-4578 Makes RegexFieldValidator to support collections

Repository: struts
Updated Branches:
  refs/heads/master 9d4aac058 -> 5fd605eb9


WW-4578 Makes RegexFieldValidator to support collections


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/caca3d05
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/caca3d05
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/caca3d05

Branch: refs/heads/master
Commit: caca3d057d56f43699c1ef5d37e7800eb7b0e5a5
Parents: 1162ddf
Author: Lukasz Lenart <lu...@apache.org>
Authored: Thu Apr 6 08:59:11 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Thu Apr 6 08:59:11 2017 +0200

----------------------------------------------------------------------
 .../validators/RegexFieldValidator.java         | 35 ++++++++--
 .../validator/validators/ValidatorSupport.java  |  2 +
 .../validator/RegexFieldValidatorTest.java      | 70 ++++++++++++++++++++
 3 files changed, 100 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/caca3d05/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
index b931482..b1ca900 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
@@ -16,11 +16,17 @@
 
 package com.opensymphony.xwork2.validator.validators;
 
+import com.opensymphony.xwork2.ObjectFactory;
+import org.apache.commons.lang3.ObjectUtils;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
 import com.opensymphony.xwork2.validator.ValidationException;
 import org.apache.commons.lang3.StringUtils;
 
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -105,13 +111,28 @@ public class RegexFieldValidator extends FieldValidatorSupport {
             return;
         }
 
-        // XW-375 - must be a string
-        if (!(value instanceof String)) {
-            return;
+        if (value instanceof String) {
+            validateFieldValue(object, fieldName, (String) value, regexToUse);
+        }
+
+        if (value.getClass().isArray()) {
+            Object[] values = (Object[]) value;
+            for (Object objValue: values) {
+                validateFieldValue(object, fieldName, Objects.toString(objValue, EMPTY_STRING), regexToUse);
+            }
         }
 
+        if (Collection.class.isAssignableFrom(value.getClass())) {
+            Collection<Object> values = (Collection<Object>) value;
+            for (Object objValue : values) {
+                validateFieldValue(object, fieldName, Objects.toString(objValue, EMPTY_STRING), regexToUse);
+            }
+        }
+    }
+
+    protected void validateFieldValue(Object object, String fieldName, String value, String regexToUse) {
         // string must not be empty
-        String str = ((String) value).trim();
+        String str = value.trim();
         if (str.length() == 0) {
             return;
         }
@@ -124,12 +145,12 @@ public class RegexFieldValidator extends FieldValidatorSupport {
             pattern = Pattern.compile(regexToUse, Pattern.CASE_INSENSITIVE);
         }
 
-        String compare = (String) value;
-        if ( isTrimed() ) {
+        String compare = value;
+        if (isTrimed()) {
             compare = compare.trim();
         }
-        Matcher matcher = pattern.matcher( compare );
 
+        Matcher matcher = pattern.matcher(compare);
         if (!matcher.matches()) {
             addFieldError(fieldName, object);
         }

http://git-wip-us.apache.org/repos/asf/struts/blob/caca3d05/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java
index 2173a2f..dabb4e3 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java
@@ -39,6 +39,8 @@ public abstract class ValidatorSupport implements Validator, ShortCircuitableVal
 
     private static final Logger LOG = LogManager.getLogger(ValidatorSupport.class);
 
+    public static final String EMPTY_STRING = "";
+
     private ValidatorContext validatorContext;
     private boolean shortCircuit;
     private String type;

http://git-wip-us.apache.org/repos/asf/struts/blob/caca3d05/core/src/test/java/com/opensymphony/xwork2/validator/RegexFieldValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/RegexFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/RegexFieldValidatorTest.java
index 4fa50fd..df392a8 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/RegexFieldValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/RegexFieldValidatorTest.java
@@ -21,6 +21,8 @@ import com.opensymphony.xwork2.XWorkTestCase;
 import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.validator.validators.RegexFieldValidator;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -183,9 +185,61 @@ public class RegexFieldValidatorTest extends XWorkTestCase {
         assertFalse(validator.getValidatorContext().hasFieldErrors());
     }
 
+    public void testArrayOfStringField() throws Exception {
+        MyTestPerson testPerson = new MyTestPerson();
+        testPerson.setFriends(new String[]{"Alice", "Matt"});
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        ActionContext.getContext().setValueStack(stack);
+
+        RegexFieldValidator validator = new RegexFieldValidator();
+        validator.setRegex("A([a-zA-Z]*)");
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("friends");
+        validator.setValueStack(ActionContext.getContext().getValueStack());
+        validator.setDefaultMessage("Only names starting with A are allowed!");
+
+        validator.validate(testPerson);
+
+        assertTrue(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertTrue(validator.getValidatorContext().hasFieldErrors());
+        assertEquals(1, validator.getValidatorContext().getFieldErrors().size());
+        assertEquals(1, validator.getValidatorContext().getFieldErrors().get("friends").size());
+        assertEquals("Only names starting with A are allowed!", validator.getValidatorContext().getFieldErrors().get("friends").get(0));
+    }
+
+    public void testListOfStringField() throws Exception {
+        MyTestPerson testPerson = new MyTestPerson();
+        testPerson.setCars(Arrays.asList("Audi", "BMW"));
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        ActionContext.getContext().setValueStack(stack);
+
+        RegexFieldValidator validator = new RegexFieldValidator();
+        validator.setRegex("A([a-zA-Z]*)");
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("cars");
+        validator.setValueStack(ActionContext.getContext().getValueStack());
+        validator.setDefaultMessage("Only cars starting with A are allowed!");
+
+        validator.validate(testPerson);
+
+        assertTrue(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertTrue(validator.getValidatorContext().hasFieldErrors());
+        assertEquals(1, validator.getValidatorContext().getFieldErrors().size());
+        assertEquals(1, validator.getValidatorContext().getFieldErrors().get("cars").size());
+        assertEquals("Only cars starting with A are allowed!", validator.getValidatorContext().getFieldErrors().get("cars").get(0));
+    }
+
     private class MyTestPerson {
         private String username;
         private int age;
+        private String[] friends;
+        private List cars;
 
         public String getUsername() {
             return username;
@@ -202,6 +256,22 @@ public class RegexFieldValidatorTest extends XWorkTestCase {
         public void setAge(int age) {
             this.age = age;
         }
+
+        public String[] getFriends() {
+            return friends;
+        }
+
+        public void setFriends(String[] friends) {
+            this.friends = friends;
+        }
+
+        public List getCars() {
+            return cars;
+        }
+
+        public void setCars(List cars) {
+            this.cars = cars;
+        }
     }
 
 }


[03/13] struts git commit: WW-4578 Makes required validator to support collections

Posted by lu...@apache.org.
WW-4578 Makes required validator to support collections


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/e66fd538
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/e66fd538
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/e66fd538

Branch: refs/heads/master
Commit: e66fd538b519b1a156d76e4bbe4e994a35e3c464
Parents: 158eda9
Author: Lukasz Lenart <lu...@apache.org>
Authored: Mon Apr 10 09:13:14 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Mon Apr 10 09:13:14 2017 +0200

----------------------------------------------------------------------
 .../validators/RequiredFieldValidator.java      |  7 ++
 .../validators/RequiredFieldValidatorTest.java  | 78 ++++++++++++++++++++
 .../validator/validators/ValidationAction.java  | 10 +++
 3 files changed, 95 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/e66fd538/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java
index dffd37a..44fd92f 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidator.java
@@ -17,6 +17,9 @@ package com.opensymphony.xwork2.validator.validators;
 
 import com.opensymphony.xwork2.validator.ValidationException;
 
+import java.lang.reflect.Array;
+import java.util.Collection;
+
 
 /**
  * <!-- START SNIPPET: javadoc -->
@@ -63,6 +66,10 @@ public class RequiredFieldValidator extends FieldValidatorSupport {
 
         if (value == null) {
             addFieldError(fieldName, object);
+        } else if (value.getClass().isArray() && Array.getLength(value) == 0) {
+            addFieldError(fieldName, object);
+        } else if (Collection.class.isAssignableFrom(value.getClass()) && ((Collection) value).size() == 0) {
+            addFieldError(fieldName, object);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/e66fd538/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidatorTest.java
new file mode 100644
index 0000000..4fc02e1
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredFieldValidatorTest.java
@@ -0,0 +1,78 @@
+package com.opensymphony.xwork2.validator.validators;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.TextProviderFactory;
+import com.opensymphony.xwork2.validator.DummyValidatorContext;
+import org.apache.struts2.StrutsInternalTestCase;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+public class RequiredFieldValidatorTest extends StrutsInternalTestCase {
+
+    @Test
+    public void testNullObject() throws Exception {
+        // given
+        RequiredFieldValidator rfv = container.inject(RequiredFieldValidator.class);
+        rfv.setValueStack(ActionContext.getContext().getValueStack());
+        rfv.setFieldName("stringValue");
+        rfv.setDefaultMessage("${fieldName} field is required!");
+        ValidationAction action = new ValidationAction();
+        DummyValidatorContext context = new DummyValidatorContext(action, container.getInstance(TextProviderFactory.class));
+        rfv.setValidatorContext(context);
+
+        // when
+        rfv.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertNotNull(context.getFieldErrors().get("stringValue"));
+        assertEquals("stringValue field is required!", context.getFieldErrors().get("stringValue").get(0));
+    }
+
+    @Test
+    public void testArrayObject() throws Exception {
+        // given
+        RequiredFieldValidator rfv = container.inject(RequiredFieldValidator.class);
+        rfv.setValueStack(ActionContext.getContext().getValueStack());
+        rfv.setFieldName("ints");
+        rfv.setDefaultMessage("${fieldName} field is required!");
+        ValidationAction action = new ValidationAction();
+        action.setInts(new Integer[]{});
+        DummyValidatorContext context = new DummyValidatorContext(action, container.getInstance(TextProviderFactory.class));
+        rfv.setValidatorContext(context);
+
+        // when
+        rfv.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertNotNull(context.getFieldErrors().get("ints"));
+        assertEquals("ints field is required!", context.getFieldErrors().get("ints").get(0));
+    }
+    
+    @Test
+    public void testCollectionObject() throws Exception {
+        // given
+        RequiredFieldValidator rfv = container.inject(RequiredFieldValidator.class);
+        rfv.setValueStack(ActionContext.getContext().getValueStack());
+        rfv.setFieldName("shorts");
+        rfv.setDefaultMessage("${fieldName} field is required!");
+        ValidationAction action = new ValidationAction();
+        action.setShorts(new ArrayList<Short>());
+        DummyValidatorContext context = new DummyValidatorContext(action, container.getInstance(TextProviderFactory.class));
+        rfv.setValidatorContext(context);
+
+        // when
+        rfv.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertNotNull(context.getFieldErrors().get("shorts"));
+        assertEquals("shorts field is required!", context.getFieldErrors().get("shorts").get(0));
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/struts/blob/e66fd538/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
index a9fc40f..a97cea6 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
@@ -1,6 +1,7 @@
 package com.opensymphony.xwork2.validator.validators;
 
 import java.util.Date;
+import java.util.List;
 
 public class ValidationAction {
 
@@ -12,6 +13,7 @@ public class ValidationAction {
     private Short shortRange;
     private Short shortMinValue;
     private Short shortMaxValue;
+    private List<Short> shorts;
 
     private Long longRange;
     private Long longMinValue;
@@ -142,4 +144,12 @@ public class ValidationAction {
     public void setInts(Integer[] ints) {
         this.ints = ints;
     }
+
+    public List<Short> getShorts() {
+        return shorts;
+    }
+
+    public void setShorts(List<Short> shorts) {
+        this.shorts = shorts;
+    }
 }


[02/13] struts git commit: WW-4578 Changes range validators to support collections

Posted by lu...@apache.org.
WW-4578 Changes range validators to support collections


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/158eda97
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/158eda97
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/158eda97

Branch: refs/heads/master
Commit: 158eda97834645a542e81d7414b67f8285042b8b
Parents: caca3d0
Author: Lukasz Lenart <lu...@apache.org>
Authored: Mon Apr 10 08:37:22 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Mon Apr 10 08:37:22 2017 +0200

----------------------------------------------------------------------
 .../validators/FieldValidatorSupport.java       | 13 +++-
 .../validators/RangeValidatorSupport.java       | 66 +++++++++++++-------
 .../validators/IntRangeFieldValidatorTest.java  | 23 +++++++
 .../validator/validators/ValidationAction.java  |  9 +++
 4 files changed, 86 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/158eda97/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
index 4a3f147..ec75e13 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
@@ -17,16 +17,17 @@ package com.opensymphony.xwork2.validator.validators;
 
 import com.opensymphony.xwork2.validator.FieldValidator;
 
-
 /**
  * Base class for field validators.
  *
- * @author Jason Carreira
+ * You can access fieldName and its currentValue in a message using expression, e.g.
+ * "Wrong value ${currentValue} for ${fieldName}"
  */
 public abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator {
 
     private String fieldName;
     private String type;
+    private Object currentValue;
 
     public void setFieldName(String fieldName) {
         this.fieldName = fieldName;
@@ -45,4 +46,12 @@ public abstract class FieldValidatorSupport extends ValidatorSupport implements
     public String getValidatorType() {
         return type;
     }
+
+    public Object getCurrentValue() {
+        return currentValue;
+    }
+
+    public void setCurrentValue(Object currentValue) {
+        this.currentValue = currentValue;
+    }
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/158eda97/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java
index 39c0e86..5d156e3 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RangeValidatorSupport.java
@@ -20,6 +20,8 @@ import org.apache.logging.log4j.LogManager;
 import com.opensymphony.xwork2.validator.ValidationException;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Collection;
+
 /**
  * Base class for range based validators. Use this class to develop any other custom range validators.
  */
@@ -40,25 +42,45 @@ public abstract class RangeValidatorSupport<T extends Comparable> extends FieldV
 
     public void validate(Object object) throws ValidationException {
         Object obj = getFieldValue(getFieldName(), object);
-        Comparable<T> value = (Comparable<T>) obj;
 
         // if there is no value - don't do comparison
         // if a value is required, a required validator should be added to the field
-        if (value == null) {
+        if (obj == null) {
             return;
         }
 
+        T min = getMin();
+        T max = getMax();
+
+        if (obj.getClass().isArray()) {
+            Object[] values = (Object[]) obj;
+            for (Object objValue : values) {
+                validateValue(object, (Comparable<T>) objValue, min, max);
+            }
+        } else if (Collection.class.isAssignableFrom(obj.getClass())) {
+            Collection<?> values = (Collection<?>) obj;
+            for (Object objValue : values) {
+                validateValue(object, (Comparable<T>) objValue, min, max);
+            }
+        } else {
+            validateValue(object, (Comparable<T>) obj, min, max);
+        }
+    }
+
+    protected void validateValue(Object object, Comparable<T> value, T min, T max) {
+        setCurrentValue(value);
+
         // only check for a minimum value if the min parameter is set
-        T minComparatorValue = getMin();
-        if ((minComparatorValue != null) && (value.compareTo(minComparatorValue) < 0)) {
+        if ((min != null) && (value.compareTo(min) < 0)) {
             addFieldError(getFieldName(), object);
         }
 
         // only check for a maximum value if the max parameter is set
-        T maxComparatorValue = getMax();
-        if ((maxComparatorValue != null) && (value.compareTo(maxComparatorValue) > 0)) {
+        if ((max != null) && (value.compareTo(max) > 0)) {
             addFieldError(getFieldName(), object);
         }
+
+        setCurrentValue(null);
     }
 
     public void setMin(T min) {
@@ -66,13 +88,11 @@ public abstract class RangeValidatorSupport<T extends Comparable> extends FieldV
     }
 
     public T getMin() {
-        if (min != null) {
-            return min;
-        } else if (StringUtils.isNotEmpty(minExpression)) {
-            return (T) parse(minExpression, type);
-        } else {
-            return null;
-        }
+        return getT(min, minExpression, type);
+    }
+
+    public T getMax() {
+        return getT(max, maxExpression, type);
     }
 
     public void setMinExpression(String minExpression) {
@@ -84,19 +104,19 @@ public abstract class RangeValidatorSupport<T extends Comparable> extends FieldV
         this.max = max;
     }
 
-    public T getMax() {
-        if (max != null) {
-            return max;
-        } else if (StringUtils.isNotEmpty(maxExpression)) {
-            return (T) parse(maxExpression, type);
-        } else {
-            return null;
-        }
-    }
-
     public void setMaxExpression(String maxExpression) {
         LOG.debug("${maxExpression} was defined as [{}]", maxExpression);
         this.maxExpression = maxExpression;
     }
 
+    protected T getT(T minMax, String minMaxExpression, Class<T> toType) {
+        if (minMax != null) {
+            return minMax;
+        } else if (StringUtils.isNotEmpty(minMaxExpression)) {
+            return (T) parse(minMaxExpression, toType);
+        } else {
+            return null;
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/struts/blob/158eda97/core/src/test/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidatorTest.java
index 229e8fc..1992c25 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/validators/IntRangeFieldValidatorTest.java
@@ -57,11 +57,34 @@ public class IntRangeFieldValidatorTest extends XWorkTestCase {
         assertEquals("Max is 101, min is 99 but value is 102", context.getFieldErrors().get("intRange").get(0));
     }
 
+    public void testArrayOfIntValidation() throws Exception {
+        // given
+        ValidationAction action = new ValidationAction();
+        action.setInts(new Integer[] {99, 100, 101, 102});
+
+        ValidatorContext context = new DummyValidatorContext(action, tpf);
+        IntRangeFieldValidator validator = prepareValidator(action, context);
+
+        // when
+        validator.setMin(100);
+        validator.setMax(101);
+        validator.setFieldName("ints");
+        validator.setDefaultMessage("Max is ${max}, min is ${min} but value is ${currentValue}");
+        validator.validate(action);
+
+        // then
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals(2, context.getFieldErrors().get("ints").size());
+        assertEquals("Max is 101, min is 100 but value is 99", context.getFieldErrors().get("ints").get(0));
+        assertEquals("Max is 101, min is 100 but value is 102", context.getFieldErrors().get("ints").get(1));
+    }
+
     private ValidationAction prepareAction(int intRange) {
         ValidationAction action = new ValidationAction();
         action.setIntMaxValue(101);
         action.setIntMinValue(99);
         action.setIntRange(intRange);
+        action.setInts(new Integer[] {101, 99, 100, 102});
         return action;
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/158eda97/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
index 268288f..a9fc40f 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
@@ -7,6 +7,7 @@ public class ValidationAction {
     private Integer intRange;
     private Integer intMinValue;
     private Integer intMaxValue;
+    private Integer[] ints;
 
     private Short shortRange;
     private Short shortMinValue;
@@ -133,4 +134,12 @@ public class ValidationAction {
     public String getStringValue() {
         return stringValue;
     }
+
+    public Integer[] getInts() {
+        return ints;
+    }
+
+    public void setInts(Integer[] ints) {
+        this.ints = ints;
+    }
 }


[11/13] struts git commit: Reduces scope

Posted by lu...@apache.org.
Reduces scope


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/034e0981
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/034e0981
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/034e0981

Branch: refs/heads/master
Commit: 034e0981847aefc67d8be8530eb08e1041e8d7fe
Parents: b1f9068
Author: Lukasz Lenart <lu...@apache.org>
Authored: Fri Apr 14 12:45:56 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Fri Apr 14 12:45:56 2017 +0200

----------------------------------------------------------------------
 .../xwork2/validator/validators/FieldValidatorSupport.java       | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/034e0981/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
index 07938c9..07f6412 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
@@ -23,7 +23,7 @@ import com.opensymphony.xwork2.validator.FieldValidator;
  * You can access fieldName and its currentValue in a message using expression, e.g.
  * "Wrong value ${currentValue} for ${fieldName}"
  */
-public abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator {
+abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator {
 
     protected String fieldName;
     protected String type;
@@ -51,7 +51,7 @@ public abstract class FieldValidatorSupport extends ValidatorSupport implements
         return currentValue;
     }
 
-    public void setCurrentValue(Object currentValue) {
+    void setCurrentValue(Object currentValue) {
         this.currentValue = currentValue;
     }
 }


[04/13] struts git commit: WW-4578 Converts double range validator to support collections

Posted by lu...@apache.org.
WW-4578 Converts double range validator to support collections


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/01a56ca1
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/01a56ca1
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/01a56ca1

Branch: refs/heads/master
Commit: 01a56ca117532c63a89bec6464109e81d9273d62
Parents: e66fd53
Author: Lukasz Lenart <lu...@apache.org>
Authored: Mon Apr 10 21:54:03 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Mon Apr 10 21:54:03 2017 +0200

----------------------------------------------------------------------
 .../validators/DoubleRangeFieldValidator.java   |  73 ++--
 .../DoubleRangeFieldValidatorTest.java          | 363 +++++++++++++++++++
 .../validator/DoubleRangeValidatorTest.java     | 279 --------------
 3 files changed, 413 insertions(+), 302 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/01a56ca1/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
index 8ed4e4c..f968b97 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
@@ -18,6 +18,11 @@ package com.opensymphony.xwork2.validator.validators;
 
 import com.opensymphony.xwork2.validator.ValidationException;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Arrays;
+import java.util.Collection;
 
 /**
  * <!-- START SNIPPET: javadoc -->
@@ -27,15 +32,15 @@ import org.apache.commons.lang3.StringUtils;
  *
  * <!-- START SNIPPET: parameters -->
  * <ul>
- *     <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
- *     <li>minInclusive - the minimum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- *     <li>maxInclusive - the maximum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- *     <li>minExclusive - the minimum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- *     <li>maxExclusive - the maximum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- *     <li>minInclusiveExpression - the minimum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
- *     <li>maxInclusiveExpression - the maximum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
- *     <li>minExclusiveExpression - the minimum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
- *     <li>maxExclusiveExpression - the maximum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ * <li>minInclusive - the minimum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ * <li>maxInclusive - the maximum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ * <li>minExclusive - the minimum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ * <li>maxExclusive - the maximum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ * <li>minInclusiveExpression - the minimum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ * <li>maxInclusiveExpression - the maximum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ * <li>minExclusiveExpression - the minimum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ * <li>maxExclusiveExpression - the maximum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
  * </ul>
  *
  * You can specify either minInclusive, maxInclusive, minExclusive and maxExclusive or minInclusiveExpression, maxInclusiveExpression,
@@ -86,7 +91,9 @@ import org.apache.commons.lang3.StringUtils;
  * @author Rene Gielen
  */
 public class DoubleRangeFieldValidator extends FieldValidatorSupport {
-    
+
+    private static final Logger LOG = LogManager.getLogger(DoubleRangeFieldValidator.class);
+
     private Double maxInclusive = null;
     private Double minInclusive = null;
     private Double minExclusive = null;
@@ -99,14 +106,8 @@ public class DoubleRangeFieldValidator extends FieldValidatorSupport {
 
     public void validate(Object object) throws ValidationException {
         String fieldName = getFieldName();
-        Double value;
-        try {
-            Object obj = this.getFieldValue(fieldName, object);
-            if (obj == null) {
-                return;
-            }
-            value = Double.valueOf(obj.toString());
-        } catch (NumberFormatException e) {
+        Object obj = this.getFieldValue(fieldName, object);
+        if (obj == null) {
             return;
         }
 
@@ -115,11 +116,37 @@ public class DoubleRangeFieldValidator extends FieldValidatorSupport {
         Double maxExclusiveToUse = getMaxExclusive();
         Double minExclusiveToUse = getMinExclusive();
 
-        if ((maxInclusiveToUse != null && value.compareTo(maxInclusiveToUse) > 0) ||
-                (minInclusiveToUse != null && value.compareTo(minInclusiveToUse) < 0) ||
-                (maxExclusiveToUse != null && value.compareTo(maxExclusiveToUse) >= 0) ||
-                (minExclusiveToUse != null && value.compareTo(minExclusiveToUse) <= 0)) {
-            addFieldError(fieldName, object);
+        if (obj.getClass().isArray()) {
+            Object[] values = (Object[]) obj;
+            validateCollection(maxInclusiveToUse, minInclusiveToUse, maxExclusiveToUse, minExclusiveToUse, Arrays.asList(values));
+        } else if (Collection.class.isAssignableFrom(obj.getClass())) {
+            Collection values = (Collection) obj;
+            validateCollection(maxInclusiveToUse, minInclusiveToUse, maxExclusiveToUse, minExclusiveToUse, values);
+        } else {
+            validateValue(obj, maxInclusiveToUse, minInclusiveToUse, maxExclusiveToUse, minExclusiveToUse);
+        }
+    }
+
+    protected void validateCollection(Double maxInclusiveToUse, Double minInclusiveToUse, Double maxExclusiveToUse, Double minExclusiveToUse, Collection values) {
+        for (Object objValue : values) {
+            validateValue(objValue, maxInclusiveToUse, minInclusiveToUse, maxExclusiveToUse, minExclusiveToUse);
+        }
+    }
+
+    protected void validateValue(Object obj, Double maxInclusiveToUse, Double minInclusiveToUse, Double maxExclusiveToUse, Double minExclusiveToUse) {
+        try {
+            setCurrentValue(obj);
+            Double value = Double.valueOf(obj.toString());
+            if ((maxInclusiveToUse != null && value.compareTo(maxInclusiveToUse) > 0) ||
+                    (minInclusiveToUse != null && value.compareTo(minInclusiveToUse) < 0) ||
+                    (maxExclusiveToUse != null && value.compareTo(maxExclusiveToUse) >= 0) ||
+                    (minExclusiveToUse != null && value.compareTo(minExclusiveToUse) <= 0)) {
+                addFieldError(getFieldName(), value);
+            }
+        } catch (NumberFormatException e) {
+            LOG.debug("Cannot validate value {} - not a Double", e);
+        } finally {
+            setCurrentValue(null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/01a56ca1/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java
new file mode 100644
index 0000000..68b1a82
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java
@@ -0,0 +1,363 @@
+package com.opensymphony.xwork2.validator;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.TextProviderFactory;
+import com.opensymphony.xwork2.ValidationAwareSupport;
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.config.providers.MockConfigurationProvider;
+import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
+import com.opensymphony.xwork2.interceptor.ValidationAware;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator;
+import org.apache.struts2.dispatcher.HttpParameters;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Unit test for {@link DoubleRangeFieldValidator}.
+ *
+ * @author <a href="mailto:hermanns@aixcept.de">Rainer Hermanns</a>
+ * @author Claus Ibsen
+ * @version $Id$
+ */
+public class DoubleRangeFieldValidatorTest extends XWorkTestCase {
+
+    private DoubleRangeFieldValidator val;
+    private TextProviderFactory tpf;
+
+    public void testRangeValidationWithError() throws Exception {
+        //Explicitly set an out-of-range double for DoubleRangeValidatorTest
+        Map<String, Object> context = new HashMap<>();
+        HashMap<String, Object> params = new HashMap<>();
+        params.put("percentage", 100.0123d);
+        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, context);
+        proxy.execute();
+        assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
+
+        Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
+
+        List<String> errorMessages = errors.get("percentage");
+        assertNotNull("Expected double range validation error message.", errorMessages);
+        assertEquals(1, errorMessages.size());
+
+        String errorMessage = errorMessages.get(0);
+        assertNotNull("Expecting: percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
+        assertEquals("percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
+    }
+
+    public void testRangeValidationNoError() throws Exception {
+        Map<String, Object> context = new HashMap<>();
+        HashMap<String, Object> params = new HashMap<>();
+        params.put("percentage", 1.234567d);
+        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "percentage", null, context);
+        proxy.execute();
+        assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
+
+        Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
+        List<String> errorMessages = errors.get("percentage");
+        assertNull("Expected no double range validation error message.", errorMessages);
+    }
+
+    public void testRangeNoExclusiveAndNoValueInStack() throws Exception {
+        val.setFieldName("hello");
+        val.validate("world");
+    }
+
+    public void testRangeSimpleDoubleValueInStack() throws Exception {
+        MyTestProduct prod = new MyTestProduct();
+        prod.setName("coca cola");
+        prod.setPrice(5.99);
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(prod);
+        ActionContext.getContext().setValueStack(stack);
+
+        val.setMinInclusive(0d);
+        val.setMaxInclusive(10d);
+        val.setFieldName("price");
+        val.validate(prod);
+    }
+
+    public void testRangeRealDoubleValueInStack() throws Exception {
+        MyTestProduct prod = new MyTestProduct();
+        prod.setName("coca cola");
+        prod.setPrice(5.99);
+        prod.setVolume(12.34d);
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(prod);
+        ActionContext.getContext().setValueStack(stack);
+
+        val.setMinInclusive(0d);
+        val.setMaxInclusive(30d);
+        val.setFieldName("volume");
+        val.validate(prod);
+    }
+
+    public void testRangeNotADoubleObjectValueInStack() throws Exception {
+        MyTestProduct prod = new MyTestProduct();
+        prod.setName("coca cola");
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(prod);
+        ActionContext.getContext().setValueStack(stack);
+
+        val.setMinInclusive(0d);
+        val.setMaxInclusive(10d);
+        val.setFieldName("name");
+
+        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
+        val.setValidatorContext(context);
+
+        val.validate(prod);
+
+        assertEquals(0d, val.getMinInclusive());
+        assertEquals(10d, val.getMaxInclusive());
+    }
+
+    public void testEdgeOfMaxRange() throws Exception {
+        MyTestProduct prod = new MyTestProduct();
+        prod.setName("coca cola");
+        prod.setPrice(9.95);
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(prod);
+        ActionContext.getContext().setValueStack(stack);
+
+        val.setFieldName("price");
+
+        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
+        val.setValidatorContext(context);
+
+        val.setMaxInclusive(9.95d);
+        val.validate(prod); // should pass
+        assertTrue(!context.hasErrors());
+        assertEquals(9.95d, val.getMaxInclusive());
+
+        val.setMaxExclusive(9.95d);
+        val.validate(prod); // should not pass
+        assertTrue(context.hasErrors());
+        assertEquals(9.95d, val.getMaxExclusive());
+    }
+
+    public void testEdgeOfMinRange() throws Exception {
+        MyTestProduct prod = new MyTestProduct();
+        prod.setName("coca cola");
+        prod.setPrice(9.95);
+
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        stack.push(prod);
+        ActionContext.getContext().setValueStack(stack);
+
+        val.setFieldName("price");
+
+        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
+        val.setValidatorContext(context);
+
+        val.setMinInclusive(9.95d);
+        val.validate(prod); // should pass
+        assertTrue(!context.hasErrors());
+
+        val.setMinExclusive(9.95d);
+        val.validate(prod); // should not pass
+        assertTrue(context.hasErrors());
+    }
+
+    public void testNoValue() throws Exception {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        ActionContext.getContext().setValueStack(stack);
+
+        val.setFieldName("price");
+
+        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
+        val.setValidatorContext(context);
+
+        val.setMinInclusive(9.95d);
+        val.validate(null);
+        assertFalse(context.hasErrors()); // should pass as null value passed in
+    }
+
+    public void testRangeValidationWithExpressionsFail() throws Exception {
+        //Explicitly set an out-of-range double for DoubleRangeValidatorTest
+        Map<String, Object> context = new HashMap<>();
+        HashMap<String, Object> params = new HashMap<>();
+        params.put("percentage", 100.0123d);
+        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.EXPRESSION_VALIDATION_ACTION, null, context);
+        proxy.execute();
+        assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
+
+        Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
+        List<String> errorMessages = errors.get("percentage");
+        assertNotNull("Expected double range validation error message.", errorMessages);
+        assertEquals(1, errorMessages.size());
+
+        String errorMessage = errorMessages.get(0);
+        assertNotNull("Expecting: percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
+        assertEquals("percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
+    }
+
+    public void testExpressionParams() throws Exception {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        ActionSupport action = new ActionSupport() {
+
+            public Double getMinInclusiveValue() {
+                return 10d;
+            }
+
+            public Double getMaxInclusiveValue() {
+                return 11d;
+            }
+
+            public Double getMinExclusiveValue() {
+                return 13d;
+            }
+
+            public Double getMaxExclusiveValue() {
+                return 14d;
+            }
+
+            public Double getPrice() {
+                return 15d;
+            }
+        };
+
+        stack.push(action);
+
+        val.setMinInclusiveExpression("${minInclusiveValue}");
+        val.setMaxInclusiveExpression("${maxInclusiveValue}");
+        val.setMinExclusiveExpression("${minExclusiveValue}");
+        val.setMaxExclusiveExpression("${maxExclusiveValue}");
+
+        val.setFieldName("price");
+        val.setDefaultMessage("Price is wrong!");
+
+        DelegatingValidatorContext context = new DelegatingValidatorContext(action, tpf);
+        val.setValidatorContext(context);
+
+        val.validate(action);
+        assertTrue(action.getFieldErrors().get("price").size() == 1);
+    }
+
+    public void testArrayOfDoubles() throws Exception {
+        val.setMinInclusive(10d);
+        val.setMaxInclusive(14d);
+
+        val.setFieldName("doubleArray");
+        val.setDefaultMessage("Value ${currentValue} not in scope!");
+
+        MyTestProduct object = new MyTestProduct();
+        object.setDoubleArray(new Double[]{11d, 15d});
+
+        DummyValidatorContext context = new DummyValidatorContext(object, tpf);
+        val.setValidatorContext(context);
+
+        val.validate(object);
+
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals(1, context.getFieldErrors().get("doubleArray").size());
+        assertEquals("Value 15.0 not in scope!", context.getFieldErrors().get("doubleArray").get(0));
+    }
+
+    public void testCollectionOfDoubles() throws Exception {
+        val.setMinInclusive(10d);
+        val.setMaxInclusive(14d);
+
+        val.setFieldName("doubleCollection");
+        val.setDefaultMessage("Value ${currentValue} not in scope!");
+
+        MyTestProduct object = new MyTestProduct();
+        object.setDoubleCollection(Arrays.asList(11d, 15d));
+
+        DummyValidatorContext context = new DummyValidatorContext(object, tpf);
+        val.setValidatorContext(context);
+
+        val.validate(object);
+
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals(1, context.getFieldErrors().get("doubleCollection").size());
+        assertEquals("Value 15.0 not in scope!", context.getFieldErrors().get("doubleCollection").get(0));
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-default.xml");
+        container.inject(provider);
+        loadConfigurationProviders(provider, new MockConfigurationProvider());
+        val = new DoubleRangeFieldValidator();
+        val.setValueStack(ActionContext.getContext().getValueStack());
+        ActionContext.getContext().setParameters(HttpParameters.create().build());
+        tpf = container.getInstance(TextProviderFactory.class);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        val = null;
+    }
+
+    private class MyTestProduct {
+        private double price;
+        private Double volume;
+        private String name;
+
+        private Double[] doubleArray;
+        private Collection<Double> doubleCollection;
+
+        public double getPrice() {
+            return price;
+        }
+
+        public void setPrice(double price) {
+            this.price = price;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public Double getVolume() {
+            return volume;
+        }
+
+        public void setVolume(Double volume) {
+            this.volume = volume;
+        }
+
+        public Double[] getDoubleArray() {
+            return doubleArray;
+        }
+
+        public void setDoubleArray(Double[] doubleArray) {
+            this.doubleArray = doubleArray;
+        }
+
+        public Collection<Double> getDoubleCollection() {
+            return doubleCollection;
+        }
+
+        public void setDoubleCollection(Collection<Double> doubleCollection) {
+            this.doubleCollection = doubleCollection;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/struts/blob/01a56ca1/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeValidatorTest.java
deleted file mode 100644
index e60d247..0000000
--- a/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeValidatorTest.java
+++ /dev/null
@@ -1,279 +0,0 @@
-package com.opensymphony.xwork2.validator;
-
-import com.opensymphony.xwork2.*;
-import com.opensymphony.xwork2.config.providers.MockConfigurationProvider;
-import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
-import com.opensymphony.xwork2.interceptor.ValidationAware;
-import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator;
-import org.apache.struts2.dispatcher.HttpParameters;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit test for {@link DoubleRangeFieldValidator}.
- *
- * @author <a href="mailto:hermanns@aixcept.de">Rainer Hermanns</a>
- * @author Claus Ibsen
- * @version $Id$
- */
-public class DoubleRangeValidatorTest extends XWorkTestCase {
-    private DoubleRangeFieldValidator val;
-    private TextProviderFactory tpf;
-
-    public void testRangeValidationWithError() throws Exception {
-        //Explicitly set an out-of-range double for DoubleRangeValidatorTest
-        Map<String, Object> context = new HashMap<>();
-        HashMap<String, Object> params = new HashMap<>();
-        params.put("percentage", 100.0123d);
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
-
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, context);
-        proxy.execute();
-        assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
-
-        Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
-
-        List<String> errorMessages = errors.get("percentage");
-        assertNotNull("Expected double range validation error message.", errorMessages);
-        assertEquals(1, errorMessages.size());
-
-        String errorMessage = errorMessages.get(0);
-        assertNotNull("Expecting: percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
-        assertEquals("percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
-    }
-
-    public void testRangeValidationNoError() throws Exception {
-        Map<String, Object> context = new HashMap<>();
-        HashMap<String, Object> params = new HashMap<>();
-        params.put("percentage", 1.234567d);
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
-
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "percentage", null, context);
-        proxy.execute();
-        assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
-
-        Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
-        List<String> errorMessages = errors.get("percentage");
-        assertNull("Expected no double range validation error message.", errorMessages);
-    }
-
-    public void testRangeNoExclusiveAndNoValueInStack() throws Exception {
-        val.setFieldName("hello");
-        val.validate("world");
-    }
-
-    public void testRangeSimpleDoubleValueInStack() throws Exception {
-        MyTestProduct prod = new MyTestProduct();
-        prod.setName("coca cola");
-        prod.setPrice(5.99);
-
-        ValueStack stack = ActionContext.getContext().getValueStack();
-        stack.push(prod);
-        ActionContext.getContext().setValueStack(stack);
-
-        val.setMinInclusive(0d);
-        val.setMaxInclusive(10d);
-        val.setFieldName("price");
-        val.validate(prod);
-    }
-
-    public void testRangeRealDoubleValueInStack() throws Exception {
-        MyTestProduct prod = new MyTestProduct();
-        prod.setName("coca cola");
-        prod.setPrice(5.99);
-        prod.setVolume(12.34d);
-
-        ValueStack stack = ActionContext.getContext().getValueStack();
-        stack.push(prod);
-        ActionContext.getContext().setValueStack(stack);
-
-        val.setMinInclusive(0d);
-        val.setMaxInclusive(30d);
-        val.setFieldName("volume");
-        val.validate(prod);
-    }
-
-    public void testRangeNotADoubleObjectValueInStack() throws Exception {
-        MyTestProduct prod = new MyTestProduct();
-        prod.setName("coca cola");
-
-        ValueStack stack = ActionContext.getContext().getValueStack();
-        stack.push(prod);
-        ActionContext.getContext().setValueStack(stack);
-
-        val.setMinInclusive(0d);
-        val.setMaxInclusive(10d);
-        val.setFieldName("name");
-
-        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
-        val.setValidatorContext(context);
-
-        val.validate(prod);
-
-        assertEquals(0d, val.getMinInclusive());
-        assertEquals(10d, val.getMaxInclusive());
-    }
-
-    public void testEdgeOfMaxRange() throws Exception {
-        MyTestProduct prod = new MyTestProduct();
-        prod.setName("coca cola");
-        prod.setPrice(9.95);
-
-        ValueStack stack = ActionContext.getContext().getValueStack();
-        stack.push(prod);
-        ActionContext.getContext().setValueStack(stack);
-
-        val.setFieldName("price");
-
-        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
-        val.setValidatorContext(context);
-
-        val.setMaxInclusive(9.95d);
-        val.validate(prod); // should pass
-        assertTrue(!context.hasErrors());
-        assertEquals(9.95d, val.getMaxInclusive());
-
-        val.setMaxExclusive(9.95d);
-        val.validate(prod); // should not pass
-        assertTrue(context.hasErrors());
-        assertEquals(9.95d, val.getMaxExclusive());
-    }
-
-    public void testEdgeOfMinRange() throws Exception {
-        MyTestProduct prod = new MyTestProduct();
-        prod.setName("coca cola");
-        prod.setPrice(9.95);
-
-        ValueStack stack = ActionContext.getContext().getValueStack();
-        stack.push(prod);
-        ActionContext.getContext().setValueStack(stack);
-
-        val.setFieldName("price");
-
-        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
-        val.setValidatorContext(context);
-
-        val.setMinInclusive(9.95d);
-        val.validate(prod); // should pass
-        assertTrue(!context.hasErrors());
-
-        val.setMinExclusive(9.95d);
-        val.validate(prod); // should not pass
-        assertTrue(context.hasErrors());
-    }
-
-    public void testNoValue() throws Exception {
-        ValueStack stack = ActionContext.getContext().getValueStack();
-        ActionContext.getContext().setValueStack(stack);
-
-        val.setFieldName("price");
-
-        DelegatingValidatorContext context = new DelegatingValidatorContext(new ValidationAwareSupport(), tpf);
-        val.setValidatorContext(context);
-
-        val.setMinInclusive(9.95d);
-        val.validate(null);
-        assertTrue(!context.hasErrors()); // should pass as null value passed in
-    }
-
-    public void testRangeValidationWithExpressionsFail() throws Exception {
-        //Explicitly set an out-of-range double for DoubleRangeValidatorTest
-        Map<String, Object> context = new HashMap<>();
-        HashMap<String, Object> params = new HashMap<>();
-        params.put("percentage", 100.0123d);
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
-
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.EXPRESSION_VALIDATION_ACTION, null, context);
-        proxy.execute();
-        assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
-
-        Map<String, List<String>> errors = ((ValidationAware) proxy.getAction()).getFieldErrors();
-        List<String> errorMessages = errors.get("percentage");
-        assertNotNull("Expected double range validation error message.", errorMessages);
-        assertEquals(1, errorMessages.size());
-
-        String errorMessage = errorMessages.get(0);
-        assertNotNull("Expecting: percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
-        assertEquals("percentage must be between 0.1 and 10.1, current value is 100.0123.", errorMessage);
-    }
-
-    public void testExpressionParams() throws Exception {
-        ValueStack stack = ActionContext.getContext().getValueStack();
-        ActionSupport action = new ActionSupport() {
-
-            public Double getMinInclusiveValue() {return 10d;}
-            public Double getMaxInclusiveValue() {return 11d;}
-            public Double getMinExclusiveValue() {return 13d;}
-            public Double getMaxExclusiveValue() {return 14d;}
-            public Double getPrice() {return 15d;}
-        };
-
-        stack.push(action);
-
-        val.setMinInclusiveExpression("${minInclusiveValue}");
-        val.setMaxInclusiveExpression("${maxInclusiveValue}");
-        val.setMinExclusiveExpression("${minExclusiveValue}");
-        val.setMaxExclusiveExpression("${maxExclusiveValue}");
-
-        val.setFieldName("price");
-        val.setDefaultMessage("Price is wrong!");
-
-        DelegatingValidatorContext context = new DelegatingValidatorContext(action, tpf);
-        val.setValidatorContext(context);
-
-        val.validate(action);
-        assertTrue(action.getFieldErrors().get("price").size() == 1);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-default.xml");
-        container.inject(provider);
-        loadConfigurationProviders(provider,  new MockConfigurationProvider());
-        val = new DoubleRangeFieldValidator();
-        val.setValueStack(ActionContext.getContext().getValueStack());
-        ActionContext.getContext().setParameters(HttpParameters.create().build());
-        tpf = container.getInstance(TextProviderFactory.class);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        val = null;
-    }
-
-    private class MyTestProduct {
-        private double price;
-        private Double volume;
-        private String name;
-
-        public double getPrice() {
-            return price;
-        }
-
-        public void setPrice(double price) {
-            this.price = price;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        public Double getVolume() {
-            return volume;
-        }
-
-        public void setVolume(Double volume) {
-            this.volume = volume;
-        }
-    }
-
-}


[10/13] struts git commit: Puts back indentation

Posted by lu...@apache.org.
Puts back indentation


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/b1f9068f
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/b1f9068f
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/b1f9068f

Branch: refs/heads/master
Commit: b1f9068f2ba7d4c61259414d1f46f32f2dda66c6
Parents: 1ad6d2c
Author: Lukasz Lenart <lu...@apache.org>
Authored: Fri Apr 14 12:25:04 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Fri Apr 14 12:25:04 2017 +0200

----------------------------------------------------------------------
 .../validators/DoubleRangeFieldValidator.java     | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/b1f9068f/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
index f968b97..fa775d8 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/DoubleRangeFieldValidator.java
@@ -32,15 +32,15 @@ import java.util.Collection;
  *
  * <!-- START SNIPPET: parameters -->
  * <ul>
- * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
- * <li>minInclusive - the minimum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- * <li>maxInclusive - the maximum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- * <li>minExclusive - the minimum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- * <li>maxExclusive - the maximum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
- * <li>minInclusiveExpression - the minimum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
- * <li>maxInclusiveExpression - the maximum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
- * <li>minExclusiveExpression - the minimum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
- * <li>maxExclusiveExpression - the maximum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ *     <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li>
+ *     <li>minInclusive - the minimum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>maxInclusive - the maximum inclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>minExclusive - the minimum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>maxExclusive - the maximum exclusive value in FloatValue format specified by Java language (if none is specified, it will not be checked) </li>
+ *     <li>minInclusiveExpression - the minimum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ *     <li>maxInclusiveExpression - the maximum inclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ *     <li>minExclusiveExpression - the minimum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
+ *     <li>maxExclusiveExpression - the maximum exclusive value specified as a OGNL expression (if none is specified, it will not be checked) </li>
  * </ul>
  *
  * You can specify either minInclusive, maxInclusive, minExclusive and maxExclusive or minInclusiveExpression, maxInclusiveExpression,


[05/13] struts git commit: WW-4578 Converts required string validator to support collections

Posted by lu...@apache.org.
WW-4578 Converts required string validator to support collections


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/df5583f1
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/df5583f1
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/df5583f1

Branch: refs/heads/master
Commit: df5583f11789fe2f5084d7fec780f99fa8d22b23
Parents: 01a56ca
Author: Lukasz Lenart <lu...@apache.org>
Authored: Tue Apr 11 08:46:24 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Tue Apr 11 08:46:24 2017 +0200

----------------------------------------------------------------------
 .../validators/FieldValidatorSupport.java       |  6 +--
 .../validators/RequiredStringValidator.java     | 42 +++++++++++++----
 .../validators/RequiredStringValidatorTest.java | 48 ++++++++++++++++++++
 .../validator/validators/ValidationAction.java  | 20 ++++++++
 4 files changed, 105 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/df5583f1/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
index ec75e13..07938c9 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
@@ -25,9 +25,9 @@ import com.opensymphony.xwork2.validator.FieldValidator;
  */
 public abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator {
 
-    private String fieldName;
-    private String type;
-    private Object currentValue;
+    protected String fieldName;
+    protected String type;
+    protected Object currentValue;
 
     public void setFieldName(String fieldName) {
         this.fieldName = fieldName;

http://git-wip-us.apache.org/repos/asf/struts/blob/df5583f1/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
index af2d807..433fd60 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
@@ -17,6 +17,7 @@ package com.opensymphony.xwork2.validator.validators;
 
 import com.opensymphony.xwork2.validator.ValidationException;
 
+import java.util.Collection;
 
 /**
  * <!-- START SNIPPET: javadoc -->
@@ -85,21 +86,46 @@ public class RequiredStringValidator extends FieldValidatorSupport {
     }
 
     public void validate(Object object) throws ValidationException {
-        String fieldName = getFieldName();
-        Object value = this.getFieldValue(fieldName, object);
+        Object fieldValue = this.getFieldValue(getFieldName(), object);
 
-        if (!(value instanceof String)) {
-            addFieldError(fieldName, object);
+        if (fieldValue == null) {
+            addFieldError(getFieldName(), object);
+            return;
+        }
+
+        if (fieldValue.getClass().isArray()) {
+            Object[] values = (Object[]) fieldValue;
+            for (Object value : values) {
+                validateValue(object, value);
+            }
+        } else if (Collection.class.isAssignableFrom(fieldValue.getClass())) {
+            Collection values = (Collection) fieldValue;
+            for (Object value : values) {
+                validateValue(object, value);
+            }
         } else {
-            String s = (String) value;
+            validateValue(object, fieldValue);
+        }
+    }
+
+    protected void validateValue(Object object, Object fieldValue) {
+        if (fieldValue == null) {
+            addFieldError(getFieldName(), object);
+            return;
+        }
+
+        if (fieldValue instanceof String) {
+            String stingValue = (String) fieldValue;
 
             if (trim) {
-                s = s.trim();
+                stingValue = stingValue.trim();
             }
 
-            if (s.length() == 0) {
-                addFieldError(fieldName, object);
+            if (stingValue.length() == 0) {
+                addFieldError(getFieldName(), object);
             }
+        } else {
+            addFieldError(getFieldName(), object);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/df5583f1/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidatorTest.java
index 8d4d919..9781bc1 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidatorTest.java
@@ -8,6 +8,8 @@ import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.validator.DummyValidatorContext;
 import com.opensymphony.xwork2.validator.ValidatorContext;
 
+import java.util.Arrays;
+
 public class RequiredStringValidatorTest extends XWorkTestCase {
 
     private TextProviderFactory tpf;
@@ -38,6 +40,52 @@ public class RequiredStringValidatorTest extends XWorkTestCase {
         assertTrue(context.getFieldErrors().size() == 0);
     }
 
+    public void testRequiredArrayOfStringsPass() throws Exception {
+        // given
+        ValueStack valueStack = ActionContext.getContext().getValueStack();
+
+        ValidationAction action = new ValidationAction();
+        action.setStrings(new String[]{"", "12334", null});
+        valueStack.push(action);
+
+        ValidatorContext context = new DummyValidatorContext(action, tpf);
+        RequiredStringValidator validator = new RequiredStringValidator();
+        validator.setValidatorContext(context);
+        validator.setFieldName("strings");
+        validator.setValueStack(valueStack);
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals(2, context.getFieldErrors().get("strings").size());
+    }
+
+    public void testRequiredCollectionOfStringsPass() throws Exception {
+        // given
+        ValueStack valueStack = ActionContext.getContext().getValueStack();
+
+        ValidationAction action = new ValidationAction();
+        action.setStringCollection(Arrays.asList("", "123456", null));
+        valueStack.push(action);
+
+        ValidatorContext context = new DummyValidatorContext(action, tpf);
+        RequiredStringValidator validator = new RequiredStringValidator();
+        validator.setValidatorContext(context);
+        validator.setFieldName("stringCollection");
+        validator.setValueStack(valueStack);
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals(2, context.getFieldErrors().get("stringCollection").size());
+    }
+
     public void testRequiredStringFails() throws Exception {
         // given
         ValueStack valueStack = ActionContext.getContext().getValueStack();

http://git-wip-us.apache.org/repos/asf/struts/blob/df5583f1/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
index a97cea6..ac7f56c 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/validators/ValidationAction.java
@@ -1,5 +1,6 @@
 package com.opensymphony.xwork2.validator.validators;
 
+import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 
@@ -22,8 +23,11 @@ public class ValidationAction {
     private Date dateRange;
     private Date dateMinValue;
     private Date dateMaxValue;
+
     private String dateFormat;
     private String stringValue;
+    private String[] strings;
+    private Collection<String> stringCollection;
 
     public Integer getIntRange() {
         return intRange;
@@ -152,4 +156,20 @@ public class ValidationAction {
     public void setShorts(List<Short> shorts) {
         this.shorts = shorts;
     }
+
+    public String[] getStrings() {
+        return strings;
+    }
+
+    public void setStrings(String[] strings) {
+        this.strings = strings;
+    }
+
+    public Collection<String> getStringCollection() {
+        return stringCollection;
+    }
+
+    public void setStringCollection(Collection<String> stringCollection) {
+        this.stringCollection = stringCollection;
+    }
 }


[07/13] struts git commit: WW-4578 Converts URL validator to support collections

Posted by lu...@apache.org.
WW-4578 Converts URL validator to support collections


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/6f272e48
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/6f272e48
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/6f272e48

Branch: refs/heads/master
Commit: 6f272e4873bdba03c1b3fe3ac8c0670b680d2c6c
Parents: 16e8f10
Author: Lukasz Lenart <lu...@apache.org>
Authored: Fri Apr 14 11:16:59 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Fri Apr 14 11:16:59 2017 +0200

----------------------------------------------------------------------
 .../validator/validators/URLValidator.java      |  43 ++-
 .../xwork2/validator/URLValidatorTest.java      | 347 +++++++++++--------
 2 files changed, 242 insertions(+), 148 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/6f272e48/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
index f12c286..d579e34 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
@@ -20,6 +20,8 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import java.util.Collection;
+import java.util.Objects;
 import java.util.regex.Pattern;
 
 /**
@@ -65,19 +67,48 @@ public class URLValidator extends FieldValidatorSupport {
     private Pattern urlPattern = Pattern.compile(DEFAULT_URL_REGEX, Pattern.CASE_INSENSITIVE);
 
     public void validate(Object object) throws ValidationException {
-        String fieldName = getFieldName();
-        Object value = this.getFieldValue(fieldName, object);
+        Object value = getFieldValue(fieldName, object);
 
         // if there is no value - don't do comparison
         // if a value is required, a required validator should be added to the field
-        if (value == null || value.toString().length() == 0) {
+        String stringValue = Objects.toString(value, "").trim();
+        if (stringValue.length() == 0) {
+            LOG.debug("Value for field {} is empty, won't ba validated, please use required validator", fieldName);
             return;
         }
 
-        String stringValue = String.valueOf(value).trim();
+        if (value.getClass().isArray()) {
+            Object[] values = (Object[]) value;
+            for (Object objValue : values) {
+                LOG.debug("Validating element of array: {}", objValue);
+                validateValue(object, objValue);
+            }
+        } else if (Collection.class.isAssignableFrom(value.getClass())) {
+            Collection values = (Collection) value;
+            for (Object objValue : values) {
+                LOG.debug("Validating element of collection: {}", objValue);
+                validateValue(object, objValue);
+            }
+        } else {
+            LOG.debug("Validating field: {}", value);
+            validateValue(object, value);
+        }
+    }
 
-        if (!(value.getClass().equals(String.class)) || !getUrlPattern().matcher(stringValue).matches()) {
-            addFieldError(fieldName, object);
+    protected void validateValue(Object object, Object value) {
+        String stringValue = Objects.toString(value, "").trim();
+        if (stringValue.length() == 0) {
+            LOG.debug("Value for field {} is empty, won't ba validated, please use required validator", fieldName);
+            return;
+        }
+
+        try {
+            setCurrentValue(value);
+            if (!(value.getClass().equals(String.class)) || !getUrlPattern().matcher(stringValue).matches()) {
+                addFieldError(fieldName, object);
+            }
+        } finally {
+            setCurrentValue(null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/6f272e48/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java
index b961d78..5c83dd1 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/URLValidatorTest.java
@@ -22,96 +22,98 @@ import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.validator.validators.URLValidator;
 import org.apache.commons.validator.routines.UrlValidator;
 
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Pattern;
 
 /**
  * Test case for URLValidator
- * 
+ *
  * @author tm_jee
  * @version $Date$ $Id$
  */
 public class URLValidatorTest extends XWorkTestCase {
 
-	
-	ValueStack stack;
-	ActionContext actionContext;
-	private TextProviderFactory tpf;
 
-	public void testAcceptNullValueForMutualExclusionOfValidators() throws Exception {
-		
-		URLValidator validator = new URLValidator();
-		validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
-		validator.setFieldName("testingUrl1");
+    ValueStack stack;
+    ActionContext actionContext;
+    private TextProviderFactory tpf;
+
+    public void testAcceptNullValueForMutualExclusionOfValidators() throws Exception {
+
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("testingUrl1");
         validator.setValueStack(ActionContext.getContext().getValueStack());
         validator.validate(new MyObject());
-		
-		assertFalse(validator.getValidatorContext().hasErrors());
-		assertFalse(validator.getValidatorContext().hasActionErrors());
-		assertFalse(validator.getValidatorContext().hasActionMessages());
-		assertFalse(validator.getValidatorContext().hasFieldErrors());
-	}
-	
-	public void testInvalidEmptyValue() throws Exception {
-		
-		URLValidator validator = new URLValidator();
-		validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
-		validator.setFieldName("testingUrl2");
+
+        assertFalse(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertFalse(validator.getValidatorContext().hasFieldErrors());
+    }
+
+    public void testInvalidEmptyValue() throws Exception {
+
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("testingUrl2");
         validator.setValueStack(ActionContext.getContext().getValueStack());
         validator.validate(new MyObject());
-		
-		assertFalse(validator.getValidatorContext().hasErrors());
-		assertFalse(validator.getValidatorContext().hasActionErrors());
-		assertFalse(validator.getValidatorContext().hasActionMessages());
-		assertFalse(validator.getValidatorContext().hasFieldErrors());
-	}
-	
-	public void testInvalidValue() throws Exception {
-		
-		URLValidator validator = new URLValidator();
-		validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
-		validator.setFieldName("testingUrl3");
+
+        assertFalse(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertFalse(validator.getValidatorContext().hasFieldErrors());
+    }
+
+    public void testInvalidValue() throws Exception {
+
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("testingUrl3");
         validator.setValueStack(ActionContext.getContext().getValueStack());
         validator.validate(new MyObject());
-		
-		assertTrue(validator.getValidatorContext().hasErrors());
-		assertFalse(validator.getValidatorContext().hasActionErrors());
-		assertFalse(validator.getValidatorContext().hasActionMessages());
-		assertTrue(validator.getValidatorContext().hasFieldErrors());
-	}
-	
-	
-	public void testValidUrl1() throws Exception {
-		
-		URLValidator validator = new URLValidator();
-		validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
-		validator.setFieldName("testingUrl4");
+
+        assertTrue(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertTrue(validator.getValidatorContext().hasFieldErrors());
+    }
+
+
+    public void testValidUrl1() throws Exception {
+
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("testingUrl4");
         validator.setValueStack(ActionContext.getContext().getValueStack());
         validator.validate(new MyObject());
-		
-		assertFalse(validator.getValidatorContext().hasErrors());
-		assertFalse(validator.getValidatorContext().hasActionErrors());
-		assertFalse(validator.getValidatorContext().hasActionMessages());
-		assertFalse(validator.getValidatorContext().hasFieldErrors());
-	}
-	
-	public void testValidUrl2() throws Exception {
-		
-		URLValidator validator = new URLValidator();
-		validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
-		validator.setFieldName("testingUrl5");
+
+        assertFalse(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertFalse(validator.getValidatorContext().hasFieldErrors());
+    }
+
+    public void testValidUrl2() throws Exception {
+
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("testingUrl5");
         validator.setValueStack(ActionContext.getContext().getValueStack());
         validator.validate(new MyObject());
-		
-		assertFalse(validator.getValidatorContext().hasErrors());
-		assertFalse(validator.getValidatorContext().hasActionErrors());
-		assertFalse(validator.getValidatorContext().hasActionMessages());
-		assertFalse(validator.getValidatorContext().hasFieldErrors());
-	}
-	
-	public void testValidUrlWithRegex() throws Exception {
-		URLValidator validator = new URLValidator();
+
+        assertFalse(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertFalse(validator.getValidatorContext().hasFieldErrors());
+    }
+
+    public void testValidUrlWithRegex() throws Exception {
+        URLValidator validator = new URLValidator();
 
         validator.setUrlRegex("^myapp:\\/\\/[a-z]*\\.com$");
 
@@ -119,10 +121,10 @@ public class URLValidatorTest extends XWorkTestCase {
 
         assertTrue(pattern.matcher("myapp://test.com").matches());
         assertFalse(pattern.matcher("myap://test.com").matches());
-	}
+    }
 
-	public void testValidUrlWithRegexExpression() throws Exception {
-		URLValidator validator = new URLValidator();
+    public void testValidUrlWithRegexExpression() throws Exception {
+        URLValidator validator = new URLValidator();
         ActionContext.getContext().getValueStack().push(new MyAction());
         validator.setValueStack(ActionContext.getContext().getValueStack());
         validator.setUrlRegexExpression("${urlRegex}");
@@ -131,10 +133,10 @@ public class URLValidatorTest extends XWorkTestCase {
 
         assertTrue(pattern.matcher("myapp://test.com").matches());
         assertFalse(pattern.matcher("myap://test.com").matches());
-	}
+    }
 
-	public void testValidUrlWithDefaultRegex() throws Exception {
-		URLValidator validator = new URLValidator();
+    public void testValidUrlWithDefaultRegex() throws Exception {
+        URLValidator validator = new URLValidator();
 
         Pattern pattern = Pattern.compile(validator.getUrlRegex(), Pattern.CASE_INSENSITIVE);
 
@@ -143,7 +145,7 @@ public class URLValidatorTest extends XWorkTestCase {
         assertFalse(pattern.matcher("").matches());
         assertFalse(pattern.matcher("   ").matches());
         assertFalse(pattern.matcher("no url").matches());
-		assertFalse(pattern.matcher("http://example.com////////////////////////////////////////////////////////////////////////////////////??").matches());
+        assertFalse(pattern.matcher("http://example.com////////////////////////////////////////////////////////////////////////////////////??").matches());
 
         assertTrue(pattern.matcher("http://www.opensymphony.com").matches());
         assertTrue(pattern.matcher("https://www.opensymphony.com").matches());
@@ -153,91 +155,152 @@ public class URLValidatorTest extends XWorkTestCase {
         assertTrue(pattern.matcher("http://www.legalspace.com/__media__/js/netsoltrademark.php?d=www.a-vos-travaux.fr%2Facheter-un-aspirateur-sans-sac-pas-cher%2F").matches());
         assertTrue(UrlValidator.getInstance().isValid("http://www.legalspace.com/__media__/js/netsoltrademark.php?d=www.a-vos-travaux.fr%2Facheter-un-aspirateur-sans-sac-pas-cher%2F"));
 
-		assertTrue(pattern.matcher("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa").matches());
-		assertTrue(UrlValidator.getInstance().isValid("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa"));
+        assertTrue(pattern.matcher("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa").matches());
+        assertTrue(UrlValidator.getInstance().isValid("http://www.duadmin.isaev.Infoduadmin.Isaev.info/?a%5B%5D=%3Ca%20href%3Dhttp%3A%2F%2Fwww.aspert.fr%2Fun-seche-cheveux-lisseur-est-il-vraiment-utile%2F%3Eseche%20cheveux%20dyson%20test%3C%2Fa"));
 
-		assertTrue(pattern.matcher("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F").matches());
-		assertTrue(UrlValidator.getInstance().isValid("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F"));
-	}
+        assertTrue(pattern.matcher("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F").matches());
+        assertTrue(UrlValidator.getInstance().isValid("http://netsol-underconstruction-page-monitor-1.com/__media__/js/netsoltrademark.php?d=www.le-soutien-scolaire.fr%2Favis-et-test-comparatifs-des-robots-multifonctions%2F"));
+    }
 
-	public void testValidUrlCaseInsensitive() throws Exception {
-		// given
-		final Map<String, Object> fieldErrors = new HashMap<>();
+    public void testValidUrlCaseInsensitive() throws Exception {
+        // given
+        final Map<String, Object> fieldErrors = new HashMap<>();
 
-		URLValidator validator = new URLValidator() {
-			@Override
-			public String getFieldName() {
-				return "url";
-			}
+        URLValidator validator = new URLValidator() {
+            @Override
+            public String getFieldName() {
+                return "url";
+            }
 
-			@Override
-			protected Object getFieldValue(String name, Object object) throws ValidationException {
-				return object;
-			}
+            @Override
+            protected Object getFieldValue(String name, Object object) throws ValidationException {
+                return object;
+            }
 
-			@Override
-			protected void addFieldError(String propertyName, Object object) {
-				fieldErrors.put(propertyName, object);
-			}
-		};
+            @Override
+            protected void addFieldError(String propertyName, Object object) {
+                fieldErrors.put(propertyName, object);
+            }
+        };
 
-		// when
+        // when
         validator.validate("http://localhost:8080/myapp");
 
-		// then
-		assertTrue(fieldErrors.isEmpty());
+        // then
+        assertTrue(fieldErrors.isEmpty());
 
-		// when
+        // when
         validator.validate("http://LOCALHOST:8080/MYAPP");
 
-		// then
-		assertTrue(fieldErrors.isEmpty());
+        // then
+        assertTrue(fieldErrors.isEmpty());
 
-		// when
+        // when
         validator.validate("http://www.appache.org/TEST");
 
-		// then
-		assertTrue(fieldErrors.isEmpty());
+        // then
+        assertTrue(fieldErrors.isEmpty());
+    }
+
+    public void testArrayOfUrls() throws Exception {
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("urls");
+        validator.setValueStack(ActionContext.getContext().getValueStack());
+        validator.validate(new MyObject());
+
+        assertTrue(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertTrue(validator.getValidatorContext().hasFieldErrors());
+        assertEquals(1, validator.getValidatorContext().getFieldErrors().get("urls").size());
     }
 
-	@Override
+    public void testCollectionOfUrls() throws Exception {
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("urlCollection");
+        validator.setValueStack(ActionContext.getContext().getValueStack());
+        validator.setDefaultMessage("Wrong URL provided: ${currentValue}");
+        validator.validate(new MyObject());
+
+        assertTrue(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertTrue(validator.getValidatorContext().hasFieldErrors());
+        assertEquals(1, validator.getValidatorContext().getFieldErrors().get("urlCollection").size());
+        assertEquals("Wrong URL provided: htps://wrong.side.com", validator.getValidatorContext().getFieldErrors().get("urlCollection").get(0));
+    }
+
+    public void testCollectionOfUrlsSafness() throws Exception {
+        URLValidator validator = new URLValidator();
+        validator.setValidatorContext(new DummyValidatorContext(new Object(), tpf));
+        validator.setFieldName("urlSafeness");
+        validator.setValueStack(ActionContext.getContext().getValueStack());
+        validator.setDefaultMessage("Wrong URL provided: ${currentValue}");
+        validator.validate(new MyObject());
+
+        assertTrue(validator.getValidatorContext().hasErrors());
+        assertFalse(validator.getValidatorContext().hasActionErrors());
+        assertFalse(validator.getValidatorContext().hasActionMessages());
+        assertTrue(validator.getValidatorContext().hasFieldErrors());
+        assertEquals(2, validator.getValidatorContext().getFieldErrors().get("urlSafeness").size());
+        assertEquals("Wrong URL provided: ${1+2}", validator.getValidatorContext().getFieldErrors().get("urlSafeness").get(0));
+        assertEquals("Wrong URL provided: %{2+3}", validator.getValidatorContext().getFieldErrors().get("urlSafeness").get(1));
+    }
+
+    @Override
     protected void setUp() throws Exception {
-	    super.setUp();
-		stack = ActionContext.getContext().getValueStack();
-		actionContext = ActionContext.getContext();
-		tpf = container.getInstance(TextProviderFactory.class);
-	}
-	
-	@Override
+        super.setUp();
+        stack = ActionContext.getContext().getValueStack();
+        actionContext = ActionContext.getContext();
+        tpf = container.getInstance(TextProviderFactory.class);
+    }
+
+    @Override
     protected void tearDown() throws Exception {
-	    super.tearDown();
-		stack = null;
-		actionContext = null;
-	}
-	
-	
-	class MyObject {
-		public String getTestingUrl1() {
-			return null;
-		}
-		
-		public String getTestingUrl2() {
-			return "";
-		}
-		
-		public String getTestingUrl3() {
-			return "sasdasd@asddd";
-		}
-		
-		public String getTestingUrl4() {
-			//return "http://yahoo.com/";
-			return "http://www.jroller.com1?qwe=qwe";
-		}
-		
-		public String getTestingUrl5() {
-			return "http://yahoo.com/articles?id=123\n";
-		}
-	}
+        super.tearDown();
+        stack = null;
+        actionContext = null;
+    }
+
+
+    class MyObject {
+        public String getTestingUrl1() {
+            return null;
+        }
+
+        public String getTestingUrl2() {
+            return "";
+        }
+
+        public String getTestingUrl3() {
+            return "sasdasd@asddd";
+        }
+
+        public String getTestingUrl4() {
+            //return "http://yahoo.com/";
+            return "http://www.jroller.com1?qwe=qwe";
+        }
+
+        public String getTestingUrl5() {
+            return "http://yahoo.com/articles?id=123\n";
+        }
+
+        public String[] getUrls() {
+            return new String[]{
+                    "https://struts.apache.org",
+                    "htps://wrong.side.com"
+            };
+        }
+
+        public Collection<String> getUrlCollection() {
+            return Arrays.asList("https://struts.apache.org","htps://wrong.side.com");
+        }
+        public Collection<String> getUrlSafeness() {
+            return Arrays.asList("https://struts.apache.org","${1+2}", "%{2+3}");
+        }
+    }
 
     class MyAction {
 


[06/13] struts git commit: WW-4578 Converts length string validator to support collections

Posted by lu...@apache.org.
WW-4578 Converts length string validator to support collections


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/16e8f10f
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/16e8f10f
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/16e8f10f

Branch: refs/heads/master
Commit: 16e8f10f6664f4d5abbc64650a0b7a93cd49290b
Parents: df5583f
Author: Lukasz Lenart <lu...@apache.org>
Authored: Tue Apr 11 09:10:19 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Tue Apr 11 09:10:19 2017 +0200

----------------------------------------------------------------------
 .../validators/StringLengthFieldValidator.java  |  45 +++-
 .../StringLengthFieldValidatorTest.java         | 270 +++++++++++--------
 2 files changed, 192 insertions(+), 123 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/16e8f10f/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
index 9d28a55..0c4f0fc 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
@@ -17,6 +17,11 @@ package com.opensymphony.xwork2.validator.validators;
 
 import com.opensymphony.xwork2.validator.ValidationException;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.Collection;
+import java.util.Objects;
 
 /**
  * <!-- START SNIPPET: javadoc -->
@@ -84,6 +89,8 @@ import org.apache.commons.lang3.StringUtils;
  */
 public class StringLengthFieldValidator extends FieldValidatorSupport {
 
+    private static final Logger LOG = LogManager.getLogger(StringLengthFieldValidator.class);
+
     private boolean trim = true;
     private int maxLength = -1;
     private int minLength = -1;
@@ -138,17 +145,37 @@ public class StringLengthFieldValidator extends FieldValidatorSupport {
     }
 
     public void validate(Object object) throws ValidationException {
-        String fieldName = getFieldName();
-        String val = (String) getFieldValue(fieldName, object);
+        Object fieldValue = getFieldValue(fieldName, object);
+
+        if (fieldValue == null) {
+            LOG.debug("Value for field {} is null, use a required validator", getFieldName());
+        } else if (fieldValue.getClass().isArray()) {
+            Object[] values = (Object[]) fieldValue;
+            for (Object value : values) {
+                validateValue(object, value);
+            }
+        } else if (Collection.class.isAssignableFrom(fieldValue.getClass())) {
+            Collection values = (Collection) fieldValue;
+            for (Object value : values) {
+                validateValue(object, value);
+            }
+        } else {
+            validateValue(object, fieldValue);
+        }
+    }
 
-        if (StringUtils.isEmpty(val)) {
-            // use a required validator for these
+    protected void validateValue(Object object, Object value) {
+        String stringValue = Objects.toString(value, "");
+
+        if (StringUtils.isEmpty(stringValue)) {
+            LOG.debug("Value is empty, use a required validator");
             return;
         }
+
         if (isTrim()) {
-            val = val.trim();
-            if (val.length() <= 0) {
-                // use a required validator
+            stringValue = stringValue.trim();
+            if (StringUtils.isEmpty(stringValue)) {
+                LOG.debug("Value is empty, use a required validator");
                 return;
             }
         }
@@ -156,9 +183,9 @@ public class StringLengthFieldValidator extends FieldValidatorSupport {
         int minLengthToUse = getMinLength();
         int maxLengthToUse = getMaxLength();
 
-        if ((minLengthToUse > -1) && (val.length() < minLengthToUse)) {
+        if ((minLengthToUse > -1) && (stringValue.length() < minLengthToUse)) {
             addFieldError(fieldName, object);
-        } else if ((maxLengthToUse > -1) && (val.length() > maxLengthToUse)) {
+        } else if ((maxLengthToUse > -1) && (stringValue.length() > maxLengthToUse)) {
             addFieldError(fieldName, object);
         }
     }

http://git-wip-us.apache.org/repos/asf/struts/blob/16e8f10f/core/src/test/java/com/opensymphony/xwork2/validator/StringLengthFieldValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/StringLengthFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/StringLengthFieldValidatorTest.java
index ee6daf7..26e3335 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/StringLengthFieldValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/StringLengthFieldValidatorTest.java
@@ -22,106 +22,130 @@ import com.opensymphony.xwork2.XWorkTestCase;
 import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator;
 
+import java.util.Arrays;
+import java.util.Collection;
+
 /**
- * 
  * @author tm_jee
  * @version $Date$ $Id$
  */
 public class StringLengthFieldValidatorTest extends XWorkTestCase {
 
-	protected InternalActionSupport action;
-	protected StringLengthFieldValidator validator;
-	
-	public void testStringLengthEmptyNoTrim1() throws Exception {
-		action.setMyField("");
-		
-		validator.setTrim(false);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), "");
-		assertFalse(action.hasFieldErrors());
-	}
-	
-	public void testStringLengthNullNoTrim() throws Exception {
-		action.setMyField(null);
-
-		validator.setTrim(false);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), null);
-		assertFalse(action.hasFieldErrors());
-	}
-	
-	public void testStringLengthEmptyTrim1() throws Exception {
-		action.setMyField("   ");
-		
-		validator.setTrim(true);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), "   ");
-		assertFalse(action.hasFieldErrors());
-	}
-	
-	public void testStringLengthEmptyNoTrim2() throws Exception {
-		action.setMyField("          ");
-		
-		validator.setTrim(false);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), "          ");
-		assertTrue(action.hasFieldErrors());
-	}
-	
-	
-	public void testStringLengthNullTrim() throws Exception {
-		action.setMyField(null);
-
-		validator.setTrim(true);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), null);
-		assertFalse(action.hasFieldErrors());
-	}
-	
-	public void testInvalidStringLengthNoTrim() throws Exception {
-		action.setMyField("abcdefghijklmn");
-		
-		validator.setTrim(false);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), "abcdefghijklmn");
-		assertTrue(action.hasFieldErrors());
-	}
-	
-	public void testInvalidStringLengthTrim() throws Exception {
-		action.setMyField("abcdefghijklmn   ");
-		
-		validator.setTrim(true);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), "abcdefghijklmn   ");
-		assertTrue(action.hasFieldErrors());
-	}
-	
-	public void testValidStringLengthNoTrim() throws Exception {
-		action.setMyField("   ");
-		
-		validator.setTrim(false);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), "   ");
-		assertFalse(action.hasFieldErrors());
-	}
-	
-	public void testValidStringLengthTrim() throws Exception {
-		action.setMyField("asd          ");
-		
-		validator.setTrim(true);
-		validator.validate(action);
-		
-		assertEquals(action.getMyField(), "asd          ");
-		assertFalse(action.hasFieldErrors());
-	}
+    protected InternalActionSupport action;
+    protected StringLengthFieldValidator validator;
+
+    public void testStringLengthEmptyNoTrim1() throws Exception {
+        action.setMyField("");
+
+        validator.setTrim(false);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), "");
+        assertFalse(action.hasFieldErrors());
+    }
+
+    public void testStringLengthNullNoTrim() throws Exception {
+        action.setMyField(null);
+
+        validator.setTrim(false);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), null);
+        assertFalse(action.hasFieldErrors());
+    }
+
+    public void testStringLengthEmptyTrim1() throws Exception {
+        action.setMyField("   ");
+
+        validator.setTrim(true);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), "   ");
+        assertFalse(action.hasFieldErrors());
+    }
+
+    public void testStringLengthEmptyNoTrim2() throws Exception {
+        action.setMyField("          ");
+
+        validator.setTrim(false);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), "          ");
+        assertTrue(action.hasFieldErrors());
+    }
+
+
+    public void testStringLengthNullTrim() throws Exception {
+        action.setMyField(null);
+
+        validator.setTrim(true);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), null);
+        assertFalse(action.hasFieldErrors());
+    }
+
+    public void testInvalidStringLengthNoTrim() throws Exception {
+        action.setMyField("abcdefghijklmn");
+
+        validator.setTrim(false);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), "abcdefghijklmn");
+        assertTrue(action.hasFieldErrors());
+    }
+
+    public void testInvalidStringLengthTrim() throws Exception {
+        action.setMyField("abcdefghijklmn   ");
+
+        validator.setTrim(true);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), "abcdefghijklmn   ");
+        assertTrue(action.hasFieldErrors());
+    }
+
+    public void testValidStringLengthNoTrim() throws Exception {
+        action.setMyField("   ");
+
+        validator.setTrim(false);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), "   ");
+        assertFalse(action.hasFieldErrors());
+    }
+
+    public void testValidStringLengthTrim() throws Exception {
+        action.setMyField("asd          ");
+
+        validator.setTrim(true);
+        validator.validate(action);
+
+        assertEquals(action.getMyField(), "asd          ");
+        assertFalse(action.hasFieldErrors());
+    }
+
+    public void testArrayOfStringsLengthTrim() throws Exception {
+        action.setStrings(new String[]{"123456", "    ", null});
+
+        validator.setFieldName("strings");
+        validator.setTrim(true);
+        validator.validate(action);
+
+        assertTrue(action.hasFieldErrors());
+        assertEquals(1, action.getFieldErrors().get("strings").size());
+    }
+
+    public void testCollectionOfStringsLengthTrim() throws Exception {
+        action.setStringCollection(Arrays.asList("123456", "    ", null));
+
+        validator.setFieldName("stringCollection");
+        validator.setTrim(true);
+        validator.validate(action);
+
+        assertTrue(action.hasFieldErrors());
+        assertEquals(1, action.getFieldErrors().get("stringCollection").size());
+    }
 
     public void testMinLengthViaExpression() throws Exception {
         assertEquals(2, validator.getMinLength());
@@ -151,41 +175,44 @@ public class StringLengthFieldValidatorTest extends XWorkTestCase {
     }
 
     @Override
-	protected void setUp() throws Exception {
-		super.setUp();
+    protected void setUp() throws Exception {
+        super.setUp();
 
         action = new InternalActionSupport();
-		container.inject(action);
+        container.inject(action);
 
         ValueStack valueStack = ActionContext.getContext().getValueStack();
         valueStack.push(action);
 
-		validator = new StringLengthFieldValidator();
-		validator.setFieldName("myField");
-		validator.setMessageKey("error");
-		validator.setValidatorContext(new DelegatingValidatorContext(action, container.getInstance(TextProviderFactory.class)));
-		validator.setMaxLength(5);
-		validator.setMinLength(2);
+        validator = new StringLengthFieldValidator();
+        validator.setFieldName("myField");
+        validator.setMessageKey("error");
+        validator.setValidatorContext(new DelegatingValidatorContext(action, container.getInstance(TextProviderFactory.class)));
+        validator.setMaxLength(5);
+        validator.setMinLength(2);
         validator.setValueStack(valueStack);
     }
-	
-	
-	@Override
-	protected void tearDown() throws Exception {
-		super.tearDown();
-		action = null;
-		validator = null;
-	}
-	
-	public static class InternalActionSupport extends ActionSupport {
 
-		private static final long serialVersionUID = 1L;
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        action = null;
+        validator = null;
+    }
+
+    public static class InternalActionSupport extends ActionSupport {
+
+        private static final long serialVersionUID = 1L;
 
         private String myField;
         private boolean trimValue;
         private int minLengthValue;
         private int maxLengthValue;
 
+        private String[] strings;
+        private Collection<String> stringCollection;
+
         public String getMyField() {
             return this.myField;
         }
@@ -218,6 +245,21 @@ public class StringLengthFieldValidatorTest extends XWorkTestCase {
             this.maxLengthValue = maxLengthValue;
         }
 
+        public String[] getStrings() {
+            return strings;
+        }
+
+        public void setStrings(String[] strings) {
+            this.strings = strings;
+        }
+
+        public Collection<String> getStringCollection() {
+            return stringCollection;
+        }
+
+        public void setStringCollection(Collection<String> stringCollection) {
+            this.stringCollection = stringCollection;
+        }
     }
 
 }


[08/13] struts git commit: WW-4578 Fixes small typo

Posted by lu...@apache.org.
WW-4578 Fixes small typo


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/569e1f6c
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/569e1f6c
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/569e1f6c

Branch: refs/heads/master
Commit: 569e1f6c82dbb562f105279df68e3dd2cf0545bd
Parents: 6f272e4
Author: Lukasz Lenart <lu...@apache.org>
Authored: Fri Apr 14 11:18:39 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Fri Apr 14 11:18:39 2017 +0200

----------------------------------------------------------------------
 .../opensymphony/xwork2/validator/validators/URLValidator.java   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/569e1f6c/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
index d579e34..6dd29f7 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
@@ -73,7 +73,7 @@ public class URLValidator extends FieldValidatorSupport {
         // if a value is required, a required validator should be added to the field
         String stringValue = Objects.toString(value, "").trim();
         if (stringValue.length() == 0) {
-            LOG.debug("Value for field {} is empty, won't ba validated, please use required validator", fieldName);
+            LOG.debug("Value for field {} is empty, won't ba validated, please use a required validator", fieldName);
             return;
         }
 
@@ -98,7 +98,7 @@ public class URLValidator extends FieldValidatorSupport {
     protected void validateValue(Object object, Object value) {
         String stringValue = Objects.toString(value, "").trim();
         if (stringValue.length() == 0) {
-            LOG.debug("Value for field {} is empty, won't ba validated, please use required validator", fieldName);
+            LOG.debug("Value for field {} is empty, won't ba validated, please use a required validator", fieldName);
             return;
         }
 


[12/13] struts git commit: Puts back public scope for class

Posted by lu...@apache.org.
Puts back public scope for class


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/30ec6f83
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/30ec6f83
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/30ec6f83

Branch: refs/heads/master
Commit: 30ec6f83109747e0801c2019ba05f498fcb506bf
Parents: 034e098
Author: Lukasz Lenart <lu...@apache.org>
Authored: Fri Apr 14 12:54:20 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Fri Apr 14 12:54:20 2017 +0200

----------------------------------------------------------------------
 .../xwork2/validator/validators/FieldValidatorSupport.java         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/30ec6f83/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
index 07f6412..8ffffad 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/FieldValidatorSupport.java
@@ -23,7 +23,7 @@ import com.opensymphony.xwork2.validator.FieldValidator;
  * You can access fieldName and its currentValue in a message using expression, e.g.
  * "Wrong value ${currentValue} for ${fieldName}"
  */
-abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator {
+public abstract class FieldValidatorSupport extends ValidatorSupport implements FieldValidator {
 
     protected String fieldName;
     protected String type;


[13/13] struts git commit: WW-4578 Supports collections when validating a value

Posted by lu...@apache.org.
WW-4578 Supports collections when validating a value


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/5fd605eb
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/5fd605eb
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/5fd605eb

Branch: refs/heads/master
Commit: 5fd605eb974cdbaa2df57ec6f783f37a6106279f
Parents: 9d4aac0 30ec6f8
Author: Lukasz Lenart <lu...@apache.org>
Authored: Wed Apr 19 09:42:06 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Apr 19 09:42:06 2017 +0200

----------------------------------------------------------------------
 .../validators/DoubleRangeFieldValidator.java   |  55 ++-
 .../validators/FieldValidatorSupport.java       |  17 +-
 .../validators/RangeValidatorSupport.java       |  66 ++--
 .../validators/RegexFieldValidator.java         |  37 +-
 .../validators/RequiredFieldValidator.java      |   7 +
 .../validators/RequiredStringValidator.java     |  49 ++-
 .../validators/StringLengthFieldValidator.java  |  54 ++-
 .../validator/validators/URLValidator.java      |  45 ++-
 .../validator/validators/ValidatorSupport.java  |   2 +
 .../DoubleRangeFieldValidatorTest.java          | 363 +++++++++++++++++++
 .../validator/DoubleRangeValidatorTest.java     | 279 --------------
 .../validator/RegexFieldValidatorTest.java      |  70 ++++
 .../StringLengthFieldValidatorTest.java         | 270 ++++++++------
 .../xwork2/validator/URLValidatorTest.java      | 347 ++++++++++--------
 .../validators/IntRangeFieldValidatorTest.java  |  23 ++
 .../validators/RequiredFieldValidatorTest.java  |  78 ++++
 .../validators/RequiredStringValidatorTest.java |  48 +++
 .../validator/validators/ValidationAction.java  |  39 ++
 18 files changed, 1236 insertions(+), 613 deletions(-)
----------------------------------------------------------------------



[09/13] struts git commit: WW-4578 Cleans up code

Posted by lu...@apache.org.
WW-4578 Cleans up code


Project: http://git-wip-us.apache.org/repos/asf/struts/repo
Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/1ad6d2c3
Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/1ad6d2c3
Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/1ad6d2c3

Branch: refs/heads/master
Commit: 1ad6d2c31726864275458c02f9cbbe22936f7833
Parents: 569e1f6
Author: Lukasz Lenart <lu...@apache.org>
Authored: Fri Apr 14 11:25:22 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Fri Apr 14 11:25:22 2017 +0200

----------------------------------------------------------------------
 .../validators/RegexFieldValidator.java         | 24 ++++++++--------
 .../validators/RequiredStringValidator.java     | 29 ++++++++++++--------
 .../validators/StringLengthFieldValidator.java  | 13 ++++++---
 .../validator/validators/URLValidator.java      |  6 ++--
 4 files changed, 39 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/1ad6d2c3/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
index b1ca900..eff835c 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RegexFieldValidator.java
@@ -95,9 +95,9 @@ public class RegexFieldValidator extends FieldValidatorSupport {
     private String regex;
     private String regexExpression;
     private Boolean caseSensitive = true;
-    private String caseSensitiveExpression = "";
+    private String caseSensitiveExpression = EMPTY_STRING;
     private Boolean trim = true;
-    private String trimExpression = "";
+    private String trimExpression = EMPTY_STRING;
 
     public void validate(Object object) throws ValidationException {
         String fieldName = getFieldName();
@@ -108,32 +108,30 @@ public class RegexFieldValidator extends FieldValidatorSupport {
         LOG.debug("Defined regexp as [{}]", regexToUse);
 
         if (value == null || regexToUse == null) {
+            LOG.debug("Either value is empty (please use a required validator) or regex is empty");
             return;
         }
 
-        if (value instanceof String) {
-            validateFieldValue(object, fieldName, (String) value, regexToUse);
-        }
-
         if (value.getClass().isArray()) {
             Object[] values = (Object[]) value;
             for (Object objValue: values) {
-                validateFieldValue(object, fieldName, Objects.toString(objValue, EMPTY_STRING), regexToUse);
+                validateFieldValue(object, Objects.toString(objValue, EMPTY_STRING), regexToUse);
             }
-        }
-
-        if (Collection.class.isAssignableFrom(value.getClass())) {
-            Collection<Object> values = (Collection<Object>) value;
+        } else if (Collection.class.isAssignableFrom(value.getClass())) {
+            Collection values = (Collection) value;
             for (Object objValue : values) {
-                validateFieldValue(object, fieldName, Objects.toString(objValue, EMPTY_STRING), regexToUse);
+                validateFieldValue(object, Objects.toString(objValue, EMPTY_STRING), regexToUse);
             }
+        } else {
+           validateFieldValue(object, Objects.toString(value, EMPTY_STRING), regexToUse);
         }
     }
 
-    protected void validateFieldValue(Object object, String fieldName, String value, String regexToUse) {
+    protected void validateFieldValue(Object object, String value, String regexToUse) {
         // string must not be empty
         String str = value.trim();
         if (str.length() == 0) {
+            LOG.debug("Value is empty, please use a required validator");
             return;
         }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/1ad6d2c3/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
index 433fd60..d11ff4e 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/RequiredStringValidator.java
@@ -109,23 +109,28 @@ public class RequiredStringValidator extends FieldValidatorSupport {
     }
 
     protected void validateValue(Object object, Object fieldValue) {
-        if (fieldValue == null) {
-            addFieldError(getFieldName(), object);
-            return;
-        }
+        try {
+            setCurrentValue(fieldValue);
+            if (fieldValue == null) {
+                addFieldError(getFieldName(), object);
+                return;
+            }
 
-        if (fieldValue instanceof String) {
-            String stingValue = (String) fieldValue;
+            if (fieldValue instanceof String) {
+                String stingValue = (String) fieldValue;
 
-            if (trim) {
-                stingValue = stingValue.trim();
-            }
+                if (trim) {
+                    stingValue = stingValue.trim();
+                }
 
-            if (stingValue.length() == 0) {
+                if (stingValue.length() == 0) {
+                    addFieldError(getFieldName(), object);
+                }
+            } else {
                 addFieldError(getFieldName(), object);
             }
-        } else {
-            addFieldError(getFieldName(), object);
+        } finally {
+            setCurrentValue(null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/1ad6d2c3/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
index 0c4f0fc..2e1957d 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/StringLengthFieldValidator.java
@@ -183,10 +183,15 @@ public class StringLengthFieldValidator extends FieldValidatorSupport {
         int minLengthToUse = getMinLength();
         int maxLengthToUse = getMaxLength();
 
-        if ((minLengthToUse > -1) && (stringValue.length() < minLengthToUse)) {
-            addFieldError(fieldName, object);
-        } else if ((maxLengthToUse > -1) && (stringValue.length() > maxLengthToUse)) {
-            addFieldError(fieldName, object);
+        try {
+            setCurrentValue(stringValue);
+            if ((minLengthToUse > -1) && (stringValue.length() < minLengthToUse)) {
+                addFieldError(fieldName, object);
+            } else if ((maxLengthToUse > -1) && (stringValue.length() > maxLengthToUse)) {
+                addFieldError(fieldName, object);
+            }
+        } finally {
+            setCurrentValue(null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/1ad6d2c3/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
index 6dd29f7..eab0fa8 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/URLValidator.java
@@ -69,9 +69,7 @@ public class URLValidator extends FieldValidatorSupport {
     public void validate(Object object) throws ValidationException {
         Object value = getFieldValue(fieldName, object);
 
-        // if there is no value - don't do comparison
-        // if a value is required, a required validator should be added to the field
-        String stringValue = Objects.toString(value, "").trim();
+        String stringValue = Objects.toString(value, EMPTY_STRING).trim();
         if (stringValue.length() == 0) {
             LOG.debug("Value for field {} is empty, won't ba validated, please use a required validator", fieldName);
             return;
@@ -96,7 +94,7 @@ public class URLValidator extends FieldValidatorSupport {
     }
 
     protected void validateValue(Object object, Object value) {
-        String stringValue = Objects.toString(value, "").trim();
+        String stringValue = Objects.toString(value, EMPTY_STRING).trim();
         if (stringValue.length() == 0) {
             LOG.debug("Value for field {} is empty, won't ba validated, please use a required validator", fieldName);
             return;