[hibernate-commits] Hibernate SVN: r16049 - in validator/trunk/hibernate-validator/src: main/java/org/hibernate/validation/util and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Feb 27 12:04:57 EST 2009


Author: hardy.ferentschik
Date: 2009-02-27 12:04:57 -0500 (Fri, 27 Feb 2009)
New Revision: 16049

Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaData.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintViolationImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
Log:
- HV-106 Integrated TraversableResolver
- Some generic cleanup


Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaData.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaData.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaData.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -67,7 +67,7 @@
 	 * @return A list of <code>MetaConstraint</code> instances encapsulating the information of all the constraints
 	 *         defined on the bean.
 	 */
-	List<MetaConstraint<T>> geMetaConstraintList();
+	List<MetaConstraint<T, ?>> geMetaConstraintList();
 
 	/**
 	 * @return A map keying the property name of a constraint to its <code>ElementDescriptor</code>.

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -63,7 +63,7 @@
 	/**
 	 * List of constraints.
 	 */
-	private List<MetaConstraint<T>> metaConstraintList = new ArrayList<MetaConstraint<T>>();
+	private List<MetaConstraint<T, ?>> metaConstraintList = new ArrayList<MetaConstraint<T, ?>>();
 
 	/**
 	 * List of cascaded fields.
@@ -171,12 +171,12 @@
 		}
 	}
 
-	private void initFieldConstraints(Class clazz) {
+	private <A extends Annotation >void initFieldConstraints(Class clazz) {
 		for ( Field field : clazz.getDeclaredFields() ) {
 			List<ConstraintDescriptorImpl> fieldMetadata = findFieldLevelConstraints( field );
 			for ( ConstraintDescriptorImpl constraintDescription : fieldMetadata ) {
 				ReflectionHelper.setAccessibility( field );
-				MetaConstraint<T> metaConstraint = new MetaConstraint<T>( field, beanClass, constraintDescription );
+				MetaConstraint<T, A> metaConstraint = new MetaConstraint<T, A>( field, beanClass, constraintDescription );
 				metaConstraintList.add( metaConstraint );
 			}
 			if ( field.isAnnotationPresent( Valid.class ) ) {
@@ -186,12 +186,12 @@
 		}
 	}
 
-	private void initMethodConstraints(Class clazz) {
+	private <A extends Annotation> void initMethodConstraints(Class clazz) {
 		for ( Method method : clazz.getDeclaredMethods() ) {
 			List<ConstraintDescriptorImpl> methodMetadata = findMethodLevelConstraints( method );
 			for ( ConstraintDescriptorImpl constraintDescription : methodMetadata ) {
 				ReflectionHelper.setAccessibility( method );
-				MetaConstraint<T> metaConstraint = new MetaConstraint<T>( method, beanClass, constraintDescription );
+				MetaConstraint<T, A> metaConstraint = new MetaConstraint<T, A>( method, beanClass, constraintDescription );
 				metaConstraintList.add( metaConstraint );
 			}
 			if ( method.isAnnotationPresent( Valid.class ) ) {
@@ -201,10 +201,10 @@
 		}
 	}
 
-	private void initClassConstraints(Class clazz) {
+	private <A extends Annotation> void initClassConstraints(Class clazz) {
 		List<ConstraintDescriptorImpl> classMetadata = findClassLevelConstraints( clazz );
 		for ( ConstraintDescriptorImpl constraintDescription : classMetadata ) {
-			MetaConstraint<T> metaConstraint = new MetaConstraint<T>( clazz, constraintDescription );
+			MetaConstraint<T, A> metaConstraint = new MetaConstraint<T, A>( clazz, constraintDescription );
 			metaConstraintList.add( metaConstraint );
 		}
 	}
@@ -349,7 +349,7 @@
 		return cascadedMembers;
 	}
 
-	public List<MetaConstraint<T>> geMetaConstraintList() {
+	public List<MetaConstraint<T, ?>> geMetaConstraintList() {
 		return metaConstraintList;
 	}
 

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -23,8 +23,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
-import org.hibernate.validation.AmbiguousConstraintUsageException;
 import javax.validation.ConstraintDescriptor;
 import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintValidatorFactory;
@@ -33,6 +31,7 @@
 
 import org.slf4j.Logger;
 
+import org.hibernate.validation.AmbiguousConstraintUsageException;
 import org.hibernate.validation.util.LoggerFactory;
 import org.hibernate.validation.util.ValidatorTypeHelper;
 
@@ -42,19 +41,19 @@
  *
  * @author Hardy Ferentschik
  */
-public class ConstraintTree<T extends Annotation> {
+public class ConstraintTree<A extends Annotation> {
 
 	private static final Logger log = LoggerFactory.make();
 
 	private final ConstraintTree<?> parent;
 	private final List<ConstraintTree<?>> children;
-	private final ConstraintDescriptor<T> descriptor;
+	private final ConstraintDescriptor<A> descriptor;
 
-	public ConstraintTree(ConstraintDescriptor<T> descriptor) {
+	public ConstraintTree(ConstraintDescriptor<A> descriptor) {
 		this( descriptor, null );
 	}
 
-	private ConstraintTree(ConstraintDescriptor<T> descriptor, ConstraintTree<?> parent) {
+	private ConstraintTree(ConstraintDescriptor<A> descriptor, ConstraintTree<?> parent) {
 		this.parent = parent;
 		this.descriptor = descriptor;
 		final Set<ConstraintDescriptor<?>> composingConstraints = descriptor.getComposingConstraints();
@@ -86,23 +85,23 @@
 		return children.size() > 0;
 	}
 
-	public ConstraintDescriptor<T> getDescriptor() {
+	public ConstraintDescriptor<A> getDescriptor() {
 		return descriptor;
 	}
 
-	public <T> void validateConstraints(Object value, Class beanClass, ExecutionContext executionContext, List<ConstraintViolationImpl<T>> constraintViolations) {
-		for ( ConstraintTree tree : getChildren() ) {
+	public <T, V> void validateConstraints(V value, Class<T> beanClass, ExecutionContext<T> executionContext, List<ConstraintViolationImpl<T>> constraintViolations) {
+		for ( ConstraintTree<?> tree : getChildren() ) {
 			tree.validateConstraints( value, beanClass, executionContext, constraintViolations );
 		}
 
 		final Object leafBeanInstance = executionContext.peekValidatedObject();
-		ConstraintValidatorContextImpl constraintContext = new ConstraintValidatorContextImpl( descriptor );
 		if ( log.isTraceEnabled() ) {
 			log.trace( "Validating value {} against constraint defined by {}", value, descriptor );
 		}
-		ConstraintValidator validator = getInitalizedValidator(
+		ConstraintValidator<A, V> validator = getInitalizedValidator(
 				value, executionContext.getConstraintValidatorFactory()
 		);
+		ConstraintValidatorContextImpl constraintContext = new ConstraintValidatorContextImpl( descriptor );
 		if ( !validator.isValid( value, constraintContext ) ) {
 			for ( ConstraintValidatorContextImpl.ErrorMessage error : constraintContext.getErrorMessages() ) {
 				final String message = error.getMessage();
@@ -156,8 +155,8 @@
 	 *
 	 * @return A initalized constraint validator matching the type of the value to be validated.
 	 */
-	private ConstraintValidator getInitalizedValidator(Object value, ConstraintValidatorFactory constraintFactory) {
-		Class<? extends ConstraintValidator<T, ?>> validatorClass;
+	private <V> ConstraintValidator<A, V> getInitalizedValidator(Object value, ConstraintValidatorFactory constraintFactory) {
+		Class<? extends ConstraintValidator<?, ?>> validatorClass;
 		//FIXME This sounds really bad, why value can be null. Why are we deciding of the validator based on the value? 
 		if ( value == null ) {
 			validatorClass = descriptor.getConstraintValidatorClasses().get( 0 );
@@ -167,10 +166,10 @@
 		}
 		//
 		@SuppressWarnings("unchecked")
-		ConstraintValidator<T,?> constraintValidator =
+		ConstraintValidator<?, ?> constraintValidator =
 				constraintFactory.getInstance( validatorClass );
 		initializeConstraint( descriptor, constraintValidator );
-		return constraintValidator;
+		return ( ConstraintValidator<A, V> ) constraintValidator;
 	}
 
 	/**
@@ -180,12 +179,12 @@
 	 *
 	 * @return The class of a matching validator.
 	 */
-	private Class findMatchingValidatorClass(Object value) {
+	private Class<? extends ConstraintValidator<?, ?>> findMatchingValidatorClass(Object value) {
 
 		Class valueClass = determineValueClass( value );
 
 		Map<Class<?>, Class<? extends ConstraintValidator<?, ?>>> validatorsTypes =
-				ValidatorTypeHelper.getValidatorsTypes( descriptor.getConstraintValidatorClasses() );
+				ValidatorTypeHelper.getValidatorsTypes( ( List<Class<? extends ConstraintValidator<A, ?>>> ) descriptor.getConstraintValidatorClasses() );
 		List<Class> assignableClasses = findAssignableClasses( valueClass, validatorsTypes );
 
 		resolveAssignableClasses( assignableClasses );
@@ -258,7 +257,7 @@
 	}
 
 	private void initializeConstraint
-			(ConstraintDescriptor<T>
+			(ConstraintDescriptor<A>
 					descriptor, ConstraintValidator
 					constraintValidator) {
 		try {

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintViolationImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintViolationImpl.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintViolationImpl.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -17,8 +17,6 @@
 */
 package org.hibernate.validation.engine;
 
-import java.util.HashSet;
-import java.util.Set;
 import javax.validation.ConstraintDescriptor;
 import javax.validation.ConstraintViolation;
 

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -18,24 +18,20 @@
 package org.hibernate.validation.engine;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.MessageInterpolator;
+import javax.validation.TraversableResolver;
 
 import org.hibernate.validation.util.IdentitySet;
 
 /**
  * Context object keeping track of all processed objects and all failing constraints.
  * At the same time it keeps track of the currently validated object, the current group and property path.
- * The way the validation works at the moment the validated object and the property path have to be processed
- * in a stack fashion.
- * <p/>
- * all sort of information needed  Introduced to reduce the parameters passed around between the different
- * validate methdods in <code>ValidatorImpl</code>.
+ * Currently the validated object and the property path are processed in a stack fashion.
  *
  * @author Hardy Ferentschik
  * @author Emmanuel Bernard
@@ -72,7 +68,7 @@
 	 * Stack for keeping track of the currently validated object.
 	 */
 	private Stack<Object> validatedObjectStack = new Stack<Object>();
-	
+
 	/**
 	 * The message resolver which should be used in this context.
 	 */
@@ -81,17 +77,20 @@
 	/**
 	 * The constraint factory which should be used in this context.
 	 */
-	ConstraintValidatorFactory constraintValidatorFactory;
+	private final ConstraintValidatorFactory constraintValidatorFactory;
 
+	private final TraversableResolver traversableResolver;
 
-	public ExecutionContext(T object, MessageInterpolator messageResolver, ConstraintValidatorFactory constraintValidatorFactory) {
-		this( object, object, messageResolver, constraintValidatorFactory );
+	public ExecutionContext(T object, MessageInterpolator messageResolver, ConstraintValidatorFactory constraintValidatorFactory, TraversableResolver traversableResolver) {
+		this( object, object, messageResolver, constraintValidatorFactory, traversableResolver );
 	}
 
-	public ExecutionContext(T rootBean, Object object, MessageInterpolator messageResolver, ConstraintValidatorFactory constraintValidatorFactory) {
+	public ExecutionContext(T rootBean, Object object, MessageInterpolator messageResolver, ConstraintValidatorFactory constraintValidatorFactory, TraversableResolver traversableResolver) {
 		this.rootBean = rootBean;
 		this.messageResolver = messageResolver;
 		this.constraintValidatorFactory = constraintValidatorFactory;
+		this.traversableResolver = traversableResolver;
+
 		validatedObjectStack.push( object );
 		processedObjects = new HashMap<Class<?>, IdentitySet>();
 		propertyPath = "";
@@ -158,7 +157,7 @@
 	}
 
 	public void addConstraintFailures(List<ConstraintViolationImpl<T>> failingConstraintViolations) {
-		for(ConstraintViolationImpl<T> violation : failingConstraintViolations) {
+		for ( ConstraintViolationImpl<T> violation : failingConstraintViolations ) {
 			addConstraintFailure( violation );
 		}
 	}
@@ -211,7 +210,28 @@
 		return propertyPath;
 	}
 
-	public boolean checkValidationRequired(Collection<Class<?>> groups) {
-		return groups.contains( currentGroup );
+	public String peekProperty() {
+		int lastIndex = propertyPath.lastIndexOf( '.' );
+		if ( lastIndex != -1 ) {
+			return propertyPath.substring( 0, lastIndex );
+		}
+		else {
+			return "";
+		}
 	}
+
+	public boolean isValidationRequired(MetaConstraint metaConstraint) {
+		if ( !metaConstraint.getGroupList().contains( currentGroup ) ) {
+			return false;
+		}
+
+		Class<?> rootBeanClass = rootBean == null ? null : rootBean.getClass();
+		return traversableResolver.isTraversable(
+				peekValidatedObject(),
+				peekProperty(),
+				rootBeanClass,
+				peekPropertyPath(),
+				metaConstraint.getElementType()
+		);
+	}
 }
\ No newline at end of file

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -17,6 +17,7 @@
 */
 package org.hibernate.validation.engine;
 
+import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -35,12 +36,12 @@
  *
  * @author Hardy Ferentschik
  */
-public class MetaConstraint<T> {
+public class MetaConstraint<T, A extends Annotation> {
 
 	/**
 	 * The constraint tree created from the constraint annotation.
 	 */
-	private final ConstraintTree constraintTree;
+	private final ConstraintTree<A> constraintTree;
 
 	/**
 	 * The type (class) the constraint was defined on. <code>null</code> if the constraint was specified on method or
@@ -76,11 +77,11 @@
 	 */
 	private final Class<T> beanClass;
 
-	public MetaConstraint(Type t, ConstraintDescriptor constraintDescriptor) {
-		this( t, null, null, ElementType.TYPE, (Class<T>) t.getClass(), constraintDescriptor, "" );
+	public MetaConstraint(Type t, ConstraintDescriptor<A> constraintDescriptor) {
+		this( t, null, null, ElementType.TYPE, ( Class<T> ) t.getClass(), constraintDescriptor, "" );
 	}
 
-	public MetaConstraint(Method m, Class<T> beanClass, ConstraintDescriptor constraintDescriptor) {
+	public MetaConstraint(Method m, Class<T> beanClass, ConstraintDescriptor<A> constraintDescriptor) {
 		this(
 				null,
 				m,
@@ -92,18 +93,18 @@
 		);
 	}
 
-	public MetaConstraint(Field f, Class<T> beanClass, ConstraintDescriptor constraintDescriptor) {
-		this( null, null, f, ElementType.FIELD, beanClass, constraintDescriptor, f.getName());
+	public MetaConstraint(Field f, Class<T> beanClass, ConstraintDescriptor<A> constraintDescriptor) {
+		this( null, null, f, ElementType.FIELD, beanClass, constraintDescriptor, f.getName() );
 	}
 
-	private MetaConstraint(Type t, Method m, Field f, ElementType elementType, Class<T> beanClass, ConstraintDescriptor constraintDescriptor, String property) {
+	private MetaConstraint(Type t, Method m, Field f, ElementType elementType, Class<T> beanClass, ConstraintDescriptor<A> constraintDescriptor, String property) {
 		this.type = t;
 		this.method = m;
 		this.field = f;
 		this.elementType = elementType;
 		this.propertyName = property;
 		this.beanClass = beanClass;
-		constraintTree = new ConstraintTree( constraintDescriptor );
+		constraintTree = new ConstraintTree<A>( constraintDescriptor );
 	}
 
 
@@ -190,7 +191,7 @@
 		return constraintTree;
 	}
 
-	public <T> boolean validateConstraint(Class beanClass, ExecutionContext<T> executionContext) {
+	public <T> boolean validateConstraint(Class<T> beanClass, ExecutionContext<T> executionContext) {
 		final Object leafBeanInstance = executionContext.peekValidatedObject();
 		Object value = getValue( leafBeanInstance );
 		List<ConstraintViolationImpl<T>> constraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
@@ -202,7 +203,7 @@
 		return true;
 	}
 
-	public <T> boolean validateConstraint(Class beanClass, Object value, ExecutionContext<T> executionContext) {
+	public <T> boolean validateConstraint(Class<T> beanClass, Object value, ExecutionContext<T> executionContext) {
 		List<ConstraintViolationImpl<T>> constraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
 		constraintTree.validateConstraints( value, beanClass, executionContext, constraintViolations );
 		if ( constraintViolations.size() > 0 ) {

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorContextImpl.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -8,6 +8,7 @@
 
 /**
  * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
  */
 public class ValidatorContextImpl implements ValidatorContext {
 	private MessageInterpolator messageInterpolator;
@@ -29,6 +30,9 @@
 		traversableResolver( factoryTraversableResolver );
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public ValidatorContext messageInterpolator(MessageInterpolator messageInterpolator) {
 		if ( messageInterpolator == null ) {
 			this.messageInterpolator = factoryMessageInterpolator;
@@ -39,6 +43,9 @@
 		return this;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public ValidatorContext traversableResolver(TraversableResolver traversableResolver) {
 		if ( traversableResolver == null ) {
 			this.traversableResolver = factoryTraversableResolver;
@@ -49,7 +56,12 @@
 		return this;
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public Validator getValidator() {
-		return new ValidatorImpl( constraintValidatorFactory, messageInterpolator, constraintHelper );
+		return new ValidatorImpl(
+				constraintValidatorFactory, messageInterpolator, traversableResolver, constraintHelper
+		);
 	}
 }

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -40,7 +40,6 @@
 		this.messageInterpolator = configurationState.getMessageInterpolator();
 		this.constraintValidatorFactory = configurationState.getConstraintValidatorFactory();
 		this.traversableResolver = configurationState.getTraversableResolver();
-		//do init metadata from XML form
 	}
 
 	/**

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-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -32,6 +32,7 @@
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.ConstraintViolation;
 import javax.validation.MessageInterpolator;
+import javax.validation.TraversableResolver;
 import javax.validation.Validator;
 import javax.validation.groups.Default;
 
@@ -86,11 +87,14 @@
 
 	private final MessageInterpolator messageInterpolator;
 
+	private final TraversableResolver traversableResolver;
+
 	private final ConstraintHelper constraintHelper;
 
-	public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, MessageInterpolator messageInterpolator, ConstraintHelper constraintHelper) {
+	public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, MessageInterpolator messageInterpolator, TraversableResolver traversableResolver, ConstraintHelper constraintHelper) {
 		this.constraintValidatorFactory = constraintValidatorFactory;
 		this.messageInterpolator = messageInterpolator;
+		this.traversableResolver = traversableResolver;
 		this.constraintHelper = constraintHelper;
 
 		groupChainGenerator = new GroupChainGenerator();
@@ -106,7 +110,7 @@
 		GroupChain groupChain = determineGroupExecutionOrder( groups );
 
 		ExecutionContext<T> context = new ExecutionContext<T>(
-				object, messageInterpolator, constraintValidatorFactory
+				object, messageInterpolator, constraintValidatorFactory, traversableResolver
 		);
 
 		List<ConstraintViolationImpl<T>> list = validateInContext( context, groupChain );
@@ -258,9 +262,9 @@
 	 */
 	private <T> boolean validateConstraintsForCurrentGroup(ExecutionContext<T> executionContext, BeanMetaData<T> beanMetaData) {
 		boolean validationSuccessful = true;
-		for ( MetaConstraint<T> metaConstraint : beanMetaData.geMetaConstraintList() ) {
+		for ( MetaConstraint<T, ?> metaConstraint : beanMetaData.geMetaConstraintList() ) {
 			executionContext.pushProperty( metaConstraint.getPropertyName() );
-			if ( executionContext.checkValidationRequired( metaConstraint.getGroupList() ) ) {
+			if ( executionContext.isValidationRequired( metaConstraint ) ) {
 				boolean tmp = metaConstraint.validateConstraint( beanMetaData.getBeanClass(), executionContext );
 				validationSuccessful = validationSuccessful && tmp;
 			}
@@ -355,7 +359,7 @@
 		@SuppressWarnings("unchecked")
 		final Class<T> beanType = ( Class<T> ) object.getClass();
 
-		Set<MetaConstraint<T>> metaConstraints = new HashSet<MetaConstraint<T>>();
+		Set<MetaConstraint<T, ?>> metaConstraints = new HashSet<MetaConstraint<T, ?>>();
 		Object hostingBeanInstance = collectMetaConstraintsForPath( beanType, object, propertyIter, metaConstraints );
 
 		if ( hostingBeanInstance == null ) {
@@ -378,21 +382,21 @@
 		Iterator<List<Group>> sequenceIterator = groupChain.getSequenceIterator();
 		while ( sequenceIterator.hasNext() ) {
 			List<Group> sequence = sequenceIterator.next();
-			int numberOfConstraintViolations = failingConstraintViolations.size();
+			int numberOfConstraintViolationsBefore = failingConstraintViolations.size();
 			for ( Group group : sequence ) {
 				validatePropertyForGroup(
 						object, propertyIter, failingConstraintViolations, metaConstraints, hostingBeanInstance, group
 				);
 
-				if ( failingConstraintViolations.size() > numberOfConstraintViolations ) {
+				if ( failingConstraintViolations.size() > numberOfConstraintViolationsBefore ) {
 					break;
 				}
 			}
 		}
 	}
 
-	private <T> int validatePropertyForGroup(T object, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, Set<MetaConstraint<T>> metaConstraints, Object hostingBeanInstance, Group group) {
-		int numberOfConstraintViolations = failingConstraintViolations.size();
+	private <T> void validatePropertyForGroup(T object, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, Set<MetaConstraint<T, ?>> metaConstraints, Object hostingBeanInstance, Group group) {
+		int numberOfConstraintViolationsBefore = failingConstraintViolations.size();
 		BeanMetaData<T> beanMetaData = getBeanMetaData( metaConstraints.iterator().next().getBeanClass() );
 
 		List<Class<?>> groupList;
@@ -405,26 +409,30 @@
 		}
 
 		for ( Class<?> groupClass : groupList ) {
-			for ( MetaConstraint<T> metaConstraint : metaConstraints ) {
-				if ( metaConstraint.getGroupList().contains( groupClass ) ) {
-					ExecutionContext<T> context = new ExecutionContext<T>(
-							object, hostingBeanInstance, messageInterpolator, constraintValidatorFactory
-					);
-					context.pushProperty( propertyIter.getOriginalProperty() );
-					metaConstraint.validateConstraint( object.getClass(), context );
+			for ( MetaConstraint<T, ?> metaConstraint : metaConstraints ) {
+				ExecutionContext<T> context = new ExecutionContext<T>(
+						object,
+						hostingBeanInstance,
+						messageInterpolator,
+						constraintValidatorFactory,
+						traversableResolver
+				);
+				context.pushProperty( propertyIter.getOriginalProperty() );
+				context.setCurrentGroup( groupClass );
+				if ( context.isValidationRequired( metaConstraint ) ) {
+					metaConstraint.validateConstraint( ( Class<T> ) object.getClass(), context );
 					failingConstraintViolations.addAll( context.getFailingConstraints() );
 				}
 			}
-			if ( failingConstraintViolations.size() > numberOfConstraintViolations ) {
+			if ( failingConstraintViolations.size() > numberOfConstraintViolationsBefore ) {
 				break;
 			}
 		}
-		return numberOfConstraintViolations;
 	}
 
 	@SuppressWarnings("unchecked")
 	private <T> void validateValue(Class<T> beanType, Object value, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, GroupChain groupChain) {
-		Set<MetaConstraint<T>> metaConstraints = new HashSet<MetaConstraint<T>>();
+		Set<MetaConstraint<T, ?>> metaConstraints = new HashSet<MetaConstraint<T, ?>>();
 		collectMetaConstraintsForPath( beanType, null, propertyIter, metaConstraints );
 
 		if ( metaConstraints.size() == 0 ) {
@@ -467,7 +475,7 @@
 		}
 	}
 
-	private <T> void validateValueForGroup(Class<T> beanType, Object value, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, Set<MetaConstraint<T>> metaConstraints, Group group) {
+	private <T> void validateValueForGroup(Class<T> beanType, Object value, PropertyIterator propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations, Set<MetaConstraint<T, ?>> metaConstraints, Group group) {
 		int numberOfConstraintViolations = failingConstraintViolations.size();
 		BeanMetaData<T> beanMetaData = getBeanMetaData( metaConstraints.iterator().next().getBeanClass() );
 
@@ -481,13 +489,15 @@
 		}
 
 		for ( Class<?> groupClass : groupList ) {
-			for ( MetaConstraint<T> metaConstraint : metaConstraints ) {
-				if ( metaConstraint.getGroupList().contains( groupClass ) ) {
-					ExecutionContext<T> context = new ExecutionContext<T>(
-							( T ) value, messageInterpolator, constraintValidatorFactory
-					);
-					context.pushProperty( propertyIter.getOriginalProperty() );
-					metaConstraint.validateConstraint( beanType.getClass(), value, context );
+			for ( MetaConstraint<T, ?> metaConstraint : metaConstraints ) {
+				ExecutionContext<T> context = new ExecutionContext<T>(
+						( T ) value, messageInterpolator, constraintValidatorFactory, traversableResolver
+				);
+				context.pushProperty( propertyIter.getOriginalProperty() );
+				context.setCurrentGroup( groupClass );
+
+				if ( context.isValidationRequired( metaConstraint ) ) {
+					metaConstraint.validateConstraint( beanType, value, context );
 					failingConstraintViolations.addAll( context.getFailingConstraints() );
 				}
 			}
@@ -511,7 +521,7 @@
 	 * @return Returns the bean hosting the constraints which match the specified property path.
 	 */
 	@SuppressWarnings("unchecked")
-	private <T> Object collectMetaConstraintsForPath(Class<T> clazz, Object value, PropertyIterator propertyIter, Set<MetaConstraint<T>> metaConstraints) {
+	private <T> Object collectMetaConstraintsForPath(Class<T> clazz, Object value, PropertyIterator propertyIter, Set<MetaConstraint<T, ?>> metaConstraints) {
 		propertyIter.split();
 
 		if ( !propertyIter.hasNext() ) {
@@ -519,8 +529,8 @@
 				throw new IllegalArgumentException( "Invalid property path." );
 			}
 
-			List<MetaConstraint<T>> metaConstraintList = getBeanMetaData( clazz ).geMetaConstraintList();
-			for ( MetaConstraint<T> metaConstraint : metaConstraintList ) {
+			List<MetaConstraint<T, ?>> metaConstraintList = getBeanMetaData( clazz ).geMetaConstraintList();
+			for ( MetaConstraint<T, ?> metaConstraint : metaConstraintList ) {
 				if ( metaConstraint.getPropertyName().equals( propertyIter.getHead() ) ) {
 					metaConstraints.add( metaConstraint );
 				}

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -46,7 +46,7 @@
 	 *         key is the type the validator accepts and value the validator class itself.
 	 */
 	public static <T extends Annotation> Map<Class<?>, Class<? extends ConstraintValidator<?, ?>>> getValidatorsTypes(
-				List<Class<? extends ConstraintValidator<T, ?>>> validators) {
+			List<Class<? extends ConstraintValidator<T, ?>>> validators) {
 		if ( validators == null || validators.size() == 0 ) {
 			throw new ValidationException( "No ConstraintValidators associated to @Constraint" );
 		}

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java	2009-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -17,6 +17,7 @@
 */
 package org.hibernate.validation.bootstrap;
 
+import java.lang.annotation.ElementType;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -28,6 +29,7 @@
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.ConstraintViolation;
 import javax.validation.MessageInterpolator;
+import javax.validation.TraversableResolver;
 import javax.validation.Validation;
 import javax.validation.ValidationException;
 import javax.validation.ValidationProviderResolver;
@@ -42,12 +44,12 @@
 import static org.junit.Assert.fail;
 import org.junit.Test;
 
-import org.hibernate.validation.engine.HibernateValidatorConfiguration;
 import org.hibernate.validation.HibernateValidationProvider;
 import org.hibernate.validation.constraints.NotNullValidator;
 import org.hibernate.validation.eg.Customer;
 import org.hibernate.validation.engine.ConfigurationImpl;
 import org.hibernate.validation.engine.ConstraintValidatorFactoryImpl;
+import org.hibernate.validation.engine.HibernateValidatorConfiguration;
 import org.hibernate.validation.engine.ValidatorFactoryImpl;
 
 /**
@@ -91,7 +93,6 @@
 		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
 	}
 
-
 	@Test
 	public void testCustomMessageInterpolator() {
 
@@ -100,7 +101,7 @@
 		assertDefaultBuilderAndFactory( configuration );
 
 		ValidatorFactory factory = configuration.buildValidatorFactory();
-		Validator validator = factory.getValidator( );
+		Validator validator = factory.getValidator();
 
 		Customer customer = new Customer();
 		customer.setFirstName( "John" );
@@ -124,7 +125,7 @@
 				}
 		);
 		factory = configuration.buildValidatorFactory();
-		validator = factory.getValidator( );
+		validator = factory.getValidator();
 		constraintViolations = validator.validate( customer );
 		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
 		constraintViolation = constraintViolations.iterator().next();
@@ -138,7 +139,7 @@
 		assertDefaultBuilderAndFactory( configuration );
 
 		ValidatorFactory factory = configuration.buildValidatorFactory();
-		Validator validator = factory.getValidator(  );
+		Validator validator = factory.getValidator();
 
 		Customer customer = new Customer();
 		customer.setFirstName( "John" );
@@ -162,7 +163,7 @@
 				}
 		);
 		factory = configuration.buildValidatorFactory();
-		validator = factory.getValidator( );
+		validator = factory.getValidator();
 		constraintViolations = validator.validate( customer );
 		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
 	}
@@ -180,9 +181,9 @@
 
 
 		HibernateValidatorConfiguration configuration = Validation
-					.byProvider( HibernateValidatorConfiguration.class )
-					.providerResolver( resolver )
-					.configure();
+				.byProvider( HibernateValidatorConfiguration.class )
+				.providerResolver( resolver )
+				.configure();
 		assertDefaultBuilderAndFactory( configuration );
 	}
 
@@ -199,9 +200,9 @@
 
 
 		Configuration<?> configuration = Validation
-			        .byDefaultProvider()
-					.providerResolver( resolver )
-					.configure();
+				.byDefaultProvider()
+				.providerResolver( resolver )
+				.configure();
 		assertDefaultBuilderAndFactory( configuration );
 	}
 
@@ -216,7 +217,7 @@
 
 		final ProviderSpecificBootstrap<HibernateValidatorConfiguration> providerSpecificBootstrap =
 				Validation
-						.byProvider( HibernateValidatorConfiguration.class)
+						.byProvider( HibernateValidatorConfiguration.class )
 						.providerResolver( resolver );
 
 		try {
@@ -237,7 +238,7 @@
 		assertTrue( configuration instanceof ConfigurationImpl );
 
 		ValidatorFactory factory = configuration.buildValidatorFactory();
-		assertDefaultFactory(factory);
+		assertDefaultFactory( factory );
 	}
 
 	private void assertDefaultFactory(ValidatorFactory factory) {
@@ -251,4 +252,36 @@
 			return true;
 		}
 	}
+
+	@Test
+	public void testCustomTraversableResolver() {
+
+		Configuration<?> configuration = Validation.byDefaultProvider().configure();
+		assertDefaultBuilderAndFactory( configuration );
+
+		ValidatorFactory factory = configuration.buildValidatorFactory();
+		Validator validator = factory.getValidator();
+
+		Customer customer = new Customer();
+		customer.setFirstName( "John" );
+
+		Set<ConstraintViolation<Customer>> constraintViolations = validator.validate( customer );
+		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+		ConstraintViolation<Customer> constraintViolation = constraintViolations.iterator().next();
+		assertEquals( "Wrong message", "may not be null", constraintViolation.getMessage() );
+
+		// get a new factory using a custom configuration
+		configuration = Validation.byDefaultProvider().configure();
+		configuration.traversableResolver(
+				new TraversableResolver() {
+					public boolean isTraversable(Object o, String s, Class<?> aClass, String s1, ElementType elementType) {
+						return false;
+					}
+				}
+		);
+		factory = configuration.buildValidatorFactory();
+		validator = factory.getValidator();
+		constraintViolations = validator.validate( customer );
+		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
+	}
 }

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-02-27 14:13:29 UTC (rev 16048)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java	2009-02-27 17:04:57 UTC (rev 16049)
@@ -455,7 +455,7 @@
 		);
 	}
 
-	@org.junit.Test
+	@Test
 	public void testObjectTraversion() {
 		Validator validator = TestUtil.getValidator();
 




More information about the hibernate-commits mailing list