Repository: wicket
Updated Branches:
  refs/heads/master 05259c230 -> 39e731510


WICKET-6499 Support Bean Validation 2.0

this closes 246


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

Branch: refs/heads/master
Commit: 39e731510cd3084d6109cb7e126ececc5bdf7da0
Parents: 05259c2
Author: Thomas Heigl <[email protected]>
Authored: Sun Nov 19 11:26:57 2017 +0100
Committer: Sven Meier <[email protected]>
Committed: Sat Nov 25 18:15:33 2017 +0100

----------------------------------------------------------------------
 .../bean/validation/PropertyValidator.java      | 27 ++++++++------
 .../validation/PropertyValidator.properties     | 37 ++++++++++++--------
 .../PropertyValidator_fr.properties.xml         | 13 +++++--
 .../PropertyValidatorRequiredTest.java          | 37 +++++++++++++++-----
 4 files changed, 79 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/39e73151/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.java
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.java
 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.java
index 862a69b..5ae2314 100644
--- 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.java
+++ 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.java
@@ -1,5 +1,6 @@
 package org.apache.wicket.bean.validation;
 
+import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -9,6 +10,8 @@ import java.util.Set;
 
 import javax.validation.ConstraintViolation;
 import javax.validation.Validator;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 import javax.validation.groups.Default;
 import javax.validation.metadata.ConstraintDescriptor;
@@ -58,6 +61,8 @@ import org.apache.wicket.validation.IValidator;
 public class PropertyValidator<T> extends Behavior implements IValidator<T>
 {
        private static final Class<?>[] EMPTY = new Class<?>[0];
+       private static final List<Class<? extends Annotation>> 
NOT_NULL_ANNOTATIONS =
+                       Arrays.asList(NotNull.class, NotBlank.class, 
NotEmpty.class);
 
        private FormComponent<T> component;
 
@@ -184,22 +189,24 @@ public class PropertyValidator<T> extends Behavior 
implements IValidator<T>
                }
        }
 
-       private List<NotNull> findNotNullConstraints()
+       private List<ConstraintDescriptor<?>> 
findNotNullConstraints(List<Class<? extends Annotation>> notNullAnnotationTypes)
        {
                BeanValidationContext config = 
BeanValidationConfiguration.get();
                Validator validator = config.getValidator();
                Property property = getProperty();
 
-               List<NotNull> constraints = new ArrayList<NotNull>();
+               List<ConstraintDescriptor<?>> constraints = new ArrayList<>();
 
                Iterator<ConstraintDescriptor<?>> it = new 
ConstraintIterator(validator, property);
 
                while (it.hasNext())
                {
                        ConstraintDescriptor<?> desc = it.next();
-                       if 
(desc.getAnnotation().annotationType().equals(NotNull.class))
+                       Annotation annotation = desc.getAnnotation();
+                       Class<? extends Annotation> annotationType = 
annotation.annotationType();
+                       if (notNullAnnotationTypes.contains(annotationType))
                        {
-                               constraints.add((NotNull)desc.getAnnotation());
+                               constraints.add(desc);
                        }
                }
 
@@ -208,24 +215,24 @@ public class PropertyValidator<T> extends Behavior 
implements IValidator<T>
 
        boolean isRequired()
        {
-               List<NotNull> constraints = findNotNullConstraints();
+               List<ConstraintDescriptor<?>> constraints = 
findNotNullConstraints(NOT_NULL_ANNOTATIONS);
 
                if (constraints.isEmpty())
                {
                        return false;
                }
 
-               HashSet<Class<?>> validatorGroups = new HashSet<Class<?>>();
+               Set<Class<?>> validatorGroups = new HashSet<>();
                validatorGroups.addAll(Arrays.asList(getGroups()));
 
-               for (NotNull constraint : constraints)
+               for (ConstraintDescriptor<?> constraint : constraints)
                {
                        if (canApplyToDefaultGroup(constraint) && 
validatorGroups.isEmpty())
                        {
                                return true;
                        }
 
-                       for (Class<?> constraintGroup : constraint.groups())
+                       for (Class<?> constraintGroup : constraint.getGroups())
                        {
                                if (validatorGroups.contains(constraintGroup))
                                {
@@ -237,9 +244,9 @@ public class PropertyValidator<T> extends Behavior 
implements IValidator<T>
                return false;
        }
 
-       private boolean canApplyToDefaultGroup(NotNull constraint)
+       private boolean canApplyToDefaultGroup(ConstraintDescriptor<?> 
constraint)
        {
-               List<Class<?>> groups = Arrays.asList(constraint.groups());
+               Set<Class<?>> groups = constraint.getGroups();
                //the constraint can be applied to default group either if its 
group array is empty
                //or if it contains javax.validation.groups.Default
                return groups.size() == 0 || groups.contains(Default.class);

http://git-wip-us.apache.org/repos/asf/wicket/blob/39e73151/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.properties
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.properties
 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.properties
index b706fc9..29f5511 100644
--- 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.properties
+++ 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator.properties
@@ -1,17 +1,26 @@
-javax.validation.constraints.AssertFalse.message = '${label}' must be false
-javax.validation.constraints.AssertTrue.message  = '${label}' must be true
-javax.validation.constraints.DecimalMax.message  = '${label}' must be less 
than or equal to ${value}
-javax.validation.constraints.DecimalMin.message  = '${label}' must be greater 
than or equal to ${value}
-javax.validation.constraints.Digits.message      = '${label}' numeric value 
out of bounds (<${integer} digits>.<${fraction} digits> expected)
-javax.validation.constraints.Future.message      = '${label}' must be in the 
future
-javax.validation.constraints.Max.message         = '${label}' must be less 
than or equal to ${value}
-javax.validation.constraints.Min.message         = '${label}' must be greater 
than or equal to ${value}
-javax.validation.constraints.NotNull.message     = '${label}' may not be null
-javax.validation.constraints.Null.message        = '${label}' must be null
-javax.validation.constraints.Past.message        = '${label}' must be in the 
past
-javax.validation.constraints.Pattern.message     = '${label}' must match 
"${regexp}"
-javax.validation.constraints.Size.message        = '${label}' must be between 
${min} and ${max}
-javax.validation.constraints.Size.message.String = '${label}' length must be 
between ${min} and ${max}
+javax.validation.constraints.AssertFalse.message        = '${label}' must be 
false
+javax.validation.constraints.AssertTrue.message         = '${label}' must be 
true
+javax.validation.constraints.DecimalMax.message         = '${label}' must be 
less than or equal to ${value}
+javax.validation.constraints.DecimalMin.message         = '${label}' must be 
greater than or equal to ${value}
+javax.validation.constraints.Digits.message             = '${label}' numeric 
value out of bounds (<${integer} digits>.<${fraction} digits> expected)
+javax.validation.constraints.Email.message              = '${label}' is not a 
well-formed email address
+javax.validation.constraints.Future.message             = '${label}' must be 
in the future
+javax.validation.constraints.FutureOrPresent.message    = '${label}' must be 
in the future or present
+javax.validation.constraints.Max.message                = '${label}' must be 
less than or equal to ${value}
+javax.validation.constraints.Min.message                = '${label}' must be 
greater than or equal to ${value}
+javax.validation.constraints.Negative.message           = '${label}' must be 
negative
+javax.validation.constraints.NegativeOrZero.message     = '${label}' must be 
negative or zero
+javax.validation.constraints.NotNull.message            = '${label}' may not 
be null
+javax.validation.constraints.NotBlank.message           = '${label}' may not 
be empty
+javax.validation.constraints.NotEmpty.message           = '${label}' may not 
be empty
+javax.validation.constraints.Null.message               = '${label}' must be 
null
+javax.validation.constraints.Past.message               = '${label}' must be 
in the past
+javax.validation.constraints.PastOrPresent.message      = '${label}' must be 
in the past or present
+javax.validation.constraints.Pattern.message            = '${label}' must 
match "${regexp}"
+javax.validation.constraints.Positive.message           = '${label}' must be 
positive
+javax.validation.constraints.PositiveOrZero.message     = '${label}' must be 
positive or zero
+javax.validation.constraints.Size.message               = '${label}' must be 
between ${min} and ${max}
+javax.validation.constraints.Size.message.String        = '${label}' length 
must be between ${min} and ${max}
 
 org.hibernate.validator.constraints.CreditCardNumber.message = '${label}' is 
not a valid credit card number
 org.hibernate.validator.constraints.Email.message            = '${label}' is 
not a well-formed email address

http://git-wip-us.apache.org/repos/asf/wicket/blob/39e73151/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator_fr.properties.xml
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator_fr.properties.xml
 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator_fr.properties.xml
index 54333e2..0354b5d 100644
--- 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator_fr.properties.xml
+++ 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/PropertyValidator_fr.properties.xml
@@ -22,12 +22,21 @@
        <entry key="javax.validation.constraints.DecimalMax.message">Le champ 
'${label}' doit être inférieur ou égal à ${value}</entry>
        <entry key="javax.validation.constraints.DecimalMin.message">Le champ 
'${label}' doit être supérieur ou égal à ${value}</entry>
        <entry key="javax.validation.constraints.Digits.message">Le champ 
'${label}' valeur numérique hors limite (&lt;${integer} 
chiffres&gt;.&lt;${fraction} chiffres&gt; attendu)</entry>
+       <entry key="javax.validation.constraints.Email.message">Le champ 
'${label}' n'est pas une adresse mail valide</entry>
        <entry key="javax.validation.constraints.Future.message">Le champ 
'${label}' doit être dans le futur</entry>
+       <entry key="javax.validation.constraints.FutureOrPresent.message">Le 
champ '${label}' doit être dans le futur ou le présent</entry>
        <entry key="javax.validation.constraints.Max.message">Le champ 
'${label}' doit être inférieur ou égal à ${value}</entry>
        <entry key="javax.validation.constraints.Min.message">Le champ 
'${label}' doit être supérieur ou égal à ${value}</entry>
-       <entry key="javax.validation.constraints.NotNull.message">Le champ 
'${label}' ne doit pas être null</entry>
-       <entry key="javax.validation.constraints.Null.message">Le champ 
'${label}' doit être null</entry>
+       <entry key="javax.validation.constraints.Negative.message">Le champ 
'${label}' doit être négatif,</entry>
+       <entry key="javax.validation.constraints.NegativeOrZero.message">Le 
champ '${label}' doit être négatif, ou zéro</entry>
+    <entry key="javax.validation.constraints.NotBlank.message">Le champ 
'${label}' ne peut pas être vide</entry>
+    <entry key="javax.validation.constraints.NotEmpty.message">Le champ 
'${label}' ne peut pas être vide</entry>
+    <entry key="javax.validation.constraints.NotNull.message">Le champ 
'${label}' ne doit pas être null</entry>
+    <entry key="javax.validation.constraints.Null.message">Le champ '${label}' 
doit être null</entry>
        <entry key="javax.validation.constraints.Past.message">Le champ 
'${label}' doit être dans le passé</entry>
+       <entry key="javax.validation.constraints.PastOrPresent.message">Le 
champ '${label}' doit être dans le passé ou le présent</entry>
+       <entry key="javax.validation.constraints.Positive.message">Le champ 
'${label}' doit être positif</entry>
+       <entry key="javax.validation.constraints.PositiveOrZero.message">Le 
champ '${label}' doit être positif ou zéro</entry>
        <entry key="javax.validation.constraints.Pattern.message">Le champ 
'${label}' doit correspondre à "${regexp}"</entry>
        <entry key="javax.validation.constraints.Size.message">Le champ 
'${label}' doit être entre ${min} et ${max}</entry>
        <entry key="javax.validation.constraints.Size.message.String">La 
longueur du champ '${label}' doit être entre ${min} et ${max}</entry>

http://git-wip-us.apache.org/repos/asf/wicket/blob/39e73151/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/PropertyValidatorRequiredTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/PropertyValidatorRequiredTest.java
 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/PropertyValidatorRequiredTest.java
index 805a5cf..2f84c01 100644
--- 
a/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/PropertyValidatorRequiredTest.java
+++ 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/PropertyValidatorRequiredTest.java
@@ -7,6 +7,8 @@ import java.util.Arrays;
 import java.util.List;
 
 import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 
 import org.apache.wicket.MarkupContainer;
@@ -72,22 +74,26 @@ public class PropertyValidatorRequiredTest
 
                assertTrue(page.input21.isRequired());
 
+               // NotEmpty + NotBlank
+               assertTrue(page.input22.isRequired());
+               assertTrue(page.input23.isRequired());
+
        }
-       
+
        /**
         * https://issues.apache.org/jira/browse/WICKET-5656
-        * 
+        *
         * Annotation NotNull must be effective even if is not directly applied.
-        * 
+        *
         * @throws Exception
         */
        @Test
        public void testResolveComposedConstraints() throws Exception
        {
-               Property property = new 
Property(DefaultPropertyResolverTest.BeanWithPassword.class, "password");       
        
+               Property property = new 
Property(DefaultPropertyResolverTest.BeanWithPassword.class, "password");
                PropertyValidator<DefaultPropertyResolverTest.BeanWithPassword> 
propertyValidator = new PropertyValidator<>(property);
-               
-               assertTrue(propertyValidator.isRequired()); 
+
+               assertTrue(propertyValidator.isRequired());
        }
 
        public static class TestApplication extends MockApplication
@@ -106,7 +112,7 @@ public class PropertyValidatorRequiredTest
                private TestBean bean = new TestBean();
                private FormComponent<String> input1, input2, input3, input4, 
input5, input6, input7,
                        input8, input9, input10, input11, input12, input13, 
input14, input15, input16, input17,
-                       input18, input19, input20, input21;
+                       input18, input19, input20, input21, input22, input23;
 
                public TestPage()
                {
@@ -164,9 +170,16 @@ public class PropertyValidatorRequiredTest
                        input21 = new TextField<String>("input21", new 
PropertyModel<String>(this,
                                "bean.subBeanList[0].property")).add(new 
PropertyValidator<>());
 
+                       input22 = new TextField<String>("input22",
+                                       new PropertyModel<String>(this, 
"bean.propertyNotEmpty"))
+                                       .add(new PropertyValidator<>());
+                       input23 = new TextField<String>("input23",
+                                       new PropertyModel<String>(this, 
"bean.propertyNotBlank"))
+                                       .add(new PropertyValidator<>());
+
                        form.add(input1, input2, input3, input4, input5, 
input6, input7, input8, input9,
                                input10, input11, input12, input13, input14, 
input15, input16, input17, input18,
-                               input19, input20, input21);
+                               input19, input20, input21, input22, input23);
 
                }
 
@@ -175,7 +188,7 @@ public class PropertyValidatorRequiredTest
                        Class<?> containerClass)
                {
                        return new StringResourceStream(
-                               "<form wicket:id='form'><input 
wicket:id='input1'/><input wicket:id='input2'/><input 
wicket:id='input3'/><input wicket:id='input4'/><input 
wicket:id='input5'/><input wicket:id='input6'/><input 
wicket:id='input7'/><input wicket:id='input8'/><input 
wicket:id='input9'/><input wicket:id='input10'/><input 
wicket:id='input11'/><input wicket:id='input12'/><input 
wicket:id='input13'/><input wicket:id='input14'/><input 
wicket:id='input15'/><input wicket:id='input16'/><input 
wicket:id='input17'/><input wicket:id='input18'/><input 
wicket:id='input19'/><input wicket:id='input20'/><input 
wicket:id='input21'/></form>");
+                               "<form wicket:id='form'><input 
wicket:id='input1'/><input wicket:id='input2'/><input 
wicket:id='input3'/><input wicket:id='input4'/><input 
wicket:id='input5'/><input wicket:id='input6'/><input 
wicket:id='input7'/><input wicket:id='input8'/><input 
wicket:id='input9'/><input wicket:id='input10'/><input 
wicket:id='input11'/><input wicket:id='input12'/><input 
wicket:id='input13'/><input wicket:id='input14'/><input 
wicket:id='input15'/><input wicket:id='input16'/><input 
wicket:id='input17'/><input wicket:id='input18'/><input 
wicket:id='input19'/><input wicket:id='input20'/><input 
wicket:id='input21'/><input wicket:id='input22'/><input 
wicket:id='input23'/></form>");
                }
 
        }
@@ -215,6 +228,12 @@ public class PropertyValidatorRequiredTest
                @NotNull(groups = { GroupOne.class, GroupTwo.class })
                String propertyOneTwo;
 
+               @NotEmpty
+               String propertyNotEmpty;
+
+               @NotBlank
+               String propertyNotBlank;
+
        }
 
 }

Reply via email to