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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Sat Mar 7 12:57:46 EST 2009


Author: hardy.ferentschik
Date: 2009-03-07 12:57:46 -0500 (Sat, 07 Mar 2009)
New Revision: 16106

Added:
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Auditable.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Order.java
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/ConstraintDescriptorImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/GroupTest.java
Log:
HV-115 Implicit grouping

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-03-07 08:33:16 UTC (rev 16105)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java	2009-03-07 17:57:46 UTC (rev 16106)
@@ -176,7 +176,7 @@
 
 	private <A extends Annotation> void initFieldConstraints(Class clazz) {
 		for ( Field field : clazz.getDeclaredFields() ) {
-			List<ConstraintDescriptorImpl> fieldMetadata = findFieldLevelConstraints( field );
+			List<ConstraintDescriptorImpl> fieldMetadata = findConstraints( field );
 			for ( ConstraintDescriptorImpl constraintDescription : fieldMetadata ) {
 				ReflectionHelper.setAccessibility( field );
 				MetaConstraint<T, A> metaConstraint = new MetaConstraint<T, A>(
@@ -186,7 +186,6 @@
 			}
 			if ( field.isAnnotationPresent( Valid.class ) ) {
 				ReflectionHelper.setAccessibility( field );
-				String name = field.getName();
 				cascadedFields.add( field );
 				addPropertyDescriptorForMember( field );
 			}
@@ -195,7 +194,7 @@
 
 	private <A extends Annotation> void initMethodConstraints(Class clazz) {
 		for ( Method method : clazz.getDeclaredMethods() ) {
-			List<ConstraintDescriptorImpl> methodMetadata = findMethodLevelConstraints( method );
+			List<ConstraintDescriptorImpl> methodMetadata = findConstraints( method );
 			for ( ConstraintDescriptorImpl constraintDescription : methodMetadata ) {
 				ReflectionHelper.setAccessibility( method );
 				MetaConstraint<T, A> metaConstraint = new MetaConstraint<T, A>(
@@ -238,12 +237,13 @@
 	/**
 	 * Examines the given annotation to see whether it is a single or multi valued constraint annotation.
 	 *
+	 * @param clazz the class we are currently processing.
 	 * @param annotation The annotation to examine.
 	 *
 	 * @return A list of constraint descriptors or the empty list in case <code>annotation</code> is neither a
 	 *         single nor multi value annotation.
 	 */
-	private <A extends Annotation> List<ConstraintDescriptorImpl> findConstraintAnnotations(A annotation) {
+	private <A extends Annotation> List<ConstraintDescriptorImpl> findConstraintAnnotations(Class<?> clazz, A annotation) {
 		List<ConstraintDescriptorImpl> constraintDescriptors = new ArrayList<ConstraintDescriptorImpl>();
 
 		List<Annotation> constraints = new ArrayList<Annotation>();
@@ -256,16 +256,23 @@
 		constraints.addAll( constraintHelper.getMultiValueConstraints( annotation ) );
 
 		for ( Annotation constraint : constraints ) {
-			final ConstraintDescriptorImpl constraintDescriptor = buildConstraintDescriptor( constraint );
+			final ConstraintDescriptorImpl constraintDescriptor = buildConstraintDescriptor( clazz, constraint );
 			constraintDescriptors.add( constraintDescriptor );
 		}
 		return constraintDescriptors;
 	}
 
 	@SuppressWarnings("unchecked")
-	private <A extends Annotation> ConstraintDescriptorImpl buildConstraintDescriptor(A annotation) {
+	private <A extends Annotation> ConstraintDescriptorImpl buildConstraintDescriptor(Class<?> clazz, A annotation) {
 		Class<?>[] groups = ReflectionHelper.getAnnotationParameter( annotation, "groups", Class[].class );
-		return new ConstraintDescriptorImpl( annotation, groups, constraintHelper );
+		ConstraintDescriptorImpl constraintDescriptor;
+		if ( clazz.isInterface() ) {
+			constraintDescriptor = new ConstraintDescriptorImpl( annotation, groups, constraintHelper, clazz );
+		}
+		else {
+			constraintDescriptor = new ConstraintDescriptorImpl( annotation, groups, constraintHelper );
+		}
+		return constraintDescriptor;
 	}
 
 	/**
@@ -276,10 +283,10 @@
 	 *
 	 * @return A list of constraint descriptors for all constraint specified on the given class.
 	 */
-	private List<ConstraintDescriptorImpl> findClassLevelConstraints(Class beanClass) {
+	private List<ConstraintDescriptorImpl> findClassLevelConstraints(Class<?> beanClass) {
 		List<ConstraintDescriptorImpl> metadata = new ArrayList<ConstraintDescriptorImpl>();
 		for ( Annotation annotation : beanClass.getAnnotations() ) {
-			metadata.addAll( findConstraintAnnotations( annotation ) );
+			metadata.addAll( findConstraintAnnotations( beanClass, annotation ) );
 		}
 		for ( ConstraintDescriptorImpl constraintDescriptor : metadata ) {
 			beanDescriptor.addConstraintDescriptor( constraintDescriptor );
@@ -287,61 +294,39 @@
 		return metadata;
 	}
 
+
 	/**
-	 * Finds all constraint annotations defined for the given methods and returns them in a list of
+	 * Finds all constraint annotations defined for the given field/method and returns them in a list of
 	 * constraint descriptors.
 	 *
-	 * @param method The method to check for constraints annotations.
+	 * @param member The fiels or method to check for constraints annotations.
 	 *
-	 * @return A list of constraint descriptors for all constraint specified for the given method.
+	 * @return A list of constraint descriptors for all constraint specified for the given field or method.
 	 */
-	private List<ConstraintDescriptorImpl> findMethodLevelConstraints(Method method) {
+	private List<ConstraintDescriptorImpl> findConstraints(Member member) {
+		assert member instanceof Field || member instanceof Method;
+
 		List<ConstraintDescriptorImpl> metadata = new ArrayList<ConstraintDescriptorImpl>();
-		for ( Annotation annotation : method.getAnnotations() ) {
-			metadata.addAll( findConstraintAnnotations( annotation ) );
+		for ( Annotation annotation : ( ( AnnotatedElement ) member ).getAnnotations() ) {
+			metadata.addAll( findConstraintAnnotations( member.getDeclaringClass(), annotation ) );
 		}
 
-		String methodName = ReflectionHelper.getPropertyName( method );
+		String name = ReflectionHelper.getPropertyName( member );
 		for ( ConstraintDescriptorImpl constraintDescriptor : metadata ) {
-			if ( methodName == null ) {
+			if ( member instanceof Method && name == null ) { // can happen if member is a Method which does not follow the bean convention
 				throw new ValidationException(
-						"Annotated methods must follow the JavaBeans naming convention. " + method.getName() + "() does not."
+						"Annotated methods must follow the JavaBeans naming convention. " + member.getName() + "() does not."
 				);
 			}
-			PropertyDescriptorImpl propertyDescriptor = ( PropertyDescriptorImpl ) propertyDescriptors.get( methodName );
+			PropertyDescriptorImpl propertyDescriptor = ( PropertyDescriptorImpl ) propertyDescriptors.get( name );
 			if ( propertyDescriptor == null ) {
-				propertyDescriptor = addPropertyDescriptorForMember( method );
+				propertyDescriptor = addPropertyDescriptorForMember( member );
 			}
 			propertyDescriptor.addConstraintDescriptor( constraintDescriptor );
 		}
 		return metadata;
 	}
 
-	/**
-	 * Finds all constraint annotations defined for the given field and returns them in a list of
-	 * constraint descriptors.
-	 *
-	 * @param field The field to check for constraints annotations.
-	 *
-	 * @return A list of constraint descriptors for all constraint specified on the given field.
-	 */
-	private List<ConstraintDescriptorImpl> findFieldLevelConstraints(Field field) {
-		List<ConstraintDescriptorImpl> metadata = new ArrayList<ConstraintDescriptorImpl>();
-		for ( Annotation annotation : field.getAnnotations() ) {
-			metadata.addAll( findConstraintAnnotations( annotation ) );
-		}
-
-		String fieldName = field.getName();
-		for ( ConstraintDescriptorImpl constraintDescriptor : metadata ) {
-			PropertyDescriptorImpl propertyDescriptor = ( PropertyDescriptorImpl ) propertyDescriptors.get( fieldName );
-			if ( propertyDescriptor == null ) {
-				propertyDescriptor = addPropertyDescriptorForMember( field );
-			}
-			propertyDescriptor.addConstraintDescriptor( constraintDescriptor );
-		}
-		return metadata;
-	}
-
 	public Class<T> getBeanClass() {
 		return beanClass;
 	}

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java	2009-03-07 08:33:16 UTC (rev 16105)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintDescriptorImpl.java	2009-03-07 17:57:46 UTC (rev 16106)
@@ -96,6 +96,11 @@
 	 */
 	private final ConstraintHelper constraintHelper;
 
+	public ConstraintDescriptorImpl(T annotation, Class<?>[] groups, ConstraintHelper constraintHelper, Class<?> implicitGroup) {
+		this( annotation, groups, constraintHelper );
+		this.groups.add( implicitGroup );
+	}
+
 	public ConstraintDescriptorImpl(T annotation, Class<?>[] groups, ConstraintHelper constraintHelper) {
 		this( annotation, new HashSet<Class<?>>(), constraintHelper );
 		if ( groups.length == 0 ) {
@@ -127,14 +132,14 @@
 		else {
 			//TODO are we sure a @Constraint is there?
 			final Class<? extends Annotation> annotationType = annotation.annotationType();
-			Class<? extends ConstraintValidator<?,?>>[] validatedBy = annotationType
+			Class<? extends ConstraintValidator<?, ?>>[] validatedBy = annotationType
 					.getAnnotation( Constraint.class )
 					.validatedBy();
-			for (Class<? extends ConstraintValidator<?,?>> validator : validatedBy) {
+			for ( Class<? extends ConstraintValidator<?, ?>> validator : validatedBy ) {
 				//FIXME does this create a CCE at runtime?
 				//FIXME if yes wrap into VE, if no we need to test the type here
 				//Once resolved,we can @SuppressWarning("unchecked") on the cast
-				Class<? extends ConstraintValidator<T,?>> safeValidator = (Class<? extends ConstraintValidator<T,?>>) validator;
+				Class<? extends ConstraintValidator<T, ?>> safeValidator = ( Class<? extends ConstraintValidator<T, ?>> ) validator;
 				constraintClasses.add( safeValidator );
 			}
 		}
@@ -165,14 +170,14 @@
 	 * {@inheritDoc}
 	 */
 	public Map<String, Object> getParameters() {
-		return Collections.unmodifiableMap(parameters);
+		return Collections.unmodifiableMap( parameters );
 	}
 
 	/**
 	 * {@inheritDoc}
 	 */
 	public Set<ConstraintDescriptor<?>> getComposingConstraints() {
-		return Collections.unmodifiableSet(composingConstraints);
+		return Collections.unmodifiableSet( composingConstraints );
 	}
 
 	/**
@@ -259,7 +264,9 @@
 		for ( Annotation declaredAnnotation : annotation.annotationType().getDeclaredAnnotations() ) {
 			if ( constraintHelper.isConstraintAnnotation( declaredAnnotation )
 					|| constraintHelper.isBuiltinConstraint( declaredAnnotation ) ) {
-				ConstraintDescriptorImpl<?> descriptor = createComposingConstraintDescriptor( declaredAnnotation, OVERRIDES_PARAMETER_DEFAULT_INDEX );
+				ConstraintDescriptorImpl<?> descriptor = createComposingConstraintDescriptor(
+						declaredAnnotation, OVERRIDES_PARAMETER_DEFAULT_INDEX
+				);
 				composingConstraints.add( descriptor );
 				log.debug( "Adding composing constraint: " + descriptor );
 			}
@@ -268,7 +275,7 @@
 				int index = 1;
 				for ( Annotation constraintAnnotation : multiValueConstraints ) {
 					ConstraintDescriptorImpl<?> descriptor = createComposingConstraintDescriptor(
-						constraintAnnotation, index
+							constraintAnnotation, index
 					);
 					composingConstraints.add( descriptor );
 					log.debug( "Adding composing constraint: " + descriptor );
@@ -282,12 +289,12 @@
 		//TODO don't quite understand this warning
 		//TODO assuming U.getClass() returns Class<U>
 		@SuppressWarnings("unchecked")
-		final Class<U> annotationType = (Class<U>) declaredAnnotation.annotationType();
+		final Class<U> annotationType = ( Class<U> ) declaredAnnotation.annotationType();
 		return createComposingConstraintDescriptor(
-						index,
-						declaredAnnotation,
-						annotationType
-				);
+				index,
+				declaredAnnotation,
+				annotationType
+		);
 	}
 
 	private <U extends Annotation> ConstraintDescriptorImpl<U> createComposingConstraintDescriptor(int index, U constraintAnnotation, Class<U> annotationType) {

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java	2009-03-07 08:33:16 UTC (rev 16105)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java	2009-03-07 17:57:46 UTC (rev 16106)
@@ -142,6 +142,26 @@
 	}
 
 	/**
+	 * Returns the type of the field of return type of a method.
+	 *
+	 * @param member the member for which to get the type.
+	 *
+	 * @return Returns the type of the field of return type of a method.
+	 */
+	public static Class<?> getAnnotations(Member member) {
+
+		Class<?> type = null;
+		if ( member instanceof Field ) {
+			type = ( ( Field ) member ).getType();
+		}
+
+		if ( member instanceof Method ) {
+			type = ( ( Method ) member ).getReturnType();
+		}
+		return type;
+	}
+
+	/**
 	 * @param member The <code>Member</code> instance for which to retrieve the type.
 	 *
 	 * @return Retrurns the <code>Type</code> of the given <code>Field</code> or <code>Method</code>.

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Auditable.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Auditable.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Auditable.java	2009-03-07 17:57:46 UTC (rev 16106)
@@ -0,0 +1,37 @@
+// $Id:$
+/*
+* 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.engine.groups;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface Auditable {
+	@NotNull
+	String getCreationDate();
+
+	@NotNull
+	String getLastUpdate();
+
+	@NotNull
+	String getLastModifier();
+
+	@NotNull
+	String getLastReader();
+}


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Auditable.java
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/GroupTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/GroupTest.java	2009-03-07 08:33:16 UTC (rev 16105)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/GroupTest.java	2009-03-07 17:57:46 UTC (rev 16106)
@@ -18,11 +18,13 @@
 package org.hibernate.validation.engine.groups;
 
 import java.util.Set;
+import javax.validation.BeanDescriptor;
 import javax.validation.ConstraintViolation;
 import javax.validation.ValidationException;
 import javax.validation.Validator;
 import javax.validation.groups.Default;
 
+import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 import static org.junit.Assert.assertEquals;
 import org.junit.Test;
@@ -344,7 +346,11 @@
 				1,
 				constraintViolations.size()
 		);
-		assertEquals( "Wrong constraint", "length must be between 2 and 20", constraintViolations.iterator().next().getMessage() );
+		assertEquals(
+				"Wrong constraint",
+				"length must be between 2 and 20",
+				constraintViolations.iterator().next().getMessage()
+		);
 
 		constraintViolations = validator.validateProperty( car, "type" );
 		assertEquals(
@@ -352,7 +358,11 @@
 				1,
 				constraintViolations.size()
 		);
-		assertEquals( "Wrong constraint", "length must be between 2 and 20", constraintViolations.iterator().next().getMessage() );
+		assertEquals(
+				"Wrong constraint",
+				"length must be between 2 and 20",
+				constraintViolations.iterator().next().getMessage()
+		);
 
 		constraintViolations = validator.validateValue( Car.class, "type", "A" );
 		assertEquals(
@@ -360,7 +370,11 @@
 				1,
 				constraintViolations.size()
 		);
-		assertEquals( "Wrong constraint", "length must be between 2 and 20", constraintViolations.iterator().next().getMessage() );
+		assertEquals(
+				"Wrong constraint",
+				"length must be between 2 and 20",
+				constraintViolations.iterator().next().getMessage()
+		);
 	}
 
 	/**
@@ -380,4 +394,25 @@
 			);
 		}
 	}
+
+	/**
+	 * HV-115
+	 */
+	@Test
+	public void testImplicitGroup() {
+		Validator validator = TestUtil.getValidator();
+		BeanDescriptor beanDescriptor = validator.getConstraintsForClass( Order.class );
+		assertTrue( beanDescriptor.isBeanConstrained() );
+
+		Set<String> constraintProperties = beanDescriptor.getConstrainedProperties();
+		assertTrue( "Each of the properties should have at least one constraint.", constraintProperties.size() == 5 );
+
+		Order order = new Order();
+		Set<ConstraintViolation<Order>> violations = validator.validate( order );
+		assertTrue( "All 5 NotNull constraints should fail.", violations.size() == 5 );
+
+		// use implicit group Auditable
+		violations = validator.validate( order, Auditable.class );
+		assertTrue( "All 4 NotNull constraints on Auditable should fail.", violations.size() == 4 );
+	}
 }
\ No newline at end of file

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Order.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Order.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Order.java	2009-03-07 17:57:46 UTC (rev 16106)
@@ -0,0 +1,54 @@
+// $Id:$
+/*
+* 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.engine.groups;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Order implements Auditable {
+	private String creationDate;
+	private String lastUpdate;
+	private String lastModifier;
+	private String lastReader;
+	private String orderNumber;
+
+	public String getCreationDate() {
+		return this.creationDate;
+	}
+
+	public String getLastUpdate() {
+		return this.lastUpdate;
+	}
+
+	public String getLastModifier() {
+		return this.lastModifier;
+	}
+
+	public String getLastReader() {
+		return this.lastReader;
+	}
+
+	@NotNull
+	@Size(min = 10, max = 10)
+	public String getOrderNumber() {
+		return this.orderNumber;
+	}
+}


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/groups/Order.java
___________________________________________________________________
Name: svn:keywords
   + Id




More information about the hibernate-commits mailing list