[hibernate-commits] Hibernate SVN: r15763 - in validator/trunk: hibernate-validator/src/main/java/org/hibernate/validation/constraints and 6 other directories.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Fri Jan 9 08:45:30 EST 2009
Author: hardy.ferentschik
Date: 2009-01-09 08:45:30 -0500 (Fri, 09 Jan 2009)
New Revision: 15763
Added:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryBuilderImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/FrenchZipcode.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
validator/trunk/pom.xml
validator/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java
Log:
BVAL-31 added support for @OverridesParameters; refactoring
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/Patterns.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -20,6 +20,7 @@
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
@@ -28,7 +29,7 @@
* @author Hardy Ferentschik
*/
@Documented
- at Target({ METHOD, FIELD })
+ at Target({ METHOD, FIELD, TYPE })
@Retention(RUNTIME)
public @interface Patterns {
Pattern[] value();
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -68,7 +68,7 @@
private Class<?> currentGroup;
/**
- * Stack for keep track of the currently validated object.
+ * Stack for keeping track of the currently validated object.
*/
private Stack<ValidatedBean> validatedObjectStack = new Stack<ValidatedBean>();
@@ -79,7 +79,7 @@
public ValidationContext(T rootBean, Object object) {
this.rootBean = rootBean;
- validatedObjectStack.push( new ValidatedBean(object) );
+ validatedObjectStack.push( new ValidatedBean( object ) );
processedObjects = new HashMap<Class<?>, IdentitySet>();
propertyPath = "";
failingConstraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
@@ -94,7 +94,7 @@
}
public void pushValidatedObject(Object validatedObject) {
- validatedObjectStack.push( new ValidatedBean(validatedObject) );
+ validatedObjectStack.push( new ValidatedBean( validatedObject ) );
}
public void popValidatedObject() {
@@ -186,7 +186,9 @@
return groups.contains( currentGroup );
}
- //TODO caching the object class is useful?
+ /**
+ * @todo Is it useful to cache the object class?
+ */
private static class ValidatedBean {
final Object bean;
@@ -194,7 +196,7 @@
private ValidatedBean(Object bean) {
this.bean = bean;
- if (bean == null) {
+ if ( bean == null ) {
this.beanType = null;
}
else {
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -30,15 +30,14 @@
import javax.validation.BeanDescriptor;
import javax.validation.Constraint;
import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintFactory;
import javax.validation.ConstraintViolation;
import javax.validation.MessageResolver;
import javax.validation.TraversableResolver;
import javax.validation.ValidationException;
import javax.validation.Validator;
-import javax.validation.ConstraintFactory;
import javax.validation.groups.Default;
-import org.hibernate.validation.Version;
import org.hibernate.validation.impl.ConstraintViolationImpl;
import org.hibernate.validation.util.PropertyIterator;
import org.hibernate.validation.util.ReflectionHelper;
@@ -60,12 +59,6 @@
INDEXABLE_CLASS.add( String.class );
}
-
- //TODO move to Factory at least
- static {
- Version.touch();
- }
-
/**
* Message resolver used for interpolating error messages.
*/
@@ -151,10 +144,10 @@
BeanMetaData<T> beanMetaData =
( BeanMetaData<T> ) factory.getBeanMetaData( context.peekValidatedObjectType() );
for ( MetaConstraint metaConstraint : beanMetaData.getConstraintMetaDataList() ) {
- ConstraintDescriptor constraintDescriptor = metaConstraint.getDescriptor();
+ ConstraintDescriptor mainConstraintDescriptor = metaConstraint.getDescriptor();
context.pushProperty( metaConstraint.getPropertyName() );
- if ( !context.needsValidation( constraintDescriptor.getGroups() ) ) {
+ if ( !context.needsValidation( mainConstraintDescriptor.getGroups() ) ) {
context.popProperty();
continue;
}
@@ -162,9 +155,10 @@
final Object leafBeanInstance = context.peekValidatedObject();
Object value = metaConstraint.getValue( leafBeanInstance );
+ // we have to check the main constraint and all composing constraints
Set<ConstraintDescriptor> descriptors = new HashSet<ConstraintDescriptor>();
- descriptors.addAll( constraintDescriptor.getComposingConstraints() );
- descriptors.add(constraintDescriptor);
+ descriptors.addAll( mainConstraintDescriptor.getComposingConstraints() );
+ descriptors.add(mainConstraintDescriptor);
for (ConstraintDescriptor descriptor : descriptors) {
ConstraintContextImpl contextImpl = new ConstraintContextImpl( descriptor );
if ( !getConstraint( descriptor ).isValid( value, contextImpl ) ) {
@@ -353,6 +347,9 @@
return factory.getBeanMetaData( clazz ).getBeanDescriptor();
}
+ /**
+ * @todo Implement composing constraints.
+ */
private <T> void validateValue(Class<T> beanType, Object object, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, Class<?>... groups) {
ConstraintDescriptor constraintDescriptor = getConstraintDescriptorForPath( beanType, propertyIter );
@@ -434,7 +431,7 @@
for ( MetaConstraint metaConstraint : metaConstraintList ) {
ConstraintDescriptor constraintDescriptor = metaConstraint.getDescriptor();
if ( metaConstraint.getPropertyName().equals( propertyIter.getHead() ) ) {
- matchingConstraintDescriptor = ( ConstraintDescriptor ) constraintDescriptor;
+ matchingConstraintDescriptor = constraintDescriptor;
}
}
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -26,6 +26,7 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.List;
import javax.validation.Constraint;
import javax.validation.ConstraintDescriptor;
import javax.validation.ConstraintValidator;
@@ -51,21 +52,27 @@
public class ConstraintDescriptorImpl implements ConstraintDescriptor {
private static final Logger log = LoggerFactory.make();
private static final Class<?>[] DEFAULT_GROUP = new Class<?>[] { Default.class };
+ private static final int OVERRIDES_PARAMETER_DEFAULT_INDEX = -1;
private final Annotation annotation;
private final Class<? extends Constraint> constraintClass;
private final Set<Class<?>> groups;
private final Map<String, Object> parameters;
private final Set<ConstraintDescriptor> composingConstraints = new HashSet<ConstraintDescriptor>();
+ private final Map<ClassIndexWrapper, Map<String, Object>> overrideParameters = new HashMap<ClassIndexWrapper, Map<String, Object>>();
private final boolean isReportAsSingleInvalidConstraint;
public ConstraintDescriptorImpl(Annotation annotation, Class<?>[] groups) {
- this.annotation = annotation;
+ this( annotation, new HashSet<Class<?>>() );
if ( groups.length == 0 ) {
groups = DEFAULT_GROUP;
}
- this.groups = new HashSet<Class<?>>();
this.groups.addAll( Arrays.asList( groups ) );
+ }
+
+ public ConstraintDescriptorImpl(Annotation annotation, Set<Class<?>> groups) {
+ this.annotation = annotation;
+ this.groups = groups;
this.parameters = getAnnotationParameters( annotation );
this.isReportAsSingleInvalidConstraint = annotation.annotationType().isAnnotationPresent(
@@ -82,49 +89,8 @@
this.constraintClass = constraintValidator.value();
}
-
- // check for overrides
- Map<ClassIndexWrapper, Map<String, Object>> overrideParameters = new HashMap<ClassIndexWrapper, Map<String, Object>>();
- for ( Method m : annotation.annotationType().getMethods() ) {
- if ( m.getAnnotation( OverridesParameter.class ) != null ) {
- addOverrideParameter(
- overrideParameters, getMethodValue( annotation, m ), m.getAnnotation( OverridesParameter.class )
- );
- }
- else if ( m.getAnnotation( OverridesParameters.class ) != null ) {
- addOverrideParameter(
- overrideParameters,
- getMethodValue( annotation, m ),
- m.getAnnotation( OverridesParameters.class ).value()
- );
- }
- }
-
- // check for composing constraints
- for ( Annotation a : annotation.annotationType().getDeclaredAnnotations() ) {
- if ( ReflectionHelper.isConstraintAnnotation( a ) || ReflectionHelper.isBuiltInConstraintAnnotation( a ) ) {
- AnnotationDescriptor annotationDescriptor = new AnnotationDescriptor(
- a.annotationType(), getAnnotationParameters( a )
- );
- Map<String, Object> overrides = overrideParameters.get(
- new ClassIndexWrapper(
- a.annotationType(), -1
- )
- );
- if ( overrides != null ) {
- for ( Map.Entry<String, Object> entry : overrides.entrySet() ) {
- annotationDescriptor.setValue( entry.getKey(), entry.getValue() );
- }
- }
- Annotation annotationProxy = AnnotationFactory.create( annotationDescriptor );
- ConstraintDescriptorImpl descriptor = new ConstraintDescriptorImpl( annotationProxy, groups );
- composingConstraints.add( descriptor );
- log.debug( "Adding composing constraint: " + descriptor );
- }
- else if ( ReflectionHelper.isMultiValueConstraint( a ) ) {
- // todo - implement
- }
- }
+ parseOverrideParameters();
+ parseComposingConstraints();
}
/**
@@ -226,6 +192,69 @@
return value;
}
+ private void parseOverrideParameters() {
+ // check for overrides
+ for ( Method m : annotation.annotationType().getMethods() ) {
+ if ( m.getAnnotation( OverridesParameter.class ) != null ) {
+ addOverrideParameter(
+ overrideParameters, getMethodValue( annotation, m ), m.getAnnotation( OverridesParameter.class )
+ );
+ }
+ else if ( m.getAnnotation( OverridesParameters.class ) != null ) {
+ addOverrideParameter(
+ overrideParameters,
+ getMethodValue( annotation, m ),
+ m.getAnnotation( OverridesParameters.class ).value()
+ );
+ }
+ }
+ }
+
+ private void parseComposingConstraints() {
+ for ( Annotation declaredAnnotation : annotation.annotationType().getDeclaredAnnotations() ) {
+ if ( ReflectionHelper.isConstraintAnnotation( declaredAnnotation ) || ReflectionHelper.isBuiltInConstraintAnnotation(
+ declaredAnnotation
+ ) ) {
+ ConstraintDescriptorImpl descriptor = createComposingConstraintDescriptor(
+ OVERRIDES_PARAMETER_DEFAULT_INDEX,
+ declaredAnnotation
+ );
+ composingConstraints.add( descriptor );
+ log.debug( "Adding composing constraint: " + descriptor );
+ }
+ else if ( ReflectionHelper.isMultiValueConstraint( declaredAnnotation ) ) {
+ List<Annotation> multiValueConstraints = ReflectionHelper.getMultiValueConstraints( declaredAnnotation );
+ int index = 1;
+ for ( Annotation constraintAnnotation : multiValueConstraints ) {
+ ConstraintDescriptorImpl descriptor = createComposingConstraintDescriptor(
+ index, constraintAnnotation
+ );
+ composingConstraints.add( descriptor );
+ log.debug( "Adding composing constraint: " + descriptor );
+ index++;
+ }
+ }
+ }
+ }
+
+ private ConstraintDescriptorImpl createComposingConstraintDescriptor(int index, Annotation constraintAnnotation) {
+ AnnotationDescriptor annotationDescriptor = new AnnotationDescriptor(
+ constraintAnnotation.annotationType(), getAnnotationParameters( constraintAnnotation )
+ );
+ Map<String, Object> overrides = overrideParameters.get(
+ new ClassIndexWrapper(
+ constraintAnnotation.annotationType(), index
+ )
+ );
+ if ( overrides != null ) {
+ for ( Map.Entry<String, Object> entry : overrides.entrySet() ) {
+ annotationDescriptor.setValue( entry.getKey(), entry.getValue() );
+ }
+ }
+ Annotation annotationProxy = AnnotationFactory.create( annotationDescriptor );
+ return new ConstraintDescriptorImpl( annotationProxy, groups );
+ }
+
private class ClassIndexWrapper {
final Class<?> clazz;
final int index;
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/HibernateValidationProvider.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -25,6 +25,7 @@
import javax.validation.spi.BootstrapState;
import org.hibernate.validation.HibernateValidatorFactoryBuilder;
+import org.hibernate.validation.Version;
/**
* Default implementation of <code>ValidationProvider</code> within Hibernate validator.
@@ -42,8 +43,10 @@
}
public <T extends ValidatorFactoryBuilder<T>> T createSpecializedValidatorFactoryBuilder(BootstrapState state, Class<T> builderClass) {
- if ( ! isSuitable( builderClass ) ) {
- throw new ValidationException("Illegal call to createSpecializedValidatorFactoryBuilder() for a non suitable provider");
+ if ( !isSuitable( builderClass ) ) {
+ throw new ValidationException(
+ "Illegal call to createSpecializedValidatorFactoryBuilder() for a non suitable provider"
+ );
}
//cast protected by isSuitable call
return builderClass.cast( new ValidatorFactoryBuilderImpl( this ) );
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryBuilderImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryBuilderImpl.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryBuilderImpl.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -32,11 +32,17 @@
import javax.validation.spi.ValidatorFactoryConfiguration;
import org.hibernate.validation.HibernateValidatorFactoryBuilder;
+import org.hibernate.validation.Version;
/**
* @author Emmanuel Bernard
*/
public class ValidatorFactoryBuilderImpl implements HibernateValidatorFactoryBuilder, ValidatorFactoryConfiguration {
+
+ static {
+ Version.touch();
+ }
+
//FIXME not sure why it is like that. We should cache these instances somehow. Static?
private final MessageResolver defaultMessageResolver = new ResourceBundleMessageResolver();
private final TraversableResolver defaultTraversableResolver = new DefaultTraversableResolver();
@@ -49,7 +55,7 @@
private TraversableResolver traversableResolver;
public ValidatorFactoryBuilderImpl(BootstrapState state) {
- if (state.getValidationProviderResolver() == null) {
+ if ( state.getValidationProviderResolver() == null ) {
this.providerResolver = new DefaultValidationProviderResolver();
}
else {
@@ -62,7 +68,7 @@
public ValidatorFactoryBuilderImpl(ValidationProvider provider) {
if ( provider == null ) {
- throw new ValidationException( "Assertion error: inconsistent ValidatorFactoryBuilderImpl construction");
+ throw new ValidationException( "Assertion error: inconsistent ValidatorFactoryBuilderImpl construction" );
}
this.provider = provider;
this.providerResolver = null;
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -34,7 +34,7 @@
* @author Hardy Ferentschik
*/
public class ValidatorFactoryImpl implements ValidatorFactoryImplementor {
-
+
private final MessageResolver messageResolver;
private final TraversableResolver traversableResolver;
private final ConstraintFactory constraintFactory;
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/FrenchZipcode.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/FrenchZipcode.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/constraint/FrenchZipcode.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -26,14 +26,19 @@
import java.lang.annotation.Target;
import javax.validation.ConstraintValidator;
import javax.validation.OverridesParameter;
+import javax.validation.OverridesParameters;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
+import org.hibernate.validation.constraints.Pattern;
+import org.hibernate.validation.constraints.Patterns;
+
/**
* @author Hardy Ferentschik
*/
@NotNull
- at Size(max = 5)
+ at Size
+ at Patterns({ @Pattern(regex = "....."), @Pattern(regex = "bar") })
@ConstraintValidator(FrenchZipcodeConstraint.class)
@Documented
@Target({ METHOD, FIELD, TYPE })
@@ -43,6 +48,16 @@
Class<?>[] groups() default { };
- @OverridesParameter(constraint = Size.class, parameter = "min")
+ @OverridesParameters({
+ @OverridesParameter(constraint = Size.class, parameter = "min"),
+ @OverridesParameter(constraint = Size.class, parameter = "max")
+ })
int size() default 5;
+
+ @OverridesParameter(constraint = Size.class, parameter = "message")
+ String sizeMessage() default "A french zip code has a length of 5";
+
+
+ @OverridesParameter(constraint = Pattern.class, parameter = "regex", index=2)
+ String regex() default "\\d*";
}
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -17,40 +17,21 @@
*/
package org.hibernate.validation.engine;
-import java.util.HashSet;
import java.util.Set;
import javax.validation.ConstraintViolation;
-import javax.validation.ValidationException;
import javax.validation.Validator;
-import javax.validation.Validation;
-import javax.validation.groups.Default;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
-import org.hibernate.validation.eg.Actor;
-import org.hibernate.validation.eg.Address;
-import org.hibernate.validation.eg.Animal;
-import org.hibernate.validation.eg.Author;
-import org.hibernate.validation.eg.Book;
-import org.hibernate.validation.eg.Boy;
-import org.hibernate.validation.eg.Customer;
-import org.hibernate.validation.eg.Dictonary;
-import org.hibernate.validation.eg.Engine;
-import org.hibernate.validation.eg.EnglishDictonary;
-import org.hibernate.validation.eg.Order;
-import org.hibernate.validation.eg.Unconstraint;
-import org.hibernate.validation.eg.First;
-import org.hibernate.validation.eg.Second;
-import org.hibernate.validation.eg.Last;
-import org.hibernate.validation.eg.DefaultAlias;
-import org.hibernate.validation.eg.FrenchAddress;
-import org.hibernate.validation.HibernateValidatorFactoryBuilder;
+import static org.hibernate.validation.util.TestUtil.getHibernateValidator;
+import static org.hibernate.validation.util.TestUtil.assertNumberOfViolations;
+import static org.hibernate.validation.util.TestUtil.assertConstraintViolation;
+
import org.hibernate.validation.constraints.NotNullConstraint;
import org.hibernate.validation.constraints.SizeContraint;
-import org.hibernate.tck.annotations.SpecAssertion;
+import org.hibernate.validation.constraints.PatternConstraint;
+import org.hibernate.validation.eg.FrenchAddress;
/**
* Tests for the implementation of <code>Validator</code>.
@@ -59,19 +40,6 @@
*/
public class ConstraintCompositionTest {
- private Validator hibernateValidator;
-
- //TODO should not be Hibernate specific in most case
- private Validator getHibernateValidator() {
- if ( hibernateValidator == null ) {
- HibernateValidatorFactoryBuilder builder = Validation
- .builderType( HibernateValidatorFactoryBuilder.class )
- .getBuilder();
- hibernateValidator = builder.build().getValidator();
- }
- return hibernateValidator;
- }
-
@Test
public void testComposition() {
Validator validator = getHibernateValidator();
@@ -81,28 +49,88 @@
address.setAddressline2( "BP 12 " );
address.setCity( "Bordeaux" );
Set<ConstraintViolation<FrenchAddress>> constraintViolations = validator.validate( address );
- assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
- ConstraintViolation<FrenchAddress> violation = constraintViolations.iterator().next();
- assertEquals(
- "Wrong error type",
+ assertNumberOfViolations( constraintViolations, 1 );
+ assertConstraintViolation(
+ constraintViolations.iterator().next(),
+ "may not be null",
NotNullConstraint.class,
- violation.getConstraintDescriptor().getConstraintClass()
+ FrenchAddress.class,
+ null,
+ "zipCode"
);
- assertEquals( "Wrong message", "may not be null", violation.getInterpolatedMessage() );
+
+ address.setZipCode( "abc" );
+ constraintViolations = validator.validate( address );
+ assertNumberOfViolations( constraintViolations, 3 );
+ for ( ConstraintViolation violation : constraintViolations ) {
+ if ( violation.getInterpolatedMessage().equals( "A french zip code has a length of 5" ) ) {
+ assertConstraintViolation(
+ violation,
+ "A french zip code has a length of 5",
+ SizeContraint.class,
+ FrenchAddress.class,
+ "abc",
+ "zipCode"
+ );
+ }
+ else if ( violation.getInterpolatedMessage().equals( "must match \"d*\"" ) ) {
+ assertConstraintViolation(
+ violation,
+ "must match \"d*\"",
+ PatternConstraint.class,
+ FrenchAddress.class,
+ "abc",
+ "zipCode"
+ );
+ }
+ else if ( violation.getInterpolatedMessage().equals( "must match \".....\"" ) ) {
+ assertConstraintViolation(
+ violation,
+ "must match \".....\"" ,
+ PatternConstraint.class,
+ FrenchAddress.class,
+ "abc",
+ "zipCode"
+ );
+ }
+ else {
+ fail( "Wrong violation found." );
+ }
+ }
+
+
address.setZipCode( "123" );
constraintViolations = validator.validate( address );
- assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
- violation = constraintViolations.iterator().next();
- assertEquals(
- "Wrong error type",
- SizeContraint.class,
- violation.getConstraintDescriptor().getConstraintClass()
- );
+ assertNumberOfViolations( constraintViolations, 2 );
+ for ( ConstraintViolation violation : constraintViolations ) {
+ if ( violation.getInterpolatedMessage().equals( "A french zip code has a length of 5" ) ) {
+ assertConstraintViolation(
+ violation,
+ "A french zip code has a length of 5",
+ SizeContraint.class,
+ FrenchAddress.class,
+ "123",
+ "zipCode"
+ );
+ }
+ else if ( violation.getInterpolatedMessage().equals( "must match \".....\"" ) ) {
+ assertConstraintViolation(
+ violation,
+ "must match \".....\"" ,
+ PatternConstraint.class,
+ FrenchAddress.class,
+ "123",
+ "zipCode"
+ );
+ }
+ else {
+ fail( "Wrong violation found." );
+ }
+ }
address.setZipCode( "33023" );
constraintViolations = validator.validate( address );
- assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
- assertEquals( "Wrong message", "size must be between 5 and 5", violation.getInterpolatedMessage() );
+ assertNumberOfViolations( constraintViolations, 0 );
}
}
\ No newline at end of file
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -22,7 +22,6 @@
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
import javax.validation.Validator;
-import javax.validation.Validation;
import javax.validation.groups.Default;
import static org.junit.Assert.assertEquals;
@@ -30,6 +29,7 @@
import static org.junit.Assert.fail;
import org.junit.Test;
+import org.hibernate.tck.annotations.SpecAssertion;
import org.hibernate.validation.eg.Actor;
import org.hibernate.validation.eg.Address;
import org.hibernate.validation.eg.Animal;
@@ -37,17 +37,16 @@
import org.hibernate.validation.eg.Book;
import org.hibernate.validation.eg.Boy;
import org.hibernate.validation.eg.Customer;
+import org.hibernate.validation.eg.DefaultAlias;
import org.hibernate.validation.eg.Dictonary;
import org.hibernate.validation.eg.Engine;
import org.hibernate.validation.eg.EnglishDictonary;
-import org.hibernate.validation.eg.Order;
-import org.hibernate.validation.eg.Unconstraint;
import org.hibernate.validation.eg.First;
-import org.hibernate.validation.eg.Second;
import org.hibernate.validation.eg.Last;
-import org.hibernate.validation.eg.DefaultAlias;
-import org.hibernate.validation.HibernateValidatorFactoryBuilder;
-import org.hibernate.tck.annotations.SpecAssertion;
+import org.hibernate.validation.eg.Order;
+import org.hibernate.validation.eg.Second;
+import org.hibernate.validation.eg.Unconstraint;
+import org.hibernate.validation.util.TestUtil;
/**
* Tests for the implementation of <code>Validator</code>.
@@ -56,29 +55,11 @@
*/
public class ValidatorImplTest {
- private Validator hibernateValidator;
-
- //TODO should not be Hibernate specific in most case
- private Validator getHibernateValidator() {
- if (hibernateValidator == null) {
- HibernateValidatorFactoryBuilder builder = Validation
- .builderType( HibernateValidatorFactoryBuilder.class )
- .getBuilder();
- hibernateValidator = builder.build().getValidator();
- }
- return hibernateValidator;
- }
-
-
- /**
- * JSR 303: Requirements on classes to be validates (3.1)
- * @jsr 3.1
- */
@SpecAssertion( section = {"3.1"} )
@Test
public void testWrongMethodName() {
try {
- getHibernateValidator().getConstraintsForClass( Boy.class ).hasConstraints();
+ TestUtil.getHibernateValidator().getConstraintsForClass( Boy.class ).hasConstraints();
fail();
}
catch ( ValidationException e ) {
@@ -93,36 +74,36 @@
@Test(expected = IllegalArgumentException.class)
public void testNullParamterToValidatorImplConstructor() {
- getHibernateValidator().getConstraintsForClass( null );
+ TestUtil.getHibernateValidator().getConstraintsForClass( null );
}
@Test
public void testUnconstraintClass() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
assertTrue( "There should be no constraints", !validator.getConstraintsForClass( Unconstraint.class ).hasConstraints() );
}
@Test
public void testHasConstraints() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
assertTrue( "There should be constraints", validator.getConstraintsForClass( Customer.class ).hasConstraints() );
}
@Test(expected = IllegalArgumentException.class)
public void testValidateWithNull() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
validator.validate( null );
}
@Test(expected = IllegalArgumentException.class)
public void testValidateWithNullProperty() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
validator.validateProperty( null, "firstName" );
}
@Test
public void testGroups() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Author author = new Author();
author.setLastName( "" );
@@ -175,7 +156,7 @@
@Test
public void testDefaultGroupSequence() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Author author = new Author();
author.setLastName( "" );
@@ -217,7 +198,7 @@
@Test
public void testBasicValidation() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Customer customer = new Customer();
customer.setFirstName( "John" );
@@ -233,7 +214,7 @@
@Test
public void testGroupSequences() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Dictonary dictonary = new Dictonary();
dictonary.setTitle( "English - German" );
@@ -249,7 +230,7 @@
@Test
public void testValidationFailureInMultipleGroups() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Animal elepfant = new Animal();
elepfant.setName( "" );
elepfant.setDomain( Animal.Domain.EUKARYOTA );
@@ -274,13 +255,13 @@
@Test(expected = ValidationException.class)
public void testInvalidSequenceName() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
validator.getConstraintsForClass( EnglishDictonary.class ).hasConstraints();
}
@Test
public void testValidationMethod() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Address address = new Address();
address.setAddressline1( null );
@@ -318,7 +299,7 @@
@Test
public void testValidateList() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Customer customer = new Customer();
customer.setFirstName( "John" );
@@ -340,13 +321,10 @@
}
- /**
- * JSR 303: Multi-valued constraints (2.2)
- * @jsr 2.2
- */
@Test
+ @SpecAssertion( section = {"2.2"} )
public void testMultiValueConstraint() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Engine engine = new Engine();
engine.setSerialNumber( "mail at foobar.com" );
@@ -362,14 +340,10 @@
assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
}
-
- /**
- * JSR 303: Object graph validation (3.5.1)
- * @jsr 3.5.1
- */
@Test
+ @SpecAssertion( section = {"3.5.1"} )
public void testGraphValidation() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Actor clint = new Actor( "Clint", "Eastwood" );
Actor morgan = new Actor( "Morgan", "" );
@@ -394,7 +368,7 @@
@Test
public void testValidateValue() {
- Validator validator = getHibernateValidator();
+ Validator validator = TestUtil.getHibernateValidator();
Order order = new Order();
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -0,0 +1,103 @@
+// $Id: ReflectionHelperTest.java 15751 2009-01-07 15:32:23Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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 org.hibernate.validation.util;
+
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+
+import static org.junit.Assert.assertEquals;
+
+import org.hibernate.validation.HibernateValidatorFactoryBuilder;
+
+/**
+ * Tests for the <code>ReflectionHelper</code>.
+ *
+ * @author Hardy Ferentschik
+ */
+public class TestUtil {
+
+ private static Validator hibernateValidator;
+
+ private TestUtil() {
+ }
+
+ public static Validator getHibernateValidator() {
+ if ( hibernateValidator == null ) {
+ HibernateValidatorFactoryBuilder builder = Validation
+ .builderType( HibernateValidatorFactoryBuilder.class )
+ .getBuilder();
+ hibernateValidator = builder.build().getValidator();
+ }
+ return hibernateValidator;
+ }
+
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean, Object invalidValue, String propertyPath, Class leafBean) {
+ assertEquals(
+ "Wrong leaf bean type",
+ leafBean,
+ violation.getLeafBean().getClass()
+ );
+ assertConstraintViolation( violation, errorMessage, constraintType, rootBean, invalidValue, propertyPath );
+ }
+
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean, Object invalidValue, String propertyPath) {
+ assertEquals(
+ "Wrong propertyPath",
+ propertyPath,
+ violation.getPropertyPath()
+ );
+ assertConstraintViolation( violation, errorMessage, constraintType, rootBean, invalidValue );
+ }
+
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean, Object invalidValue) {
+ assertEquals(
+ "Wrong invalid value",
+ invalidValue,
+ violation.getInvalidValue()
+ );
+ assertConstraintViolation( violation, errorMessage, constraintType, rootBean );
+ }
+
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean) {
+ assertEquals(
+ "Wrong root bean type",
+ rootBean,
+ violation.getRootBean().getClass()
+ );
+ assertConstraintViolation( violation, errorMessage, constraintType );
+ }
+
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType) {
+ assertEquals(
+ "Wrong constraint error Type",
+ constraintType,
+ violation.getConstraintDescriptor().getConstraintClass()
+ );
+ assertConstraintViolation( violation, errorMessage );
+ }
+
+ public static void assertConstraintViolation(ConstraintViolation violation, String message) {
+ assertEquals( "Wrong message", message, violation.getInterpolatedMessage() );
+ }
+
+ public static void assertNumberOfViolations(Set violations, int expectedViolations) {
+ assertEquals( "Wrong number of constraint violations", expectedViolations, violations.size() );
+ }
+}
Modified: validator/trunk/pom.xml
===================================================================
--- validator/trunk/pom.xml 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/pom.xml 2009-01-09 13:45:30 UTC (rev 15763)
@@ -124,6 +124,9 @@
<configuration>
<forkMode>always</forkMode>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
+ <includes>
+ <include>**/*Test.java</include>
+ </includes>
</configuration>
</plugin>
<plugin>
Modified: validator/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java 2009-01-09 11:32:38 UTC (rev 15762)
+++ validator/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java 2009-01-09 13:45:30 UTC (rev 15763)
@@ -6,7 +6,7 @@
* Contract determining if a property can be accessed by the Bean Validation provider
* This contract is called for each property either validated or traversed
*
- * A traversable resolver implementation must me thread-safe
+ * A traversable resolver implementation must me thread-safe.
*
* @author Emmanuel Bernard
*/
@@ -14,14 +14,14 @@
/**
* Determine if a property can be traversed by Bean Validation.
*
- * @param traversableObject object hosting traversableProperty
- * @param traversableProperty name of the traqversable property
+ * @param traversableObject object hosting <code>traversableProperty</code>.
+ * @param traversableProperty name of the traqversable property.
* @param rootBeanType type of the root object passed to the Validator.
- * @param pathToTraversableObject path from the root object to the traversableObject
- * (using the path specification defined by Bean Validator)
- * @param elementType either FIELD or METHOD
+ * @param pathToTraversableObject path from the root object to the <code>traversableProperty</code>
+ * (using the path specification defined by Bean Validator).
+ * @param elementType either <code>FIELD</code> or <code>METHOD</code>.
*
- * @return true if the property is traversable by Bean Validation
+ * @return <code>true</code> if the property is traversable by Bean Validation, <code>false</code> otherwise.
*/
boolean isTraversable(Object traversableObject,
String traversableProperty,
More information about the hibernate-commits
mailing list