[hibernate-commits] Hibernate SVN: r16960 - validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Jun 29 07:48:30 EDT 2009


Author: hardy.ferentschik
Date: 2009-06-29 07:48:29 -0400 (Mon, 29 Jun 2009)
New Revision: 16960

Modified:
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/B3.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/GroupSequenceIsolationTest.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/SafeEncryption.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/LocalExecutionContext.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/metadata/BeanDescriptorImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaData.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaDataImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/MetaConstraint.java
Log:
HV-164 - Made sure that the default group sequence applies when a super class gets validated where @GroupSequence is used, but not on the subclass.


Modified: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/B3.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/B3.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/B3.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -27,5 +27,5 @@
 	String encryptionKey;
 
 	@Size(max = 20)
-	String nickname; //B1 group
+	String nickname; 
 }
\ No newline at end of file

Modified: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/GroupSequenceIsolationTest.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/GroupSequenceIsolationTest.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/GroupSequenceIsolationTest.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -110,7 +110,7 @@
 		assertCorrectNumberOfViolations( violations, 0 );
 	}
 
-	@Test(enabled = false)
+	@Test
 	public void testCorrectDefaultSequenceInheritance3() {
 		Validator validator = TestUtil.getDefaultValidator();
 		B3 b = new B3();
@@ -120,8 +120,9 @@
 		b.encryptionKey = "not safe";
 
 		Set<ConstraintViolation<B3>> violations = validator.validate( b );
-		assertCorrectNumberOfViolations( violations, 1 );
-		assertCorrectConstraintTypes( violations, Max.class );
+		assertCorrectNumberOfViolations( violations, 2 );
+		assertCorrectConstraintTypes( violations, Max.class, Size.class );
+		assertCorrectPropertyPaths( violations, "size", "nickname" );
 	}
 
 	@Test
@@ -192,6 +193,5 @@
 		e.name = "Johnatan";
 		violations = validator.validate( e );
 		assertCorrectNumberOfViolations( violations, 0 );
-
 	}
 }
\ No newline at end of file

Modified: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/SafeEncryption.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/SafeEncryption.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/groups/groupsequenceisolation/SafeEncryption.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -36,7 +36,7 @@
 @Retention(RUNTIME)
 @Documented
 public @interface SafeEncryption {
-	public abstract String message() default "encryption faild";
+	public abstract String message() default "encryption failed";
 
 	public abstract Class<?>[] groups() default { };
 

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/LocalExecutionContext.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/LocalExecutionContext.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/LocalExecutionContext.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
 /*
 * JBoss, Home of Professional Open Source
 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
@@ -17,12 +17,14 @@
 */
 package org.hibernate.validation.engine;
 
+import javax.validation.groups.Default;
+
 /**
  * An instance of this class is used to collect all the relevant information for validating a single entity/bean.
  *
  * @author Hardy Ferentschik
  */
-public class LocalExecutionContext<T,V> {
+public class LocalExecutionContext<T, V> {
 
 	/**
 	 * The current bean which gets validated. This is the bean hosting the constraints which get validated.
@@ -49,14 +51,14 @@
 	 */
 	private V currentValue;
 
-	public static <T,V> LocalExecutionContext<T,V> getLocalExecutionContext(T value) {
+	public static <T, V> LocalExecutionContext<T, V> getLocalExecutionContext(T value) {
 		@SuppressWarnings("unchecked")
 		Class<T> rootBeanClass = ( Class<T> ) value.getClass();
-		return new LocalExecutionContext<T,V>( value, rootBeanClass );
+		return new LocalExecutionContext<T, V>( value, rootBeanClass );
 	}
 
-	public static <T,V> LocalExecutionContext<T,V> getLocalExecutionContext(Class<T> type) {
-		return new LocalExecutionContext<T,V>( null, type );
+	public static <T, V> LocalExecutionContext<T, V> getLocalExecutionContext(Class<T> type) {
+		return new LocalExecutionContext<T, V>( null, type );
 	}
 
 	public LocalExecutionContext(T currentBean, Class<T> currentBeanType) {
@@ -100,6 +102,10 @@
 		propertyPath.getLeafNode().setInIterable( true );
 	}
 
+	public boolean validatingDefault() {
+		return getCurrentGroup() != null && getCurrentGroup().getName().equals( Default.class.getName() );
+	}
+
 	@Override
 	public String toString() {
 		return "LocalExecutionContext{" +

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-06-26 15:56:27 UTC (rev 16959)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -24,18 +24,18 @@
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.MessageInterpolator;
 import javax.validation.TraversableResolver;
+import javax.validation.ValidationException;
 import javax.validation.Validator;
 import javax.validation.ValidatorContext;
 import javax.validation.ValidatorFactory;
-import javax.validation.ValidationException;
 import javax.validation.spi.ConfigurationState;
 
 import org.hibernate.validation.metadata.AnnotationIgnores;
-import org.hibernate.validation.xml.XmlMappingParser;
+import org.hibernate.validation.metadata.BeanMetaDataCache;
 import org.hibernate.validation.metadata.BeanMetaDataImpl;
-import org.hibernate.validation.metadata.BeanMetaDataCache;
+import org.hibernate.validation.metadata.ConstraintHelper;
 import org.hibernate.validation.metadata.MetaConstraint;
-import org.hibernate.validation.metadata.ConstraintHelper;
+import org.hibernate.validation.xml.XmlMappingParser;
 
 /**
  * Factory returning initialized <code>Validator</code> instances.
@@ -70,7 +70,7 @@
 	}
 
 	public <T> T unwrap(Class<T> type) {
-		throw new ValidationException( "Type " + type + " not supported");
+		throw new ValidationException( "Type " + type + " not supported" );
 	}
 
 	public ValidatorContext usingContext() {
@@ -89,13 +89,14 @@
 		mappingParser.parse( mappingStreams );
 
 		AnnotationIgnores annotationIgnores = mappingParser.getAnnotationIgnores();
-		for ( Class<?> beanClass : mappingParser.getProcessedClasses() ) {
+		for ( Class<?> clazz : mappingParser.getProcessedClasses() ) {
+			Class<T> beanClass = ( Class<T> ) clazz;
 			BeanMetaDataImpl<T> metaData = new BeanMetaDataImpl<T>(
-					( Class<T> ) beanClass, constraintHelper, annotationIgnores
+					beanClass, constraintHelper, annotationIgnores
 			);
 
-			for ( MetaConstraint<T, ? extends Annotation> constraint : mappingParser.getConstraintsForClass( ( Class<T> ) beanClass ) ) {
-				metaData.addMetaConstraint( constraint );
+			for ( MetaConstraint<T, ? extends Annotation> constraint : mappingParser.getConstraintsForClass( beanClass ) ) {
+				metaData.addMetaConstraint( beanClass, constraint );
 			}
 
 			for ( Member m : mappingParser.getCascadedMembersForClass( beanClass ) ) {
@@ -105,7 +106,7 @@
 			if ( !mappingParser.getDefaultSequenceForClass( beanClass ).isEmpty() ) {
 				metaData.setDefaultGroupSequence( mappingParser.getDefaultSequenceForClass( beanClass ) );
 			}
-			beanMetaDataCache.addBeanMetaData( ( Class<T> ) beanClass, ( BeanMetaDataImpl<T> ) metaData );
+			beanMetaDataCache.addBeanMetaData( beanClass, metaData );
 		}
 	}
 }

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-06-26 15:56:27 UTC (rev 16959)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -41,7 +41,6 @@
 import javax.validation.metadata.BeanDescriptor;
 
 import com.googlecode.jtype.TypeUtils;
-import org.slf4j.Logger;
 
 import org.hibernate.validation.engine.groups.Group;
 import org.hibernate.validation.engine.groups.GroupChain;
@@ -52,7 +51,6 @@
 import org.hibernate.validation.metadata.BeanMetaDataImpl;
 import org.hibernate.validation.metadata.ConstraintHelper;
 import org.hibernate.validation.metadata.MetaConstraint;
-import org.hibernate.validation.util.LoggerFactory;
 import org.hibernate.validation.util.ReflectionHelper;
 
 /**
@@ -62,7 +60,6 @@
  * @author Hardy Ferentschik
  */
 public class ValidatorImpl implements Validator {
-	private static final Logger log = LoggerFactory.make();
 
 	/**
 	 * The default group array used in case any of the validate methods is called without a group.
@@ -215,7 +212,7 @@
 		while ( groupIterator.hasNext() ) {
 			Group group = groupIterator.next();
 			localExecutionContext.setCurrentGroup( group.getGroup() );
-			validateConstraints( context, localExecutionContext, path );
+			validateConstraintsForCurrentGroup( context, localExecutionContext, path );
 		}
 		groupIterator = groupChain.getGroupIterator();
 		while ( groupIterator.hasNext() ) {
@@ -232,7 +229,7 @@
 				int numberOfViolations = context.getFailingConstraints().size();
 				localExecutionContext.setCurrentGroup( group.getGroup() );
 
-				validateConstraints( context, localExecutionContext, path );
+				validateConstraintsForCurrentGroup( context, localExecutionContext, path );
 				validateCascadedConstraints( context, localExecutionContext, path );
 
 				if ( context.getFailingConstraints().size() > numberOfViolations ) {
@@ -243,60 +240,99 @@
 		return context.getFailingConstraints();
 	}
 
-	/**
-	 * Validates non cascaded constraints
-	 *
-	 * @param executionContext The global execution context
-	 * @param localExecutionContext Collected information for single validation
-	 * @param path The current path of the validation
-	 * @param <T> The type of the root bean
-	 */
-	private <T, U, V> void validateConstraints(GlobalExecutionContext<T> executionContext, LocalExecutionContext<U, V> localExecutionContext, PathImpl path) {
+	private <T, U, V> void validateConstraintsForCurrentGroup(GlobalExecutionContext<T> globalExecutionContext, LocalExecutionContext<U, V> localExecutionContext, PathImpl path) {
 		BeanMetaData<U> beanMetaData = getBeanMetaData( localExecutionContext.getCurrentBeanType() );
-		if ( localExecutionContext.getCurrentGroup().getName().equals( Default.class.getName() ) ) {
-			List<Class<?>> defaultGroupSequence = beanMetaData.getDefaultGroupSequence();
-			if ( log.isTraceEnabled() && defaultGroupSequence.size() > 0 && defaultGroupSequence.get( 0 ) != Default.class ) {
-				log.trace(
-						"Executing re-defined Default group for bean {} as sequence {}",
-						beanMetaData.getBeanClass().getName(),
-						defaultGroupSequence
-				);
-			}
+		boolean validatingDefault = localExecutionContext.validatingDefault();
+		boolean validatedBeanRedefinesDefault = beanMetaData.defaultGroupSequenceIsRedefined();
+
+		// if we are not validating the default group there is nothing slecial to consider
+		if ( !validatingDefault ) {
+			validateConstraintsForNonDefaultGroup( globalExecutionContext, localExecutionContext, path );
+			return;
+		}
+
+		// if we are validating the default group we have to distinguish between the case where the main entity type redefines the default group and
+		// where not
+		if ( validatedBeanRedefinesDefault ) {
+			validateConstraintsForRedefinedDefaultGroupOnMainEntity(
+					globalExecutionContext, localExecutionContext, path, beanMetaData
+			);
+		}
+		else {
+			validateConstraintsForRedefinedDefaultGroup(
+					globalExecutionContext, localExecutionContext, path, beanMetaData
+			);
+		}
+	}
+
+	private <T, U, V> void validateConstraintsForRedefinedDefaultGroup(GlobalExecutionContext<T> globalExecutionContext, LocalExecutionContext<U, V> localExecutionContext, PathImpl path, BeanMetaData<U> beanMetaData) {
+		// in the case where the main entity does not redefine the default group we have to check whether the entity which defines the constraint does
+		for ( Map.Entry<Class<?>, List<MetaConstraint<U, ? extends Annotation>>> entry : beanMetaData.geMetaConstraintsAsMap()
+				.entrySet() ) {
+			Class<?> hostingBeanClass = entry.getKey();
+			List<MetaConstraint<U, ? extends Annotation>> constraints = entry.getValue();
+
+			List<Class<?>> defaultGroupSequence = getBeanMetaData( hostingBeanClass ).getDefaultGroupSequence();
 			for ( Class<?> defaultSequenceMember : defaultGroupSequence ) {
 				localExecutionContext.setCurrentGroup( defaultSequenceMember );
-				boolean validationSuccessful = validateConstraintsForCurrentGroup(
-						executionContext, localExecutionContext, beanMetaData, path
-				);
+				boolean validationSuccessful = true;
+				for ( MetaConstraint<U, ? extends Annotation> metaConstraint : constraints ) {
+					boolean tmp = validateConstraint(
+							globalExecutionContext, localExecutionContext, metaConstraint, path
+					);
+					validationSuccessful = validationSuccessful && tmp;
+				}
 				if ( !validationSuccessful ) {
 					break;
 				}
 			}
 		}
-		else {
-			validateConstraintsForCurrentGroup( executionContext, localExecutionContext, beanMetaData, path );
-		}
 	}
 
-	private <T, U, V> boolean validateConstraintsForCurrentGroup(GlobalExecutionContext<T> globalExecutionContext, LocalExecutionContext<U, V> localExecutionContext, BeanMetaData<U> beanMetaData, PathImpl path) {
-		boolean validationSuccessful = true;
-		for ( MetaConstraint<U, ?> metaConstraint : beanMetaData.geMetaConstraintList() ) {
-			PathImpl newPath = PathImpl.createShallowCopy( path );
-			if ( !"".equals( metaConstraint.getPropertyName() ) ) {
-				newPath.addNode( new NodeImpl( metaConstraint.getPropertyName() ) );
-			}
-			localExecutionContext.setPropertyPath( newPath );
-			if ( isValidationRequired( globalExecutionContext, localExecutionContext, metaConstraint ) ) {
-				Object valueToValidate = metaConstraint.getValue( localExecutionContext.getCurrentBean() );
-				localExecutionContext.setCurrentValidatedValue( ( V ) valueToValidate );
-				boolean tmp = metaConstraint.validateConstraint( globalExecutionContext, localExecutionContext );
+	private <T, U, V> void validateConstraintsForRedefinedDefaultGroupOnMainEntity(GlobalExecutionContext<T> globalExecutionContext, LocalExecutionContext<U, V> localExecutionContext, PathImpl path, BeanMetaData<U> beanMetaData) {
+		// in the case where the main entity redefines the default group we can interate over all constraints independend of the bean they are
+		// defined in. The redefined group sequence applies for all constraints.
+		List<Class<?>> defaultGroupSequence = beanMetaData.getDefaultGroupSequence();
+		for ( Class<?> defaultSequenceMember : defaultGroupSequence ) {
+			localExecutionContext.setCurrentGroup( defaultSequenceMember );
+			boolean validationSuccessful = true;
+			for ( MetaConstraint<U, ? extends Annotation> metaConstraint : beanMetaData.geMetaConstraintsAsList() ) {
+				boolean tmp = validateConstraint(
+						globalExecutionContext, localExecutionContext, metaConstraint, path
+				);
 				validationSuccessful = validationSuccessful && tmp;
 			}
-			globalExecutionContext.markProcessed(
-					localExecutionContext.getCurrentBean(),
-					localExecutionContext.getCurrentGroup(),
-					localExecutionContext.getPropertyPath()
-			);
+			if ( !validationSuccessful ) {
+				break;
+			}
 		}
+	}
+
+	private <T, U, V> void validateConstraintsForNonDefaultGroup(GlobalExecutionContext<T> globalExecutionContext, LocalExecutionContext<U, V> localExecutionContext, PathImpl path) {
+		BeanMetaData<U> beanMetaData = getBeanMetaData( localExecutionContext.getCurrentBeanType() );
+		for ( MetaConstraint<U, ? extends Annotation> metaConstraint : beanMetaData.geMetaConstraintsAsList() ) {
+			validateConstraint( globalExecutionContext, localExecutionContext, metaConstraint, path );
+		}
+	}
+
+	private <T, U, V> boolean validateConstraint(GlobalExecutionContext<T> globalExecutionContext, LocalExecutionContext<U, V> localExecutionContext, MetaConstraint<U, ?> metaConstraint, PathImpl path) {
+		boolean validationSuccessful = true;
+		PathImpl newPath = PathImpl.createShallowCopy( path );
+		if ( !"".equals( metaConstraint.getPropertyName() ) ) {
+			newPath.addNode( new NodeImpl( metaConstraint.getPropertyName() ) );
+		}
+		localExecutionContext.setPropertyPath( newPath );
+		if ( isValidationRequired( globalExecutionContext, localExecutionContext, metaConstraint ) ) {
+			Object valueToValidate = metaConstraint.getValue( localExecutionContext.getCurrentBean() );
+			localExecutionContext.setCurrentValidatedValue( ( V ) valueToValidate );
+			validationSuccessful = metaConstraint.validateConstraint( globalExecutionContext, localExecutionContext );
+		}
+		globalExecutionContext.markProcessed(
+				localExecutionContext.getCurrentBean(),
+				localExecutionContext.getCurrentGroup(),
+				localExecutionContext.getPropertyPath()
+		);
+
 		return validationSuccessful;
 	}
 
@@ -647,7 +683,7 @@
 				);
 			}
 
-			List<MetaConstraint<T, ? extends Annotation>> metaConstraintList = metaData.geMetaConstraintList();
+			List<MetaConstraint<T, ? extends Annotation>> metaConstraintList = metaData.geMetaConstraintsAsList();
 			for ( MetaConstraint<T, ?> metaConstraint : metaConstraintList ) {
 				if ( metaConstraint.getPropertyName().equals( elem.getName() ) ) {
 					metaConstraints.add( metaConstraint );
@@ -685,10 +721,10 @@
 		return value;
 	}
 
-	private <T> BeanMetaData<T> getBeanMetaData(Class<T> beanClass) {
-		BeanMetaDataImpl<T> metadata = beanMetaDataCache.getBeanMetaData( beanClass );
+	private <U> BeanMetaData<U> getBeanMetaData(Class<U> beanClass) {
+		BeanMetaDataImpl<U> metadata = beanMetaDataCache.getBeanMetaData( beanClass );
 		if ( metadata == null ) {
-			metadata = new BeanMetaDataImpl<T>( beanClass, constraintHelper );
+			metadata = new BeanMetaDataImpl<U>( beanClass, constraintHelper );
 			beanMetaDataCache.addBeanMetaData( beanClass, metadata );
 		}
 		return metadata;

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanDescriptorImpl.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanDescriptorImpl.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -17,7 +17,7 @@
 	}
 
 	public boolean isBeanConstrained() {
-		return metadataBean.geMetaConstraintList().size() > 0;
+		return metadataBean.geMetaConstraintsAsMap().size() > 0;
 	}
 
 	public PropertyDescriptor getConstraintsForProperty(String propertyName) {

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaData.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaData.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaData.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -20,6 +20,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Member;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import javax.validation.metadata.BeanDescriptor;
 import javax.validation.metadata.PropertyDescriptor;
@@ -57,10 +58,16 @@
 	boolean defaultGroupSequenceIsRedefined();
 
 	/**
+	 * @return A map of {@code MetaConstraint} instances encapsulating the information of all the constraints
+	 *         defined on the bean mapped to the class in which the constraints is defined.
+	 */
+	Map<Class<?>, List<MetaConstraint<T, ? extends Annotation>>> geMetaConstraintsAsMap();
+
+	/**
 	 * @return A list of {@code MetaConstraint} instances encapsulating the information of all the constraints
 	 *         defined on the bean.
 	 */
-	List<MetaConstraint<T, ? extends Annotation>> geMetaConstraintList();
+	List<MetaConstraint<T, ? extends Annotation>> geMetaConstraintsAsList();
 
 	/**
 	 * Return {@code PropertyDescriptor} for the given property.

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaDataImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaDataImpl.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/BeanMetaDataImpl.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -66,9 +66,10 @@
 	private BeanDescriptorImpl<T> beanDescriptor;
 
 	/**
-	 * List of constraints.
+	 * Map of all direct constraints which belong to the entity {@code beanClass}. The constraints are mapped to the class
+	 * (eg super class or interface) in which they are defined.
 	 */
-	private List<MetaConstraint<T, ? extends Annotation>> metaConstraintList = new ArrayList<MetaConstraint<T, ? extends Annotation>>();
+	private Map<Class<?>, List<MetaConstraint<T, ? extends Annotation>>> metaConstraints = new HashMap<Class<?>, List<MetaConstraint<T, ? extends Annotation>>>();
 
 	/**
 	 * List of cascaded members.
@@ -117,14 +118,30 @@
 		return Collections.unmodifiableList( cascadedMembers );
 	}
 
-	public List<MetaConstraint<T, ? extends Annotation>> geMetaConstraintList() {
-		return Collections.unmodifiableList( metaConstraintList );
+	public Map<Class<?>, List<MetaConstraint<T, ? extends Annotation>>> geMetaConstraintsAsMap() {
+		return Collections.unmodifiableMap( metaConstraints );
 	}
 
-	public void addMetaConstraint(MetaConstraint<T, ? extends Annotation> metaConstraint) {
-		metaConstraintList.add( metaConstraint );
+	public List<MetaConstraint<T, ? extends Annotation>> geMetaConstraintsAsList() {
+		List<MetaConstraint<T, ? extends Annotation>> constraintList = new ArrayList<MetaConstraint<T, ? extends Annotation>>();
+		for ( List<MetaConstraint<T, ? extends Annotation>> list : metaConstraints.values() ) {
+			constraintList.addAll( list );
+		}
+		return Collections.unmodifiableList( constraintList );
 	}
 
+	public void addMetaConstraint(Class<?> clazz, MetaConstraint<T, ? extends Annotation> metaConstraint) {
+		List<MetaConstraint<T, ? extends Annotation>> constraintList;
+		if ( !metaConstraints.containsKey( clazz ) ) {
+			constraintList = new ArrayList<MetaConstraint<T, ? extends Annotation>>();
+			metaConstraints.put( clazz, constraintList );
+		}
+		else {
+			constraintList = metaConstraints.get( clazz );
+		}
+		constraintList.add( metaConstraint );
+	}
+
 	public void addCascadedMember(Member member) {
 		cascadedMembers.add( member );
 	}
@@ -231,7 +248,7 @@
 		setDefaultGroupSequence( groupSequence );
 	}
 
-	private void initFieldConstraints(Class clazz, AnnotationIgnores annotationIgnores) {
+	private void initFieldConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores) {
 		for ( Field field : clazz.getDeclaredFields() ) {
 			List<ConstraintDescriptorImpl<?>> fieldMetadata = findConstraints( field );
 			for ( ConstraintDescriptorImpl<?> constraintDescription : fieldMetadata ) {
@@ -240,7 +257,7 @@
 				}
 				ReflectionHelper.setAccessibility( field );
 				MetaConstraint<T, ?> metaConstraint = createMetaConstraint( field, constraintDescription );
-				metaConstraintList.add( metaConstraint );
+				addMetaConstraint( clazz, metaConstraint );
 			}
 			if ( field.isAnnotationPresent( Valid.class ) ) {
 				ReflectionHelper.setAccessibility( field );
@@ -250,7 +267,7 @@
 		}
 	}
 
-	private void initMethodConstraints(Class clazz, AnnotationIgnores annotationIgnores) {
+	private void initMethodConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores) {
 		for ( Method method : clazz.getDeclaredMethods() ) {
 			List<ConstraintDescriptorImpl<?>> methodMetadata = findConstraints( method );
 			for ( ConstraintDescriptorImpl<?> constraintDescription : methodMetadata ) {
@@ -259,7 +276,7 @@
 				}
 				ReflectionHelper.setAccessibility( method );
 				MetaConstraint<T, ?> metaConstraint = createMetaConstraint( method, constraintDescription );
-				metaConstraintList.add( metaConstraint );
+				addMetaConstraint( clazz, metaConstraint );
 			}
 			if ( method.isAnnotationPresent( Valid.class ) ) {
 				ReflectionHelper.setAccessibility( method );
@@ -292,7 +309,7 @@
 		List<ConstraintDescriptorImpl<?>> classMetadata = findClassLevelConstraints( clazz );
 		for ( ConstraintDescriptorImpl<?> constraintDescription : classMetadata ) {
 			MetaConstraint<T, ?> metaConstraint = createMetaConstraint( constraintDescription );
-			metaConstraintList.add( metaConstraint );
+			addMetaConstraint( clazz, metaConstraint );
 		}
 	}
 
@@ -402,7 +419,7 @@
 		sb.append( "BeanMetaDataImpl" );
 		sb.append( "{beanClass=" ).append( beanClass );
 		sb.append( ", beanDescriptor=" ).append( beanDescriptor );
-		sb.append( ", metaConstraintList=" ).append( metaConstraintList );
+		sb.append( ", metaConstraints=" ).append( metaConstraints );
 		sb.append( ", cascadedMembers=" ).append( cascadedMembers );
 		sb.append( ", propertyDescriptors=" ).append( propertyDescriptors );
 		sb.append( ", defaultGroupSequence=" ).append( defaultGroupSequence );

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/MetaConstraint.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/MetaConstraint.java	2009-06-26 15:56:27 UTC (rev 16959)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/metadata/MetaConstraint.java	2009-06-29 11:48:29 UTC (rev 16960)
@@ -35,7 +35,7 @@
 import org.hibernate.validation.util.ReflectionHelper;
 
 /**
- * Instances of this class abstract the constraint type  (class, method or field constraint) and gives access to
+ * Instances of this class abstract the constraint type  (class, method or field constraint) and give access to
  * meta data about the constraint. This allows a unified handling of constraints in the validator imlpementation.
  *
  * @author Hardy Ferentschik
@@ -171,11 +171,9 @@
 	public String toString() {
 		final StringBuilder sb = new StringBuilder();
 		sb.append( "MetaConstraint" );
-		sb.append( "{member=" ).append( member );
-		sb.append( ", propertyName='" ).append( propertyName ).append( '\'' );
+		sb.append( "{propertyName='" ).append( propertyName ).append( '\'' );
 		sb.append( ", elementType=" ).append( elementType );
 		sb.append( ", beanClass=" ).append( beanClass );
-		sb.append( ", constraintTree=" ).append( constraintTree );
 		sb.append( '}' );
 		return sb.toString();
 	}




More information about the hibernate-commits mailing list