On Wed, Aug 20, 2014 at 1:46 PM, <[email protected]> wrote:
> Repository: wicket
> Updated Branches:
> refs/heads/master 70368f123 -> 6b62b86ae
>
>
> 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/6b62b86a
> Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/6b62b86a
> Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/6b62b86a
>
> Branch: refs/heads/master
> Commit: 6b62b86ae853150fda617e393d269c9fb9e17a77
> Parents: 70368f1
> Author: adelbene <[email protected]>
> Authored: Wed Aug 20 12:36:24 2014 +0200
> Committer: adelbene <[email protected]>
> Committed: Wed Aug 20 12:46:22 2014 +0200
>
> ----------------------------------------------------------------------
> wicket-bean-validation/pom.xml | 6 +
> .../validation/DefaultViolationTranslator.java | 71 +++++++---
> .../validation/DefaultPropertyResolverTest.java | 129 +++++++++++++++++--
> .../PasswordConstraintAnnotation.java | 45 +++++++
> .../customconstraint/PasswordValidator.java | 58 +++++++++
> 5 files changed, 278 insertions(+), 31 deletions(-)
> ----------------------------------------------------------------------
>
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/6b62b86a/wicket-bean-validation/pom.xml
> ----------------------------------------------------------------------
> diff --git a/wicket-bean-validation/pom.xml
> b/wicket-bean-validation/pom.xml
> index 0b52e32..b91e4e7 100644
> --- a/wicket-bean-validation/pom.xml
> +++ b/wicket-bean-validation/pom.xml
> @@ -37,5 +37,11 @@
> <version>5.1.2.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>
> </project>
>
>
> http://git-wip-us.apache.org/repos/asf/wicket/blob/6b62b86a/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());
>
Use Classes.simpleName(invalidValue.getClass()) instead.
It is smarter when dealing with anonymous classes.
> + }
> +
> + 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/6b62b86a/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 2ef498f..1dc6802 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;
>
> @@ -45,8 +61,7 @@ public class DefaultPropertyResolverTest
> {
> DefaultPropertyResolver resolver = new
> DefaultPropertyResolver();
>
> - TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean1>(new Bean1(),
> - "foo"));
> + TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean1>(new Bean1(), "foo"));
> Property property = resolver.resolveProperty(component);
> assertThat(property, not(nullValue()));
> assertThat(property.getName(), is("foo"));
> @@ -61,8 +76,8 @@ public class DefaultPropertyResolverTest
> {
> DefaultPropertyResolver resolver = new
> DefaultPropertyResolver();
>
> - TextField<?> component = new TextField<>("id", new
> PropertyModel<BooleanBean>(new BooleanBean(),
> - "foo"));
> + TextField<?> component = new TextField<>("id", new
> PropertyModel<BooleanBean>(
> + new BooleanBean(), "foo"));
> Property property = resolver.resolveProperty(component);
> assertThat(property, not(nullValue()));
> assertThat(property.getName(), is("foo"));
> @@ -74,8 +89,7 @@ public class DefaultPropertyResolverTest
> {
> DefaultPropertyResolver resolver = new
> DefaultPropertyResolver();
>
> - TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean2>(new Bean2(),
> - "foo"));
> + TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean2>(new Bean2(), "foo"));
> Property property = resolver.resolveProperty(component);
> assertThat(property, not(nullValue()));
> assertThat(property.getName(), is("foo"));
> @@ -92,8 +106,7 @@ public class DefaultPropertyResolverTest
> {
> DefaultPropertyResolver resolver = new
> DefaultPropertyResolver();
>
> - TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean3>(new Bean3(),
> - "foo"));
> + TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean3>(new Bean3(), "foo"));
> Property property = resolver.resolveProperty(component);
> assertThat(property, not(nullValue()));
> assertThat(property.getName(), is("foo"));
> @@ -108,14 +121,83 @@ public class DefaultPropertyResolverTest
> {
> DefaultPropertyResolver resolver = new
> DefaultPropertyResolver();
>
> - TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean4>(new Bean4(),
> - "foo"));
> + TextField<?> component = new TextField<>("id", new
> PropertyModel<Bean4>(new Bean4(), "foo"));
> Property property = resolver.resolveProperty(component);
> assertThat(property, not(nullValue()));
> assertThat(property.getName(), is("foo"));
> 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 +225,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/6b62b86a/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/6b62b86a/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;
> + }
> +
> +}
>
>