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/24 08:12:21 UTC

[1/8] struts git commit: WW-3952 Adds implementation of credit card validator

Repository: struts
Updated Branches:
  refs/heads/master faf72b5a0 -> 775d1c8c6


WW-3952 Adds implementation of credit card validator


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

Branch: refs/heads/master
Commit: 01d710bdf3dace8cf964bcd32d0afe14cf251dc2
Parents: 293d2fd
Author: Lukasz Lenart <lu...@apache.org>
Authored: Wed Apr 19 18:05:53 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Apr 19 18:05:53 2017 +0200

----------------------------------------------------------------------
 .../validators/CreditCardValidator.java         | 46 ++++++++++++++++++++
 1 file changed, 46 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/01d710bd/core/src/main/java/com/opensymphony/xwork2/validator/validators/CreditCardValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/CreditCardValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/CreditCardValidator.java
new file mode 100644
index 0000000..94ee646
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/CreditCardValidator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.opensymphony.xwork2.validator.validators;
+
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * CreditCardFieldValidator checks that a given String/Array/Collection field,
+ * if not empty, is a valid credit card number.
+ */
+public class CreditCardValidator extends RegexFieldValidator {
+
+    public static final String CREDIT_CARD_PATTERN =
+                    "^(?:4[0-9]{12}(?:[0-9]{3})?" + // Visa
+                    "|(?:5[1-5][0-9]{2}" + // MasterCard
+                    "|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}" +
+                    "|3[47][0-9]{13}" + // American Express
+                    "|3(?:0[0-5]|[68][0-9])[0-9]{11}" + // Diners Club
+                    "|6(?:011|5[0-9]{2})[0-9]{12}" + // Discover
+                    "|(?:2131|1800|35\\d{3})\\d{11}" + // JCB
+                    ")$";
+
+    public CreditCardValidator() {
+        setRegex(CREDIT_CARD_PATTERN);
+        setCaseSensitive(false);
+    }
+
+    protected void validateFieldValue(Object object, String value, String regexToUse) {
+        super.validateFieldValue(object, StringUtils.deleteWhitespace(value), regexToUse);
+    }
+
+}


[7/8] struts git commit: WW-3952 Fixes test

Posted by lu...@apache.org.
WW-3952 Fixes test


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

Branch: refs/heads/master
Commit: 6ef9f7a3aadd1c9dea5ca7a7a5ae350f37e6e96b
Parents: 9eec07b
Author: Lukasz Lenart <lu...@apache.org>
Authored: Sun Apr 23 10:31:13 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Sun Apr 23 10:31:13 2017 +0200

----------------------------------------------------------------------
 .../resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt  | 8 ++++----
 .../resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt | 8 ++++----
 .../resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt | 8 ++++----
 3 files changed, 12 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/6ef9f7a3/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
index 806a94e..62d566c 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
@@ -36,9 +36,9 @@
     function validateForm_doubleValidationAction() {
         var getFieldValue = function(field) {
             var type = field.type ? field.type : field[0].type;
-            if(type == 'select-one' || type == 'select-multiple') {
-                return (field.selectedIndex == -1 ? "" : field.options[field.selectedIndex].value);
-            } else if(type=='checkbox'||type=='radio') {
+            if(type === 'select-one' || type === 'select-multiple') {
+                return (field.selectedIndex === -1 ? "" : field.options[field.selectedIndex].value);
+            } else if(type==='checkbox'||type==='radio') {
                 if(!field.length){
                     field=[field];
                 }
@@ -62,7 +62,7 @@
             field = form.elements['myUpDownSelectTag'];
             var error = "bar must be between 6000.1 and 10000.1.";
             var fieldValue=getFieldValue(field);
-            if(continueValidation && fieldValue != null) {
+            if(continueValidation && fieldValue !== null) {
                 var value = parseFloat(fieldValue);
                 if(value < 6000.1 || value>10000.1 || false || false){
                     addError(field, error);

http://git-wip-us.apache.org/repos/asf/struts/blob/6ef9f7a3/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
index 710ad54..136dc15 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-22.txt
@@ -35,9 +35,9 @@
     function validateForm_doubleValidationAction() {
         var getFieldValue = function(field) {
             var type = field.type ? field.type : field[0].type;
-            if(type == 'select-one' || type == 'select-multiple') {
-                return (field.selectedIndex == -1 ? "" : field.options[field.selectedIndex].value);
-            } else if(type == 'checkbox' || type == 'radio') {
+            if(type === 'select-one' || type === 'select-multiple') {
+                return (field.selectedIndex === -1 ? "" : field.options[field.selectedIndex].value);
+            } else if(type === 'checkbox' || type === 'radio') {
                 if(!field.length) {
                     field = [field];
                 }
@@ -61,7 +61,7 @@
             field = form.elements['myUpDownSelectTag'];
             var error = "bar must be between 6000.1 and 10000.1.";
             var fieldValue=getFieldValue(field);
-            if(continueValidation && fieldValue != null) {
+            if(continueValidation && fieldValue !== null) {
                 var value = parseFloat(fieldValue);
                 if(value < 6000.1 || value>10000.1 || false || false){
                     addError(field, error);

http://git-wip-us.apache.org/repos/asf/struts/blob/6ef9f7a3/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt
index f512ff4..a27432a 100644
--- a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-24.txt
@@ -35,9 +35,9 @@
     function validateForm_doubleValidationAction() {
         var getFieldValue = function(field) {
             var type = field.type ? field.type : field[0].type;
-            if(type == 'select-one' || type == 'select-multiple') {
-                return (field.selectedIndex == -1 ? "" : field.options[field.selectedIndex].value);
-            } else if(type == 'checkbox' || type == 'radio') {
+            if(type === 'select-one' || type === 'select-multiple') {
+                return (field.selectedIndex === -1 ? "" : field.options[field.selectedIndex].value);
+            } else if(type === 'checkbox' || type === 'radio') {
                 if(!field.length) {
                     field=[field];
                 }
@@ -61,7 +61,7 @@
             field = form.elements['myUpDownSelectTag'];
             var error = "bar must be between 6000.1 and 10000.1.";
             var fieldValue = getFieldValue(field);
-            if(continueValidation && fieldValue != null) {
+            if(continueValidation && fieldValue !== null) {
                 var value = parseFloat(fieldValue);
                 if(value < 6000.1 || value > 10000.1 || false || false) {
                     addError(field, error);


[5/8] struts git commit: WW-3952 Updates test to include credit card validation

Posted by lu...@apache.org.
WW-3952 Updates test to include credit card validation


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

Branch: refs/heads/master
Commit: eb4fcb4afc79dac03f6ed0780211f98e72a09851
Parents: 0813eaa
Author: Lukasz Lenart <lu...@apache.org>
Authored: Wed Apr 19 18:07:38 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Apr 19 18:07:38 2017 +0200

----------------------------------------------------------------------
 ...nnotationValidationConfigurationBuilderTest.java | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/eb4fcb4a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
index da6df01..1bc0564 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilderTest.java
@@ -17,6 +17,7 @@ import com.opensymphony.xwork2.util.ValueStackFactory;
 import com.opensymphony.xwork2.util.location.LocatableProperties;
 import com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator;
 import com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator;
+import com.opensymphony.xwork2.validator.validators.CreditCardValidator;
 import com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator;
 import com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator;
 import com.opensymphony.xwork2.validator.validators.EmailValidator;
@@ -50,7 +51,7 @@ public class AnnotationValidationConfigurationBuilderTest extends XWorkTestCase
         List<Validator> validators = manager.getValidators(AnnotationValidationAction.class, null);
 
         // then
-        assertEquals(validators.size(), 16);
+        assertEquals(validators.size(), 17);
         for (Validator validator : validators) {
             validate(validator);
         }
@@ -89,6 +90,8 @@ public class AnnotationValidationConfigurationBuilderTest extends XWorkTestCase
             validateDoubleRangeFieldValidator((DoubleRangeFieldValidator) validator);
         } else if (validator.getValidatorType().equals("email")) {
             validateEmailValidator((EmailValidator) validator);
+        } else if (validator.getValidatorType().equals("creditcard")) {
+            validateCreditCardValidator((CreditCardValidator) validator);
         } else if (validator.getValidatorType().equals("expression")) {
             validateExpressionValidator((ExpressionValidator) validator);
         } else if (validator.getValidatorType().equals("fieldexpression")) {
@@ -203,6 +206,17 @@ public class AnnotationValidationConfigurationBuilderTest extends XWorkTestCase
         assertEquals(true, validator.isTrimed());
     }
 
+    private void validateCreditCardValidator(CreditCardValidator validator) {
+        assertEquals("foo", validator.getFieldName());
+        assertEquals(CreditCardValidator.CREDIT_CARD_PATTERN, validator.getRegex());
+        assertEquals("Foo isn't a valid credit card!", validator.getDefaultMessage());
+        assertEquals("creditCard.key", validator.getMessageKey());
+        assertTrue(Arrays.equals(new String[]{"one", "two", "three"}, validator.getMessageParameters()));
+        assertEquals(true, validator.isShortCircuit());
+        assertEquals(false, validator.isCaseSensitive());
+        assertEquals(true, validator.isTrimed());
+    }
+
     private void validateDoubleRangeFieldValidator(DoubleRangeFieldValidator validator) {
         assertEquals("foo", validator.getFieldName());
         assertEquals("double.key", validator.getMessageKey());


[6/8] struts git commit: WW-3952 Adds client side validation support

Posted by lu...@apache.org.
WW-3952 Adds client side validation support


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

Branch: refs/heads/master
Commit: 9eec07b310b4ac9e99342cfd632293acd2a45d8b
Parents: eb4fcb4
Author: Lukasz Lenart <lu...@apache.org>
Authored: Sat Apr 22 17:40:40 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Sat Apr 22 17:40:40 2017 +0200

----------------------------------------------------------------------
 .../template/xhtml/form-close-validate.ftl      | 28 ++++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/9eec07b3/core/src/main/resources/template/xhtml/form-close-validate.ftl
----------------------------------------------------------------------
diff --git a/core/src/main/resources/template/xhtml/form-close-validate.ftl b/core/src/main/resources/template/xhtml/form-close-validate.ftl
index e8dd991..3ffc3bf 100644
--- a/core/src/main/resources/template/xhtml/form-close-validate.ftl
+++ b/core/src/main/resources/template/xhtml/form-close-validate.ftl
@@ -41,9 +41,9 @@ END SNIPPET: supported-validators
         -->
         var getFieldValue = function(field) {
             var type = field.type ? field.type : field[0].type;
-            if (type == 'select-one' || type == 'select-multiple') {
-                return (field.selectedIndex == -1 ? "" : field.options[field.selectedIndex].value);
-            } else if (type == 'checkbox' || type == 'radio') {
+            if (type === 'select-one' || type === 'select-multiple') {
+                return (field.selectedIndex === -1 ? "" : field.options[field.selectedIndex].value);
+            } else if (type === 'checkbox' || type === 'radio') {
                 if (!field.length) {
                     field = [field];
                 }
@@ -79,25 +79,25 @@ END SNIPPET: supported-validators
             var fieldValue = getFieldValue(field);
             
             <#if validator.validatorType = "required">
-            if (fieldValue == "") {
+            if (fieldValue === "") {
                 addError(field, error);
                 errors = true;
                 <#if validator.shortCircuit>continueValidation = false;</#if>
             }
             <#elseif validator.validatorType = "requiredstring">
-            if (continueValidation && fieldValue != null && (fieldValue == "" || fieldValue.replace(/^\s+|\s+$/g,"").length == 0)) {
+            if (continueValidation && fieldValue !== null && (fieldValue === "" || fieldValue.replace(/^\s+|\s+$/g,"").length === 0)) {
                 addError(field, error);
                 errors = true;
                 <#if validator.shortCircuit>continueValidation = false;</#if>
             }
             <#elseif validator.validatorType = "stringlength">
-            if (continueValidation && fieldValue != null) {
+            if (continueValidation && fieldValue !== null) {
                 var value = fieldValue;
                 <#if validator.trim>
                     //trim field value
-                    while (value.substring(0,1) == ' ')
+                    while (value.substring(0,1) === ' ')
                         value = value.substring(1, value.length);
-                    while (value.substring(value.length-1, value.length) == ' ')
+                    while (value.substring(value.length-1, value.length) === ' ')
                         value = value.substring(0, value.length-1);
                 </#if>
                 if ((${validator.minLength?c} > -1 && value.length < ${validator.minLength?c}) ||
@@ -108,25 +108,25 @@ END SNIPPET: supported-validators
                 }
             }
             <#elseif validator.validatorType = "regex">
-            if (continueValidation && fieldValue != null && !fieldValue.match("${validator.regex?js_string}")) {
+            if (continueValidation && fieldValue !== null && !fieldValue.match("${validator.regex?js_string}")) {
                 addError(field, error);
                 errors = true;
                 <#if validator.shortCircuit>continueValidation = false;</#if>
             }
-            <#elseif validator.validatorType = "email">
-            if (continueValidation && fieldValue != null && fieldValue.length > 0 && fieldValue.match(/${validator.regex}/i)==null) {
+            <#elseif validator.validatorType = "email" || validator.validatorType = "creditcard">
+            if (continueValidation && fieldValue !== null && fieldValue.length > 0 && fieldValue.match(/${validator.regex}/i) === null) {
                 addError(field, error);
                 errors = true;
                 <#if validator.shortCircuit>continueValidation = false;</#if>
             }
             <#elseif validator.validatorType = "url">
-            if (continueValidation && fieldValue != null && fieldValue.length > 0 && fieldValue.match(/${validator.urlRegex}/i)==null) {
+            if (continueValidation && fieldValue !== null && fieldValue.length > 0 && fieldValue.match(/${validator.urlRegex}/i) === null) {
                 addError(field, error);
                 errors = true;
                 <#if validator.shortCircuit>continueValidation = false;</#if>
             }
             <#elseif validator.validatorType = "int" || validator.validatorType = "short">
-            if (continueValidation && fieldValue != null) {
+            if (continueValidation && fieldValue !== null) {
                 if (<#if validator.min??>parseInt(fieldValue) <
                      ${validator.min?c}<#else>false</#if> ||
                         <#if validator.max??>parseInt(fieldValue) >
@@ -137,7 +137,7 @@ END SNIPPET: supported-validators
                 }
             }
             <#elseif validator.validatorType = "double">
-            if (continueValidation && fieldValue != null) {
+            if (continueValidation && fieldValue !== null) {
                 var value = parseFloat(fieldValue);
                 if (<#if validator.minInclusive??>value < ${validator.minInclusive?c}<#else>false</#if> ||
                         <#if validator.maxInclusive??>value > ${validator.maxInclusive?c}<#else>false</#if> ||


[2/8] struts git commit: WW-3952 Adds test to check implementation

Posted by lu...@apache.org.
WW-3952 Adds test to check implementation


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

Branch: refs/heads/master
Commit: fc497360bee7084293749f712dec233eb219bbf4
Parents: 01d710b
Author: Lukasz Lenart <lu...@apache.org>
Authored: Wed Apr 19 18:06:17 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Apr 19 18:06:17 2017 +0200

----------------------------------------------------------------------
 .../validators/CreditCardValidatorTest.java     | 230 +++++++++++++++++++
 1 file changed, 230 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/fc497360/core/src/test/java/com/opensymphony/xwork2/validator/validators/CreditCardValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/validators/CreditCardValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/validators/CreditCardValidatorTest.java
new file mode 100644
index 0000000..877b964
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/validators/CreditCardValidatorTest.java
@@ -0,0 +1,230 @@
+package com.opensymphony.xwork2.validator.validators;
+
+import com.opensymphony.xwork2.TextProviderFactory;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+import com.opensymphony.xwork2.validator.DummyValidatorContext;
+import com.opensymphony.xwork2.validator.ValidatorContext;
+import org.apache.struts2.StrutsInternalTestCase;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CreditCardValidatorTest extends StrutsInternalTestCase {
+
+    private CreditCardValidator validator;
+    private CreditCardAction action;
+    private ValidatorContext context;
+
+    public void testInvalidCardNumber() throws Exception {
+        // given
+        action.setAmericanExpress("123456768900");
+        validator.setFieldName("americanExpress");
+        validator.setDefaultMessage("It is not a valid American Express card number: ${americanExpress}");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals("It is not a valid American Express card number: 123456768900", context.getFieldErrors().get("americanExpress").get(0));
+    }
+
+    public void testInvalidArrayOfCardNumbers() throws Exception {
+        // given
+        action.setAmericanExpresses(new String[]{"098776544322"});
+        validator.setFieldName("americanExpresses");
+        validator.setDefaultMessage("It is not a valid American Express card number: ${currentValue}");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals("It is not a valid American Express card number: 098776544322", context.getFieldErrors().get("americanExpresses").get(0));
+    }
+
+    public void testEmptyArrayOfCardNumbers() throws Exception {
+        // given
+        action.setAmericanExpresses(new String[]{});
+        validator.setFieldName("americanExpresses");
+        validator.setDefaultMessage("It is not a valid American Express card number: ${currentValue}");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertFalse(context.hasFieldErrors());
+    }
+
+    public void testInvalidCollectionOfCardNumbers() throws Exception {
+        // given
+        action.setDinerClubs(Arrays.asList("75736151433"));
+        validator.setFieldName("dinerClubs");
+        validator.setDefaultMessage("It is not a valid Diner Club card number: ${currentValue}");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertTrue(context.hasFieldErrors());
+        assertEquals(1, context.getFieldErrors().size());
+        assertEquals("It is not a valid Diner Club card number: 75736151433", context.getFieldErrors().get("dinerClubs").get(0));
+    }
+
+    public void testValidAmericanExpressCard() throws Exception {
+        // given
+        action.setAmericanExpress("378282246310005");
+        validator.setFieldName("americanExpress");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertFalse(context.hasFieldErrors());
+    }
+
+    public void testValidAmericanExpressCardWithSpaces() throws Exception {
+        // given
+        action.setAmericanExpress("3782 8224 6310 005");
+        validator.setFieldName("americanExpress");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertFalse(context.hasFieldErrors());
+    }
+
+    public void testValidDinersClubCard() throws Exception {
+        // given
+        action.setDinersClub("30569309025904");
+        validator.setFieldName("dinersClub");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertFalse(context.hasFieldErrors());
+    }
+
+    public void testValidJCBCard() throws Exception {
+        // given
+        action.setJCB("3530111333300000");
+        validator.setFieldName("JCB");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertFalse(context.hasFieldErrors());
+    }
+
+    public void testMasterCardCard() throws Exception {
+        // given
+        action.setMasterCard("5555555555554444");
+        validator.setFieldName("masterCard");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertFalse(context.hasFieldErrors());
+    }
+
+    public void testVisaCard() throws Exception {
+        // given
+        action.setVisa("4111111111111111");
+        validator.setFieldName("visa");
+
+        // when
+        validator.validate(action);
+
+        // then
+        assertFalse(context.hasFieldErrors());
+    }
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        validator = new CreditCardValidator();
+        action = new CreditCardAction();
+        TextProviderFactory tpf = container.getInstance(TextProviderFactory.class);
+        context = new DummyValidatorContext(action, tpf);
+        validator.setValidatorContext(context);
+
+        ValueStack valueStack = container.getInstance(ValueStackFactory.class).createValueStack();
+        valueStack.push(action);
+
+        validator.setValueStack(valueStack);
+    }
+
+}
+
+class CreditCardAction {
+
+    private String americanExpress;
+    private String dinersClub;
+    private String JCB;
+    private String masterCard;
+    private String visa;
+    private String[] americanExpresses;
+    private List<String> dinerClubs;
+
+    public void setAmericanExpress(String americanExpress) {
+        this.americanExpress = americanExpress;
+    }
+
+    public String getAmericanExpress() {
+        return americanExpress;
+    }
+
+    public void setDinersClub(String dinersClub) {
+        this.dinersClub = dinersClub;
+    }
+
+    public String getDinersClub() {
+        return dinersClub;
+    }
+
+    public void setJCB(String JCB) {
+        this.JCB = JCB;
+    }
+
+    public String getJCB() {
+        return JCB;
+    }
+
+    public void setMasterCard(String masterCard) {
+        this.masterCard = masterCard;
+    }
+
+    public String getMasterCard() {
+        return masterCard;
+    }
+
+    public void setVisa(String visa) {
+        this.visa = visa;
+    }
+
+    public String getVisa() {
+        return visa;
+    }
+
+    public void setAmericanExpresses(String[] americanExpresses) {
+        this.americanExpresses = americanExpresses;
+    }
+
+    public String[] getAmericanExpresses() {
+        return americanExpresses;
+    }
+
+    public void setDinerClubs(List<String> dinerClubs) {
+        this.dinerClubs = dinerClubs;
+    }
+
+    public List<String> getDinerClubs() {
+        return dinerClubs;
+    }
+}


[4/8] struts git commit: WW-3952 Extends existing logic to handle credit card validation

Posted by lu...@apache.org.
WW-3952 Extends existing logic to handle credit card validation


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

Branch: refs/heads/master
Commit: 0813eaa0c8f446404243fba87cde51a619643cb9
Parents: 743d27f
Author: Lukasz Lenart <lu...@apache.org>
Authored: Wed Apr 19 18:07:16 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Apr 19 18:07:16 2017 +0200

----------------------------------------------------------------------
 ...nnotationValidationConfigurationBuilder.java | 39 ++++++++++++++++++++
 .../validator/annotations/Validations.java      |  2 +
 .../validators/RegexFieldValidator.java         | 11 ++++--
 .../validator/AnnotationValidationAction.java   |  3 ++
 core/src/test/resources/validators.xml          |  1 +
 5 files changed, 53 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/0813eaa0/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java b/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java
index b587bf3..b2764ca 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/AnnotationValidationConfigurationBuilder.java
@@ -122,6 +122,14 @@ public class AnnotationValidationConfigurationBuilder {
                         result.add(temp);
                     }
                 }
+                // Process CrediCardValidator
+                else if (a instanceof CreditCardValidator) {
+                    CreditCardValidator v = (CreditCardValidator) a;
+                    ValidatorConfig temp = processCreditCardValidatorAnnotation(v, fieldName, methodName);
+                    if (temp != null) {
+                        result.add(temp);
+                    }
+                }
                 // Process FieldExpressionValidator
                 else if (a instanceof FieldExpressionValidator) {
                     FieldExpressionValidator v = (FieldExpressionValidator) a;
@@ -263,6 +271,15 @@ public class AnnotationValidationConfigurationBuilder {
                 }
             }
         }
+        CreditCardValidator[] ccv = validations.creditCards();
+        if (ccv != null) {
+            for (CreditCardValidator v : ccv) {
+                ValidatorConfig temp = processCreditCardValidatorAnnotation(v, fieldName, methodName);
+                if (temp != null) {
+                    result.add(temp);
+                }
+            }
+        }
         FieldExpressionValidator[] fev = validations.fieldExpressions();
         if (fev != null) {
             for (FieldExpressionValidator v : fev) {
@@ -786,6 +803,28 @@ public class AnnotationValidationConfigurationBuilder {
                 .build();
     }
 
+    private ValidatorConfig processCreditCardValidatorAnnotation(CreditCardValidator v, String fieldName, String methodName) {
+        String validatorType = "creditcard";
+
+        Map<String, Object> params = new HashMap<>();
+
+        if (fieldName != null) {
+            params.put("fieldName", fieldName);
+        } else if (StringUtils.isNotEmpty(v.fieldName())) {
+            params.put("fieldName", v.fieldName());
+        }
+
+        validatorFactory.lookupRegisteredValidatorType(validatorType);
+        return new ValidatorConfig.Builder(validatorType)
+                .addParams(params)
+                .addParam("methodName", methodName)
+                .shortCircuit(v.shortCircuit())
+                .defaultMessage(v.message())
+                .messageKey(v.key())
+                .messageParams(v.messageParams())
+                .build();
+    }
+
     private ValidatorConfig processDateRangeFieldValidatorAnnotation(DateRangeFieldValidator v, String fieldName, String methodName) {
         String validatorType = "date";
 

http://git-wip-us.apache.org/repos/asf/struts/blob/0813eaa0/core/src/main/java/com/opensymphony/xwork2/validator/annotations/Validations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/annotations/Validations.java b/core/src/main/java/com/opensymphony/xwork2/validator/annotations/Validations.java
index b4b640b..bdf5a75 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/annotations/Validations.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/annotations/Validations.java
@@ -167,6 +167,8 @@ public @interface Validations {
 
     EmailValidator[] emails() default {};
 
+    CreditCardValidator[] creditCards() default {};
+
     FieldExpressionValidator[] fieldExpressions() default {};
 
     IntRangeFieldValidator[] intRangeFields() default {};

http://git-wip-us.apache.org/repos/asf/struts/blob/0813eaa0/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 eff835c..f6e9748 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
@@ -148,9 +148,14 @@ public class RegexFieldValidator extends FieldValidatorSupport {
             compare = compare.trim();
         }
 
-        Matcher matcher = pattern.matcher(compare);
-        if (!matcher.matches()) {
-            addFieldError(fieldName, object);
+        try {
+            setCurrentValue(compare);
+            Matcher matcher = pattern.matcher(compare);
+            if (!matcher.matches()) {
+                addFieldError(fieldName, object);
+            }
+        } finally {
+            setCurrentValue(null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/struts/blob/0813eaa0/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
index 6dbb429..9e95dde 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/AnnotationValidationAction.java
@@ -3,6 +3,7 @@ package com.opensymphony.xwork2.validator;
 import com.opensymphony.xwork2.ActionSupport;
 import com.opensymphony.xwork2.validator.annotations.ConditionalVisitorFieldValidator;
 import com.opensymphony.xwork2.validator.annotations.ConversionErrorFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.CreditCardValidator;
 import com.opensymphony.xwork2.validator.annotations.CustomValidator;
 import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator;
 import com.opensymphony.xwork2.validator.annotations.DoubleRangeFieldValidator;
@@ -45,6 +46,8 @@ public class AnnotationValidationAction extends ActionSupport {
             messageParams = {"one", "two", "three"})
     @EmailValidator(message = "Foo isn't a valid e-mail!", fieldName = "foo", key = "email.key",
             messageParams = {"one", "two", "three"}, shortCircuit = true)
+    @CreditCardValidator(message = "Foo isn't a valid credit card!", fieldName = "foo", key = "creditCard.key",
+            messageParams = {"one", "two", "three"}, shortCircuit = true)
     @ExpressionValidator(expression = "true", message = "Is not true!", key = "expression.key",
             messageParams = {"one", "two", "three"}, shortCircuit = true)
     @FieldExpressionValidator(expression = "true", fieldName = "foo", key = "fieldexpression.key", message = "It is not true!",

http://git-wip-us.apache.org/repos/asf/struts/blob/0813eaa0/core/src/test/resources/validators.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/validators.xml b/core/src/test/resources/validators.xml
index 48369fa..5eff925 100644
--- a/core/src/test/resources/validators.xml
+++ b/core/src/test/resources/validators.xml
@@ -11,6 +11,7 @@
     <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
     <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
     <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
+    <validator name="creditcard" class="com.opensymphony.xwork2.validator.validators.CreditCardValidator"/>
     <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
     <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
     <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>


[8/8] struts git commit: WW-3952 introduces credit card validator

Posted by lu...@apache.org.
WW-3952 introduces credit card validator


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

Branch: refs/heads/master
Commit: 775d1c8c65e4207e0590b8d7bfb56f0423f89d90
Parents: faf72b5 6ef9f7a
Author: Lukasz Lenart <lu...@apache.org>
Authored: Mon Apr 24 10:12:13 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Mon Apr 24 10:12:13 2017 +0200

----------------------------------------------------------------------
 ...nnotationValidationConfigurationBuilder.java |  39 ++++
 .../annotations/CreditCardValidator.java        |  66 ++++++
 .../validator/annotations/Validations.java      |   2 +
 .../validators/CreditCardValidator.java         |  46 ++++
 .../validators/RegexFieldValidator.java         |  11 +-
 .../template/xhtml/form-close-validate.ftl      |  28 +--
 .../validator/AnnotationValidationAction.java   |   3 +
 ...ationValidationConfigurationBuilderTest.java |  16 +-
 .../validators/CreditCardValidatorTest.java     | 230 +++++++++++++++++++
 .../apache/struts2/views/jsp/ui/Formtag-2.txt   |   8 +-
 .../apache/struts2/views/jsp/ui/Formtag-22.txt  |   8 +-
 .../apache/struts2/views/jsp/ui/Formtag-24.txt  |   8 +-
 core/src/test/resources/validators.xml          |   1 +
 13 files changed, 436 insertions(+), 30 deletions(-)
----------------------------------------------------------------------



[3/8] struts git commit: WW-3952 Introduces annotation

Posted by lu...@apache.org.
WW-3952 Introduces annotation


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

Branch: refs/heads/master
Commit: 743d27f841ce990ed3153f569f890179bdbb6a37
Parents: fc49736
Author: Lukasz Lenart <lu...@apache.org>
Authored: Wed Apr 19 18:06:31 2017 +0200
Committer: Lukasz Lenart <lu...@apache.org>
Committed: Wed Apr 19 18:06:31 2017 +0200

----------------------------------------------------------------------
 .../annotations/CreditCardValidator.java        | 66 ++++++++++++++++++++
 1 file changed, 66 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/struts/blob/743d27f8/core/src/main/java/com/opensymphony/xwork2/validator/annotations/CreditCardValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/annotations/CreditCardValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/annotations/CreditCardValidator.java
new file mode 100644
index 0000000..f007ab7
--- /dev/null
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/annotations/CreditCardValidator.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.opensymphony.xwork2.validator.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This validator checks that a field is a valid credit card.
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CreditCardValidator {
+
+    /**
+     * @return The default error message for this validator.
+     * NOTE: It is required to set a message, if you are not using the message key for 18n lookup!
+     */
+    String message() default "";
+
+    /**
+     * @return The message key to lookup for i18n.
+     */
+    String key() default "";
+
+    /**
+     * @return Additional params to be used to customize message - will be evaluated against the Value Stack
+     */
+    String[] messageParams() default {};
+
+    /**
+     * @return The optional fieldName for SIMPLE validator types.
+     */
+    String fieldName() default "";
+
+    /**
+     * If this is activated, the validator will be used as short-circuit.
+     *
+     * Adds the short-circuit='true' attribute value if <tt>true</tt>.
+     *
+     * @return true if validator will be used as short-circuit. Default is false.
+     */
+    boolean shortCircuit() default false;
+
+    /**
+     * @return The validation type for this field/method.
+     */
+    ValidatorType type() default ValidatorType.FIELD;
+
+}