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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri May 21 06:31:30 EDT 2010


Author: hardy.ferentschik
Date: 2010-05-21 06:31:30 -0400 (Fri, 21 May 2010)
New Revision: 19581

Added:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/privilegedactions/package.html
Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java
Log:
HV-274 made sure inherited constraints configured via api get picked up

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	2010-05-21 06:56:48 UTC (rev 19580)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java	2010-05-21 10:31:30 UTC (rev 19581)
@@ -49,7 +49,7 @@
 import org.hibernate.validator.xml.XmlMappingParser;
 
 /**
- * Factory returning initialized <code>Validator</code> instances. This is Hibernate Validator's default
+ * Factory returning initialized {@code Validator} instances. This is Hibernate Validator's default
  * implementation of the {@code ValidatorFactory} interface.
  *
  * @author Emmanuel Bernard
@@ -125,54 +125,38 @@
 	 */
 	private <A extends Annotation, T> void initProgrammaticConfiguration(ConstraintMapping mapping) {
 		Map<Class<?>, List<ConstraintDefinition<?>>> configData = mapping.getConfigData();
-		for ( Map.Entry<Class<?>, List<ConstraintDefinition<?>>> entry : configData.entrySet() ) {
-			Map<Class<?>, List<MetaConstraint<T, ?>>> constraints = new HashMap<Class<?>, List<MetaConstraint<T, ?>>>();
-			for ( ConstraintDefinition<?> config : entry.getValue() ) {
-				AnnotationDescriptor<A> annotationDescriptor = new AnnotationDescriptor<A>(
-						( Class<A> ) config.getConstraintType()
-				);
-				for ( Map.Entry<String, Object> parameter : config.getParameters().entrySet() ) {
-					annotationDescriptor.setValue( parameter.getKey(), parameter.getValue() );
-				}
 
-				A annotation;
-				try {
-					annotation = AnnotationFactory.create( annotationDescriptor );
-				}
-				catch ( RuntimeException e ) {
-					throw new ValidationException(
-							"Unable to create annotation for configured constraint: " + e.getMessage(), e
-					);
-				}
+		for ( Class<?> clazz : mapping.getConfigData().keySet() ) {
+			@SuppressWarnings("unchecked")
+			Class<T> beanClass = ( Class<T> ) clazz;
 
-				ConstraintDescriptorImpl<A> constraintDescriptor = new ConstraintDescriptorImpl<A>(
-						annotation, constraintHelper, config.getElementType(), ConstraintOrigin.DEFINED_LOCALLY
-				);
+			// for each configured entity we have to check whether any of the interfaces or super classes is configured
+			// vua the programmatic api as well
+			List<Class<?>> classes = ReflectionHelper.computeClassHierarchy( beanClass );
 
-				final Member member = ReflectionHelper.getMember(
-						config.getBeanType(), config.getProperty(), config.getElementType()
-				);
+			Map<Class<?>, List<MetaConstraint<T, ?>>> constraints = createEmptyConstraintMap();
+			List<Member> cascadedMembers = new ArrayList<Member>();
 
-				MetaConstraint<T, ?> metaConstraint = new MetaConstraint(
-						config.getBeanType(), member, constraintDescriptor
-				);
-				List<MetaConstraint<T, ?>> constraintList = new ArrayList<MetaConstraint<T, ?>>();
-				constraintList.add( metaConstraint );
-				constraints.put( config.getBeanType(), constraintList );
+			for ( Class<?> classInHierarchy : classes ) {
+				// if the programmatic config contains constraints for the class in the hierarchy create a meta constraint
+				if ( mapping.getConfigData().keySet().contains( classInHierarchy ) ) {
+					addProgrammaticConfiguredConstraints(
+							mapping.getConfigData().get( classInHierarchy ), beanClass, classInHierarchy, constraints
+					);
+				}
+			}
 
+			BeanMetaDataImpl<T> metaData = new BeanMetaDataImpl<T>(
+					beanClass,
+					constraintHelper,
+					new ArrayList<Class<?>>(),
+					constraints,
+					new ArrayList<Member>(),
+					new AnnotationIgnores(),
+					beanMetaDataCache
+			);
 
-				BeanMetaDataImpl<T> metaData = new BeanMetaDataImpl<T>(
-						( Class<T> ) config.getBeanType(),
-						constraintHelper,
-						new ArrayList<Class<?>>(),
-						constraints,
-						new ArrayList<Member>(),
-						new AnnotationIgnores(),
-						beanMetaDataCache
-				);
-
-				beanMetaDataCache.addBeanMetaData( ( Class<T> ) config.getBeanType(), metaData );
-			}
+			beanMetaDataCache.addBeanMetaData( beanClass, metaData );
 		}
 	}
 
@@ -188,7 +172,7 @@
 			Class<T> beanClass = ( Class<T> ) clazz;
 
 			List<Class<?>> classes = ReflectionHelper.computeClassHierarchy( beanClass );
-			Map<Class<?>, List<MetaConstraint<T, ?>>> constraints = new HashMap<Class<?>, List<MetaConstraint<T, ?>>>();
+			Map<Class<?>, List<MetaConstraint<T, ?>>> constraints = createEmptyConstraintMap();
 			List<Member> cascadedMembers = new ArrayList<Member>();
 			// we need to collect all constraints which apply for a single class. Due to constraint inheritance
 			// some constraints might be configured in super classes or interfaces. The xml configuration does not
@@ -216,7 +200,9 @@
 	}
 
 	@SuppressWarnings("unchecked")
-	private <T, A extends Annotation> void addXmlConfiguredConstraints(XmlMappingParser mappingParser, Class<T> rootClass, Class<?> hierarchyClass, Map<Class<?>, List<MetaConstraint<T, ?>>> constraints) {
+	private <T, A extends Annotation> void addXmlConfiguredConstraints(XmlMappingParser mappingParser,
+																	   Class<T> rootClass,
+																	   Class<?> hierarchyClass, Map<Class<?>, List<MetaConstraint<T, ?>>> constraints) {
 		for ( MetaConstraint<?, ? extends Annotation> constraint : mappingParser.getConstraintsForClass( hierarchyClass ) ) {
 			ConstraintOrigin definedIn = definedIn( rootClass, hierarchyClass );
 			ConstraintDescriptorImpl<A> descriptor = new ConstraintDescriptorImpl<A>(
@@ -228,21 +214,60 @@
 			MetaConstraint<T, A> newMetaConstraint = new MetaConstraint<T, A>(
 					rootClass, constraint.getMember(), descriptor
 			);
-			List<MetaConstraint<T, ?>> constraintList = constraints.get( hierarchyClass );
-			if ( constraintList == null ) {
-				constraintList = new ArrayList<MetaConstraint<T, ?>>();
-				constraints.put( hierarchyClass, constraintList );
-			}
-			constraintList.add( newMetaConstraint );
+
+			addConstraintToMap( hierarchyClass, newMetaConstraint, constraints );
 		}
 	}
 
-	private void addXmlCascadedMember(XmlMappingParser mappingParser, Class<?> hierarchyClass, List<Member> cascadedMembers) {
+	@SuppressWarnings("unchecked")
+	private <T, A extends Annotation> void addProgrammaticConfiguredConstraints(List<ConstraintDefinition<?>> definitions,
+																				Class<T> rootClass, Class<?> hierarchyClass,
+																				Map<Class<?>, List<MetaConstraint<T, ?>>> constraints) {
+		for ( ConstraintDefinition<?> config : definitions ) {
+			A annotation = (A) createAnnotationProxy( config );
+			ConstraintOrigin definedIn = definedIn( rootClass, hierarchyClass );
+			ConstraintDescriptorImpl<A> constraintDescriptor = new ConstraintDescriptorImpl<A>(
+					annotation, constraintHelper, config.getElementType(), definedIn
+			);
+
+			Member member = ReflectionHelper.getMember(
+					config.getBeanType(), config.getProperty(), config.getElementType()
+			);
+
+			MetaConstraint<T, ?> metaConstraint = new MetaConstraint(
+					config.getBeanType(), member, constraintDescriptor
+			);
+			addConstraintToMap( hierarchyClass, metaConstraint, constraints );
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private <T, A extends Annotation> void addConstraintToMap(Class<?> hierarchyClass,
+															  MetaConstraint<T, A> constraint,
+															  Map<Class<?>, List<MetaConstraint<T, ?>>> constraints) {
+		List<MetaConstraint<T, ?>> constraintList = constraints.get( hierarchyClass );
+		if ( constraintList == null ) {
+			constraintList = new ArrayList<MetaConstraint<T, ?>>();
+			constraints.put( hierarchyClass, constraintList );
+		}
+		constraintList.add( constraint );
+	}
+
+	private void addXmlCascadedMember(XmlMappingParser mappingParser,
+									  Class<?> hierarchyClass,
+									  List<Member> cascadedMembers) {
 		for ( Member m : mappingParser.getCascadedMembersForClass( hierarchyClass ) ) {
 			cascadedMembers.add( m );
 		}
 	}
 
+	/**
+	 * @param rootClass The root class. That is the class for which we currently create a  {@code BeanMetaData}
+	 * @param hierarchyClass The class on which the current constraint is defined on
+	 *
+	 * @return Returns {@code ConstraintOrigin.DEFINED_LOCALLY} if the constraint was defined on the root bean,
+	 *         {@code ConstraintOrigin.DEFINED_IN_HIERARCHY} otherwise.
+	 */
 	private ConstraintOrigin definedIn(Class<?> rootClass, Class<?> hierarchyClass) {
 		if ( hierarchyClass.equals( rootClass ) ) {
 			return ConstraintOrigin.DEFINED_LOCALLY;
@@ -251,4 +276,28 @@
 			return ConstraintOrigin.DEFINED_IN_HIERARCHY;
 		}
 	}
+
+	@SuppressWarnings("unchecked")
+	private <A extends Annotation> Annotation createAnnotationProxy(ConstraintDefinition<?> config) {
+		Class<A> constraintType = (Class<A>) config.getConstraintType();
+		AnnotationDescriptor<A> annotationDescriptor = new AnnotationDescriptor<A>( constraintType );
+		for ( Map.Entry<String, Object> parameter : config.getParameters().entrySet() ) {
+			annotationDescriptor.setValue( parameter.getKey(), parameter.getValue() );
+		}
+
+		A annotation;
+		try {
+			annotation = AnnotationFactory.create( annotationDescriptor );
+		}
+		catch ( RuntimeException e ) {
+			throw new ValidationException(
+					"Unable to create annotation for configured constraint: " + e.getMessage(), e
+			);
+		}
+		return annotation;
+	}
+
+	private <T> Map<Class<?>, List<MetaConstraint<T, ?>>> createEmptyConstraintMap() {
+		return new HashMap<Class<?>, List<MetaConstraint<T, ?>>>();
+	}
 }

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java	2010-05-21 06:56:48 UTC (rev 19580)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/ReflectionHelper.java	2010-05-21 10:31:30 UTC (rev 19581)
@@ -650,7 +650,8 @@
 	 *
 	 * @param clazz The class to start the search with.
 	 *
-	 * @return List of all super classes and interfaces of {@code clazz}.
+	 * @return List of all super classes and interfaces of {@code clazz}. The list contains the class itself! The empty
+	 *         list is returned if {@code clazz} is {@code null}.
 	 */
 	public static List<Class<?>> computeClassHierarchy(Class<?> clazz) {
 		List<Class<?>> classes = new ArrayList<Class<?>>();

Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/privilegedactions/package.html (from rev 19558, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/package.html)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/privilegedactions/package.html	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/util/privilegedactions/package.html	2010-05-21 10:31:30 UTC (rev 19581)
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+    <!--
+
+  JBoss, Home of Professional Open Source
+  Copyright 2010, 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.
+
+-->
+</head>
+<body>
+Implementations of {@code PrivilegedAction} in order to execute reflection operations in a security manager.
+</body>
+</html>

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java	2010-05-21 06:56:48 UTC (rev 19580)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java	2010-05-21 10:31:30 UTC (rev 19581)
@@ -92,7 +92,7 @@
 		assertConstraintViolation( violations.iterator().next(), "may not be null" );
 	}
 
-	@Test(enabled = false)
+	@Test
 	public void testInheritedConstraint() {
 		HibernateValidatorConfiguration config = TestUtil.getConfiguration( HibernateValidator.class );
 
@@ -117,7 +117,7 @@
 
 		Set<ConstraintViolation<Marathon>> violations = validator.validate( marathon );
 		assertNumberOfViolations( violations, 1 );
-		assertConstraintViolation( violations.iterator().next(), "may not be null" );
+		assertConstraintViolation( violations.iterator().next(), "must be in the future" );
 	}
 
 	@Test



More information about the hibernate-commits mailing list