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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Oct 28 08:14:32 EDT 2009


Author: hardy.ferentschik
Date: 2009-10-28 08:14:31 -0400 (Wed, 28 Oct 2009)
New Revision: 17860

Added:
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterface.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterfaceImpl.java
   validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-impl-mapping.xml
   validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-mapping.xml
Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java
Log:
HV-262

When building the metadata for a class we have to check the bean meta cache as well, since it could contain configuration for beans which are only mapped in xml

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java	2009-10-28 10:57:21 UTC (rev 17859)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java	2009-10-28 12:14:31 UTC (rev 17860)
@@ -107,7 +107,7 @@
 			@SuppressWarnings("unchecked")
 			Class<T> beanClass = ( Class<T> ) clazz;
 			BeanMetaDataImpl<T> metaData = new BeanMetaDataImpl<T>(
-					beanClass, constraintHelper, annotationIgnores
+					beanClass, constraintHelper, annotationIgnores, beanMetaDataCache
 			);
 
 			List<Class<?>> classes = new ArrayList<Class<?>>();

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorImpl.java	2009-10-28 10:57:21 UTC (rev 17859)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorImpl.java	2009-10-28 12:14:31 UTC (rev 17860)
@@ -732,7 +732,7 @@
 	private <U> BeanMetaData<U> getBeanMetaData(Class<U> beanClass) {
 		BeanMetaDataImpl<U> beanMetaData = beanMetaDataCache.getBeanMetaData( beanClass );
 		if ( beanMetaData == null ) {
-			beanMetaData = new BeanMetaDataImpl<U>( beanClass, constraintHelper );
+			beanMetaData = new BeanMetaDataImpl<U>( beanClass, constraintHelper, beanMetaDataCache );
 			beanMetaDataCache.addBeanMetaData( beanClass, beanMetaData );
 		}
 		return beanMetaData;

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java	2009-10-28 10:57:21 UTC (rev 17859)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/metadata/BeanMetaDataImpl.java	2009-10-28 12:14:31 UTC (rev 17860)
@@ -102,18 +102,19 @@
 	// Used to avoid ReflectionHelper#containsMembe which is slow
 	private final Set<String> propertyNames = new HashSet<String>( 30 );
 
-	public BeanMetaDataImpl(Class<T> beanClass, ConstraintHelper constraintHelper) {
+	public BeanMetaDataImpl(Class<T> beanClass, ConstraintHelper constraintHelper, BeanMetaDataCache beanMetaDataCache) {
 		this(
 				beanClass,
 				constraintHelper,
-				new AnnotationIgnores()
+				new AnnotationIgnores(),
+				beanMetaDataCache
 		);
 	}
 
-	public BeanMetaDataImpl(Class<T> beanClass, ConstraintHelper constraintHelper, AnnotationIgnores annotationIgnores) {
+	public BeanMetaDataImpl(Class<T> beanClass, ConstraintHelper constraintHelper, AnnotationIgnores annotationIgnores, BeanMetaDataCache beanMetaDataCache) {
 		this.beanClass = beanClass;
 		this.constraintHelper = constraintHelper;
-		createMetaData( annotationIgnores );
+		createMetaData( annotationIgnores, beanMetaDataCache );
 	}
 
 	public Class<T> getBeanClass() {
@@ -225,22 +226,23 @@
 	 * Create bean descriptor, find all classes/subclasses/interfaces which have to be taken in consideration
 	 * for this validator and create meta data.
 	 *
-	 * @param annotationIgnores Data structure keeping track on which annotation should be ignored.
+	 * @param annotationIgnores Data structure keeping track on which annotation should be ignored
+	 * @param beanMetaDataCache The bean meta data cache
 	 */
-	private void createMetaData(AnnotationIgnores annotationIgnores) {
+	private void createMetaData(AnnotationIgnores annotationIgnores, BeanMetaDataCache beanMetaDataCache) {
 		beanDescriptor = new BeanDescriptorImpl<T>( this );
 		initDefaultGroupSequence();
 		List<Class<?>> classes = new ArrayList<Class<?>>();
 		ReflectionHelper.computeClassHierarchy( beanClass, classes );
 		for ( Class<?> current : classes ) {
-			initClass( current, annotationIgnores );
+			initClass( current, annotationIgnores, beanMetaDataCache );
 		}
 	}
 
-	private void initClass(Class<?> clazz, AnnotationIgnores annotationIgnores) {
-		initClassConstraints( clazz, annotationIgnores );
-		initMethodConstraints( clazz, annotationIgnores );
-		initFieldConstraints( clazz, annotationIgnores );
+	private void initClass(Class<?> clazz, AnnotationIgnores annotationIgnores, BeanMetaDataCache beanMetaDataCache) {
+		initClassConstraints( clazz, annotationIgnores, beanMetaDataCache );
+		initMethodConstraints( clazz, annotationIgnores, beanMetaDataCache );
+		initFieldConstraints( clazz, annotationIgnores, beanMetaDataCache );
 	}
 
 	/**
@@ -259,7 +261,7 @@
 		setDefaultGroupSequence( groupSequence );
 	}
 
-	private void initFieldConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores) {
+	private void initFieldConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores, BeanMetaDataCache beanMetaDataCache) {
 		GetDeclaredFields action = GetDeclaredFields.action( clazz );
 		final Field[] fields;
 		if ( System.getSecurityManager() != null ) {
@@ -280,14 +282,32 @@
 				continue;
 			}
 
-			List<ConstraintDescriptorImpl<?>> fieldMetaData = findConstraints( field, ElementType.FIELD );
+			// HV-262
+			BeanMetaDataImpl<?> cachedMetaData = beanMetaDataCache.getBeanMetaData( clazz );
+			List<ConstraintDescriptorImpl<?>> fieldMetaData;
+			boolean cachedFieldIsCascaded = false;
+			if ( cachedMetaData != null ) {
+				fieldMetaData = new ArrayList<ConstraintDescriptorImpl<?>>();
+				cachedFieldIsCascaded = cachedMetaData.getCascadedMembers().contains( field );
+				for ( MetaConstraint<?, ?> metaConstraint : cachedMetaData.getMetaConstraintsAsMap().get( clazz ) ) {
+					ConstraintDescriptorImpl<?> descriptor = metaConstraint.getDescriptor();
+					if ( descriptor.getElementType() == ElementType.FIELD
+							&& metaConstraint.getPropertyName().equals( ReflectionHelper.getPropertyName( field ) ) ) {
+						fieldMetaData.add( descriptor );
+					}
+				}
+			}
+			else {
+				fieldMetaData = findConstraints( field, ElementType.FIELD );
+			}
+
 			for ( ConstraintDescriptorImpl<?> constraintDescription : fieldMetaData ) {
 				setAccessibility( field );
 				MetaConstraint<T, ?> metaConstraint = createMetaConstraint( field, constraintDescription );
 				addMetaConstraint( clazz, metaConstraint );
 			}
 
-			if ( field.isAnnotationPresent( Valid.class ) ) {
+			if ( cachedFieldIsCascaded || field.isAnnotationPresent( Valid.class ) ) {
 				addCascadedMember( field );
 			}
 		}
@@ -310,7 +330,7 @@
 		}
 	}
 
-	private void initMethodConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores) {
+	private void initMethodConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores, BeanMetaDataCache beanMetaDataCache) {
 		GetDeclaredMethods action = GetDeclaredMethods.action( clazz );
 		final Method[] declaredMethods;
 		if ( System.getSecurityManager() != null ) {
@@ -332,13 +352,32 @@
 				continue;
 			}
 
-			List<ConstraintDescriptorImpl<?>> methodMetaData = findConstraints( method, ElementType.METHOD );
+			// HV-262
+			BeanMetaDataImpl<?> cachedMetaData = beanMetaDataCache.getBeanMetaData( clazz );
+			List<ConstraintDescriptorImpl<?>> methodMetaData;
+			boolean cachedMethodIsCascaded = false;
+			if ( cachedMetaData != null ) {
+				cachedMethodIsCascaded = cachedMetaData.getCascadedMembers().contains( method );
+				methodMetaData = new ArrayList<ConstraintDescriptorImpl<?>>();
+				for ( MetaConstraint<?, ?> metaConstraint : cachedMetaData.getMetaConstraintsAsMap().get( clazz ) ) {
+					ConstraintDescriptorImpl<?> descriptor = metaConstraint.getDescriptor();
+					if ( descriptor.getElementType() == ElementType.METHOD
+							&& metaConstraint.getPropertyName().equals( ReflectionHelper.getPropertyName( method ) ) ) {
+						methodMetaData.add( descriptor );
+					}
+				}
+			}
+			else {
+				methodMetaData = findConstraints( method, ElementType.METHOD );
+			}
+
 			for ( ConstraintDescriptorImpl<?> constraintDescription : methodMetaData ) {
 				setAccessibility( method );
 				MetaConstraint<T, ?> metaConstraint = createMetaConstraint( method, constraintDescription );
 				addMetaConstraint( clazz, metaConstraint );
 			}
-			if ( method.isAnnotationPresent( Valid.class ) ) {
+
+			if ( cachedMethodIsCascaded || method.isAnnotationPresent( Valid.class ) ) {
 				addCascadedMember( method );
 			}
 		}
@@ -365,12 +404,28 @@
 		return ( ( AnnotatedElement ) member ).isAnnotationPresent( Valid.class );
 	}
 
-	private void initClassConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores) {
+	private void initClassConstraints(Class<?> clazz, AnnotationIgnores annotationIgnores, BeanMetaDataCache beanMetaDataCache) {
 		if ( annotationIgnores.isIgnoreAnnotations( clazz ) ) {
 			return;
 		}
-		List<ConstraintDescriptorImpl<?>> classMetadata = findClassLevelConstraints( clazz );
-		for ( ConstraintDescriptorImpl<?> constraintDescription : classMetadata ) {
+
+		// HV-262
+		BeanMetaDataImpl<?> cachedMetaData = beanMetaDataCache.getBeanMetaData( clazz );
+		List<ConstraintDescriptorImpl<?>> classMetaData;
+		if ( cachedMetaData != null ) {
+			classMetaData = new ArrayList<ConstraintDescriptorImpl<?>>();
+			for ( MetaConstraint<?, ?> metaConstraint : cachedMetaData.getMetaConstraintsAsMap().get( clazz ) ) {
+				ConstraintDescriptorImpl<?> descriptor = metaConstraint.getDescriptor();
+				if ( descriptor.getElementType() == ElementType.TYPE ) {
+					classMetaData.add( descriptor );
+				}
+			}
+		}
+		else {
+			classMetaData = findClassLevelConstraints( clazz );
+		}
+
+		for ( ConstraintDescriptorImpl<?> constraintDescription : classMetaData ) {
 			MetaConstraint<T, ?> metaConstraint = createMetaConstraint( null, constraintDescription );
 			addMetaConstraint( clazz, metaConstraint );
 		}

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterface.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterface.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterface.java	2009-10-28 12:14:31 UTC (rev 17860)
@@ -0,0 +1,27 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, 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.validator.xml;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public interface MyInterface {
+	Integer getId();
+}
+
+

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterfaceImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterfaceImpl.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/MyInterfaceImpl.java	2009-10-28 12:14:31 UTC (rev 17860)
@@ -0,0 +1,28 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat, Inc. and/or its affiliates, 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.validator.xml;
+
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class MyInterfaceImpl implements MyInterface {
+	public Integer getId() {
+		return null;
+	}
+}
\ No newline at end of file

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java	2009-10-28 10:57:21 UTC (rev 17859)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/xml/XmlMappingTest.java	2009-10-28 12:14:31 UTC (rev 17860)
@@ -75,4 +75,36 @@
 
 		assertEquals( violations.size(), 0 );
 	}
+
+	@Test
+	/**
+	 * HV-262
+	 */
+	public void testInterfaceConfiguration() {
+
+		final Configuration<?> configuration = Validation.byDefaultProvider().configure();
+		configuration.addMapping( XmlMappingTest.class.getResourceAsStream( "my-interface-mapping.xml" ) );
+
+		final ValidatorFactory validatorFactory = configuration.buildValidatorFactory();
+		final Validator validator = validatorFactory.getValidator();
+		final Set<ConstraintViolation<MyInterfaceImpl>> violations = validator.validate( new MyInterfaceImpl());
+
+		assertEquals( violations.size(), 1);
+	}
+
+	@Test
+	/**
+	 * HV-262
+	 */
+	public void testInterfaceImplementationConfiguration() {
+
+		final Configuration<?> configuration = Validation.byDefaultProvider().configure();
+		configuration.addMapping( XmlMappingTest.class.getResourceAsStream( "my-interface-impl-mapping.xml" ) );
+
+		final ValidatorFactory validatorFactory = configuration.buildValidatorFactory();
+		final Validator validator = validatorFactory.getValidator();
+		final Set<ConstraintViolation<MyInterfaceImpl>> violations = validator.validate( new MyInterfaceImpl());
+
+		assertEquals( violations.size(), 1);
+	}
 }

Added: validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-impl-mapping.xml
===================================================================
--- validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-impl-mapping.xml	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-impl-mapping.xml	2009-10-28 12:14:31 UTC (rev 17860)
@@ -0,0 +1,10 @@
+<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                     xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"
+                     xmlns="http://jboss.org/xml/ns/javax/validation/mapping">
+    <default-package>org.hibernate.validator.xml</default-package>
+    <bean class="MyInterfaceImpl" ignore-annotations="true">
+        <getter name="id" ignore-annotations="true">
+            <constraint annotation="javax.validation.constraints.NotNull"/>
+        </getter>
+    </bean>
+</constraint-mappings>
\ No newline at end of file

Copied: validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-mapping.xml (from rev 17637, validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/mapping.xml)
===================================================================
--- validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-mapping.xml	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validator/xml/my-interface-mapping.xml	2009-10-28 12:14:31 UTC (rev 17860)
@@ -0,0 +1,10 @@
+<constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                     xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd"
+                     xmlns="http://jboss.org/xml/ns/javax/validation/mapping">
+    <default-package>org.hibernate.validator.xml</default-package>
+    <bean class="MyInterface" ignore-annotations="true">
+        <getter name="id" ignore-annotations="true">
+            <constraint annotation="javax.validation.constraints.NotNull"/>
+        </getter>
+    </bean>
+</constraint-mappings>
\ No newline at end of file



More information about the hibernate-commits mailing list