Repository: wicket
Updated Branches:
  refs/heads/wicket-6.x c3795bd0e -> f2f77d8fc


WICKET-5654 DefaultViolationTranslator should maybe use getMessage()


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

Branch: refs/heads/wicket-6.x
Commit: f2f77d8fcf7eeeac309010948ca36671cc51ac49
Parents: c3795bd
Author: adelbene <[email protected]>
Authored: Wed Aug 20 12:36:24 2014 +0200
Committer: adelbene <[email protected]>
Committed: Wed Aug 20 15:56:51 2014 +0200

----------------------------------------------------------------------
 wicket-bean-validation/pom.xml                  |   6 +
 .../validation/DefaultViolationTranslator.java  |  71 +++++++++---
 .../validation/DefaultPropertyResolverTest.java | 113 ++++++++++++++++++-
 .../PasswordConstraintAnnotation.java           |  45 ++++++++
 .../customconstraint/PasswordValidator.java     |  58 ++++++++++
 5 files changed, 272 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/f2f77d8f/wicket-bean-validation/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-bean-validation/pom.xml b/wicket-bean-validation/pom.xml
index 1c239bb..8e8886f 100644
--- a/wicket-bean-validation/pom.xml
+++ b/wicket-bean-validation/pom.xml
@@ -31,6 +31,12 @@
                        <version>4.3.1.Final</version>
                        <scope>test</scope>
                </dependency>
+               <dependency>
+                       <groupId>org.glassfish.web</groupId>
+                       <artifactId>el-impl</artifactId>
+                       <version>2.2</version>
+                       <scope>test</scope>
+               </dependency>
        </dependencies>
        <build>
                <plugins>

http://git-wip-us.apache.org/repos/asf/wicket/blob/f2f77d8f/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/DefaultViolationTranslator.java
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/DefaultViolationTranslator.java
 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/DefaultViolationTranslator.java
index feec4f3..7b006aa 100644
--- 
a/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/DefaultViolationTranslator.java
+++ 
b/wicket-bean-validation/src/main/java/org/apache/wicket/bean/validation/DefaultViolationTranslator.java
@@ -1,5 +1,8 @@
 package org.apache.wicket.bean.validation;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.validation.ConstraintViolation;
 import javax.validation.metadata.ConstraintDescriptor;
 
@@ -24,37 +27,69 @@ public class DefaultViolationTranslator implements 
IViolationTranslator
                ValidationError error = new ValidationError();
                error.setMessage(violation.getMessage());
 
-               String messageKey = getMessageKey(desc);
-               if (messageKey != null)
-               {
-                       if (violation.getInvalidValue() != null)
-                       {
-                               error.addKey(messageKey + "." +
-                                       
violation.getInvalidValue().getClass().getSimpleName());
-                       }
-                       error.addKey(messageKey);
-               }
+               List<String> messages = getViolationMessages(violation, desc);
+               addErrorKeys(error, violation.getInvalidValue(), messages);
 
                for (String key : desc.getAttributes().keySet())
                {
                        error.setVariable(key, desc.getAttributes().get(key));
                }
+               
                return error;
        }
 
-       private String getMessageKey(ConstraintDescriptor<?> desc)
+       private List<String> getViolationMessages(ConstraintViolation<?> 
violation,
+               ConstraintDescriptor<?> desc)
        {
-               final Object val = desc.getAttributes().get("message");
-               if (val != null)
+               String defaultMessage = 
(String)desc.getAttributes().get("message");
+               String violationMessage = violation.getMessage();
+               String violationMessageTemplate = 
violation.getMessageTemplate();               
+               List<String> messages = new ArrayList<String>();
+
+               //violation message is considered only if it is different from
+               //the interpolated message
+               if (!Strings.isEqual(violationMessage, 
violationMessageTemplate))
                {
-                       String str = val.toString();
-                       if (!Strings.isEmpty(str) && str.startsWith("{") && 
str.endsWith("}"))
+                       messages.add(violationMessageTemplate);
+               }
+               
+               messages.add(violationMessage);
+               
+               //the default message is considered only if it is different from
+               //the violation message template
+               if (!Strings.isEqual(defaultMessage, violationMessageTemplate))
+               {
+                       messages.add(defaultMessage);
+               }
+
+               return messages;
+       }
+
+       private void addErrorKeys(ValidationError error, Object invalidValue, 
List<String> messages)
+       {
+               for (String message : messages)
+               {
+                       String messageKey = getMessageKey(message);
+
+                       if (messageKey != null)
                        {
-                               return str.substring(1, str.length() - 1);
+                               if (invalidValue != null)
+                               {
+                                       error.addKey(messageKey + "." + 
invalidValue.getClass().getSimpleName());
+                               }
+
+                               error.addKey(messageKey);
                        }
                }
-               return null;
        }
 
-
+       private String getMessageKey(String message)
+       {
+               if (!Strings.isEmpty(message) && message.startsWith("{") && 
message.endsWith("}"))
+               {
+                       return message.substring(1, message.length() - 1);
+               }
+       
+               return null;
+       }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/f2f77d8f/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/DefaultPropertyResolverTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/DefaultPropertyResolverTest.java
 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/DefaultPropertyResolverTest.java
index 99ad65d..56eebb1 100644
--- 
a/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/DefaultPropertyResolverTest.java
+++ 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/DefaultPropertyResolverTest.java
@@ -16,12 +16,28 @@
  */
 package org.apache.wicket.bean.validation;
 
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.*;
-
+import static 
org.apache.wicket.bean.validation.customconstraint.PasswordConstraintAnnotation.CUSTOM_BUNDLE_KEY;
+import static 
org.apache.wicket.bean.validation.customconstraint.PasswordConstraintAnnotation.DEFAULT_BUNDLE_KEY;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+import 
org.apache.wicket.bean.validation.customconstraint.PasswordConstraintAnnotation;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.util.tester.WicketTesterScope;
+import org.apache.wicket.validation.ValidationError;
 import org.junit.Rule;
 import org.junit.Test;
 
@@ -116,6 +132,76 @@ public class DefaultPropertyResolverTest
                assertThat(property.getOwner().getName(), 
is(Bean4.class.getName()));
        }
 
+       /**
+        * Test custom bundle mechanism of jsr 303
+        * 
+        * https://issues.apache.org/jira/browse/WICKET-5654
+        * 
+        * @throws Exception
+        */
+       @Test
+       public void testBundleKeysResolution() throws Exception
+       {
+               ValidatorFactory factory = 
Validation.buildDefaultValidatorFactory();
+               Validator validator = factory.getValidator();
+               DefaultViolationTranslator translator = new 
DefaultViolationTranslator();
+
+               // test with a too short password
+               BeanWithPassword bean = new BeanWithPassword("short");
+
+               Set<ConstraintViolation<BeanWithPassword>> constraintViolations 
= validator.validate(bean);
+               assertEquals(1, constraintViolations.size());
+
+               @SuppressWarnings("unchecked")
+               ConstraintViolation<BeanWithPassword> shortViolation = 
(ConstraintViolation<BeanWithPassword>)constraintViolations
+                       .toArray()[0];
+
+               ValidationError error = translator.convert(shortViolation);
+
+               checkErrorBundleKeys(error, DEFAULT_BUNDLE_KEY + ".String", 
DEFAULT_BUNDLE_KEY);
+
+               // test with a password containing non-word chars
+               bean.setPassword("notWord&%$£");
+
+               constraintViolations = validator.validate(bean);
+               assertEquals(1, constraintViolations.size());
+
+               @SuppressWarnings("unchecked")
+               ConstraintViolation<BeanWithPassword> nonWordviolation = 
(ConstraintViolation<BeanWithPassword>)constraintViolations.toArray()[0];
+
+               error = translator.convert(nonWordviolation);
+
+               checkErrorBundleKeys(error, CUSTOM_BUNDLE_KEY + ".String", 
CUSTOM_BUNDLE_KEY,
+                       DEFAULT_BUNDLE_KEY + ".String", DEFAULT_BUNDLE_KEY);
+
+               // test with a valid password
+               bean.setPassword("aValidPassword1234");
+
+               constraintViolations = validator.validate(bean);
+               assertEquals(0, constraintViolations.size());
+       }
+
+       /**
+        * Checks that validation error has the expected keys as bundle keys, 
in the order they are
+        * specified in {@code expectedKeys}.
+        * 
+        * @param error
+        * @param expectedKeys
+        */
+       private void checkErrorBundleKeys(ValidationError error, String... 
expectedKeys)
+       {
+               List<String> keys = error.getKeys();
+
+               assertEquals("The expected number for bundle keys is '" + 
expectedKeys.length
+                       + "' but we have '" + keys.size() + "'", 
expectedKeys.length, keys.size());
+
+               for (int i = 0; i < expectedKeys.length; i++)
+               {
+                       String expectedKey = expectedKeys[i];
+
+                       assertTrue(keys.get(i).equals(expectedKey));
+               }
+       }
 
        public static class Bean3
        {
@@ -143,4 +229,25 @@ public class DefaultPropertyResolverTest
                        return "foo4";
                }
        }
+       
+       public static class BeanWithPassword
+        {
+            @PasswordConstraintAnnotation
+            private String password;
+
+               public BeanWithPassword(String password)
+               {
+                       this.password = password;
+               }
+
+               public String getPassword()
+               {
+                       return password;
+               }
+
+               public void setPassword(String password)
+               {
+                       this.password = password;
+               }
+        }
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/f2f77d8f/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordConstraintAnnotation.java
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordConstraintAnnotation.java
 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordConstraintAnnotation.java
new file mode 100644
index 0000000..73f0ab1
--- /dev/null
+++ 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordConstraintAnnotation.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.bean.validation.customconstraint;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ METHOD, FIELD, ANNOTATION_TYPE })
+@Retention(RUNTIME)
+@Constraint(validatedBy = PasswordValidator.class)
+@Documented
+public @interface PasswordConstraintAnnotation 
+{
+       public static final String DEFAULT_BUNDLE_KEY = "default.bundle.key";
+       public static final String CUSTOM_BUNDLE_KEY = "custom.bundle.key";
+       
+       String message() default "{" + DEFAULT_BUNDLE_KEY +"}";
+
+       Class<?>[] groups() default { };
+
+       Class<? extends Payload>[] payload() default { };
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/f2f77d8f/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordValidator.java
----------------------------------------------------------------------
diff --git 
a/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordValidator.java
 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordValidator.java
new file mode 100644
index 0000000..a319953
--- /dev/null
+++ 
b/wicket-bean-validation/src/test/java/org/apache/wicket/bean/validation/customconstraint/PasswordValidator.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.wicket.bean.validation.customconstraint;
+
+import java.util.regex.Matcher;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+import org.apache.wicket.util.parse.metapattern.MetaPattern;
+import org.apache.wicket.util.string.Strings;
+
+public class PasswordValidator implements 
ConstraintValidator<PasswordConstraintAnnotation, String>
+{
+
+       @Override
+       public void initialize(PasswordConstraintAnnotation 
constraintAnnotation)
+       {
+       }
+
+       @Override
+       public boolean isValid(String value, ConstraintValidatorContext context)
+       {
+               // password must be at least 8 chars long.
+               if (Strings.isEmpty(value) || value.length() < 8)
+               {
+                       return false;
+               }
+
+               Matcher matcher = MetaPattern.NON_WORD.matcher(value);
+               
+               // password must not contain non-word characters.
+               if (matcher.find())
+               {
+                       context.disableDefaultConstraintViolation();
+                       context.buildConstraintViolationWithTemplate("{" +
+                               PasswordConstraintAnnotation.CUSTOM_BUNDLE_KEY 
+ "}").addConstraintViolation();
+                       return false;
+               }
+
+               return true;
+       }
+
+}

Reply via email to