[hibernate-commits] Hibernate SVN: r16279 - in validator/trunk/hibernate-validator/src: test/java/org/hibernate/validation/constraints and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Apr 8 08:48:10 EDT 2009


Author: hardy.ferentschik
Date: 2009-04-08 08:48:10 -0400 (Wed, 08 Apr 2009)
New Revision: 16279

Added:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.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/ValidatorFactoryImpl.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternValidatorTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/User.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/XmlConfigurationTest.java
   validator/trunk/hibernate-validator/src/test/resources/META-INF/validation/user-constraints.xml
Log:
HV-112
Added a new class for taking care of the annotation ignores.

Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/AnnotationIgnores.java	2009-04-08 12:48:10 UTC (rev 16279)
@@ -0,0 +1,119 @@
+// $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;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+
+import org.hibernate.validation.util.LoggerFactory;
+
+/**
+ * This class instantiated during the parsing of the XML configuration data and keeps
+ * track of the annotations which should be ignored.
+ *
+ * @author Hardy Ferentschik
+ */
+public class AnnotationIgnores {
+
+	private static final Logger log = LoggerFactory.make();
+
+	/**
+	 * Keeps track whether the 'ignore-annotations' flag is set on bean level in the xml configuration. If 'ignore-annotations'
+	 * is not specified <code>false</code> is the default.
+	 */
+	private final Map<Class<?>, Boolean> ignoreAnnotationDefaults = new HashMap<Class<?>, Boolean>();
+
+	/**
+	 * Keeps track of explicitly excluded members (fields and properties) for a given class. If a member appears in
+	 * the list mapped to a given class 'ignore-annotations' was explicitly set to <code>true</code> in the configuration
+	 * for this class.
+	 */
+	private final Map<Class<?>, List<Member>> ignoreAnnotationOnMember = new HashMap<Class<?>, List<Member>>();
+
+	private final List<Class<?>> ignoreAnnotationOnClass = new ArrayList<Class<?>>();
+
+	public void setDefaultIgnoreAnnotation(Class<?> clazz, Boolean b) {
+		if ( b == null ) {
+			ignoreAnnotationDefaults.put( clazz, Boolean.FALSE );
+		}
+		else {
+			ignoreAnnotationDefaults.put( clazz, b );
+		}
+	}
+
+	public boolean getDefaultIgnoreAnnotation(Class<?> clazz) {
+		return ignoreAnnotationDefaults.containsKey( clazz ) && ignoreAnnotationDefaults.get( clazz );
+	}
+
+	public void setIgnoreAnnotationsOnMember(Member member) {
+		Class<?> beanClass = member.getDeclaringClass();
+		if ( ignoreAnnotationOnMember.get( beanClass ) == null ) {
+			List<Member> tmpList = new ArrayList<Member>();
+			tmpList.add( member );
+			ignoreAnnotationOnMember.put( beanClass, tmpList );
+		}
+		else {
+			ignoreAnnotationOnMember.get( beanClass ).add( member );
+		}
+	}
+
+	public boolean isIgnoreAnnotations(Member member) {
+		boolean ignoreAnnotation;
+		Class<?> clazz = member.getDeclaringClass();
+		List<Member> ignoreAnnotationForMembers = ignoreAnnotationOnMember.get( clazz );
+		if ( ignoreAnnotationForMembers == null || !ignoreAnnotationForMembers.contains( member ) ) {
+			ignoreAnnotation = getDefaultIgnoreAnnotation( clazz );
+		}
+		else {
+			ignoreAnnotation = ignoreAnnotationForMembers.contains( member );
+		}
+		if ( ignoreAnnotation ) {
+			logMessage( member, clazz );
+		}
+		return ignoreAnnotation;
+	}
+
+	private void logMessage(Member member, Class<?> clazz) {
+		String type;
+		if ( member instanceof Field ) {
+			type = "Field";
+		}
+		else {
+			type = "Property";
+		}
+		log.debug( type + " level annotations are getting ignored for " + clazz.getName() + "." + member.getName() );
+	}
+
+	public void setIgnoreAnnotationsOnClass(Class<?> clazz) {
+		ignoreAnnotationOnClass.add( clazz );
+	}
+
+	public boolean isIgnoreAnnotations(Class<?> clazz) {
+		boolean ignoreAnnotation = ignoreAnnotationOnClass.contains( clazz ) || getDefaultIgnoreAnnotation( clazz );
+		if ( log.isDebugEnabled() && ignoreAnnotation ) {
+			log.debug( "Class level annotation are getting ignored for " + clazz.getName() );
+		}
+		return ignoreAnnotation;
+	}
+}


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

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-04-08 11:23:35 UTC (rev 16278)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BeanMetaDataImpl.java	2009-04-08 12:48:10 UTC (rev 16279)
@@ -90,32 +90,18 @@
 	 */
 	private final ConstraintHelper constraintHelper;
 
-	private Map<Class<?>, Boolean> ignoreAnnotationDefaults;
-	private Map<Class<?>, List<Member>> ignoreAnnotationOnMember;
-	private List<Class<?>> ignoreAnnotationOnClass;
-
 	public BeanMetaDataImpl(Class<T> beanClass, ConstraintHelper constraintHelper) {
 		this(
 				beanClass,
 				constraintHelper,
-				new HashMap<Class<?>, Boolean>(),
-				new ArrayList<Class<?>>(),
-				new HashMap<Class<?>, List<Member>>()
+				new AnnotationIgnores()
 		);
 	}
 
-	public BeanMetaDataImpl(Class<T> beanClass, ConstraintHelper constraintHelper, Map<Class<?>, Boolean> ignoreAnnotationDefaults, List<Class<?>> ignoreAnnotationOnClass, Map<Class<?>, List<Member>> ignoreAnnotationOnMember) {
+	public BeanMetaDataImpl(Class<T> beanClass, ConstraintHelper constraintHelper, AnnotationIgnores annotationIgnores) {
 		this.beanClass = beanClass;
 		this.constraintHelper = constraintHelper;
-		this.ignoreAnnotationDefaults = ignoreAnnotationDefaults;
-		this.ignoreAnnotationOnClass = ignoreAnnotationOnClass;
-		this.ignoreAnnotationOnMember = ignoreAnnotationOnMember;
-
-		createMetaData();
-
-		this.ignoreAnnotationDefaults = null;
-		this.ignoreAnnotationOnClass = null;
-		this.ignoreAnnotationOnMember = null;
+		createMetaData( annotationIgnores );
 	}
 
 	public Class<T> getBeanClass() {
@@ -153,14 +139,16 @@
 	/**
 	 * Create bean desciptor, find all classes/subclasses/interfaces which have to be taken in consideration
 	 * for this validator and create meta data.
+	 *
+	 * @param annotationIgnores Datastructure keeping track on which annotation should be ignored.
 	 */
-	private void createMetaData() {
+	private void createMetaData(AnnotationIgnores annotationIgnores) {
 		beanDescriptor = new BeanDescriptorImpl<T>( this );
 		initDefaultGroupSequence( beanClass );
 		List<Class> classes = new ArrayList<Class>();
 		computeClassHierarchy( beanClass, classes );
 		for ( Class current : classes ) {
-			initClass( current );
+			initClass( current, annotationIgnores );
 		}
 	}
 
@@ -185,10 +173,10 @@
 		}
 	}
 
-	private void initClass(Class clazz) {
-		initClassConstraints( clazz );
-		initMethodConstraints( clazz );
-		initFieldConstraints( clazz );
+	private void initClass(Class clazz, AnnotationIgnores annotationIgnores) {
+		initClassConstraints( clazz, annotationIgnores );
+		initMethodConstraints( clazz, annotationIgnores );
+		initFieldConstraints( clazz, annotationIgnores );
 	}
 
 	/**
@@ -225,11 +213,11 @@
 		}
 	}
 
-	private <A extends Annotation> void initFieldConstraints(Class clazz) {
+	private <A extends Annotation> void initFieldConstraints(Class clazz, AnnotationIgnores annotationIgnores) {
 		for ( Field field : clazz.getDeclaredFields() ) {
 			List<ConstraintDescriptorImpl> fieldMetadata = findConstraints( field );
 			for ( ConstraintDescriptorImpl constraintDescription : fieldMetadata ) {
-				if ( checkSkipAnnotationProcessing( clazz, field ) ) {
+				if ( annotationIgnores.isIgnoreAnnotations( field ) ) {
 					break;
 				}
 				ReflectionHelper.setAccessibility( field );
@@ -246,11 +234,11 @@
 		}
 	}
 
-	private <A extends Annotation> void initMethodConstraints(Class clazz) {
+	private <A extends Annotation> void initMethodConstraints(Class clazz, AnnotationIgnores annotationIgnores) {
 		for ( Method method : clazz.getDeclaredMethods() ) {
 			List<ConstraintDescriptorImpl> methodMetadata = findConstraints( method );
 			for ( ConstraintDescriptorImpl constraintDescription : methodMetadata ) {
-				if ( checkSkipAnnotationProcessing( clazz, method ) ) {
+				if ( annotationIgnores.isIgnoreAnnotations( method ) ) {
 					break;
 				}
 				ReflectionHelper.setAccessibility( method );
@@ -267,29 +255,6 @@
 		}
 	}
 
-	private boolean checkSkipAnnotationProcessing(Class clazz, Member member) {
-		List<Member> ignoreAnnotationForFields = ignoreAnnotationOnMember.get( clazz );
-		boolean ignoreAnnotation;
-		if ( ignoreAnnotationForFields == null || !ignoreAnnotationForFields.contains( member ) ) {
-			ignoreAnnotation = ignoreAnnotationDefaults.containsKey( clazz ) && ignoreAnnotationDefaults.get( clazz );
-		}
-		else {
-			ignoreAnnotation = ignoreAnnotationForFields.contains( member );
-		}
-		if ( ignoreAnnotation ) {
-			String type;
-			if ( member instanceof Field ) {
-				type = "Field";
-			}
-			else {
-				type = "Property";
-			}
-			log.debug( type + " level annotations are getting ignored for " + clazz.getName() + "." + member.getName() );
-			return true;
-		}
-		return false;
-	}
-
 	private PropertyDescriptorImpl addPropertyDescriptorForMember(Member member) {
 		String name = ReflectionHelper.getPropertyName( member );
 		PropertyDescriptorImpl propertyDescriptor = ( PropertyDescriptorImpl ) propertyDescriptors.get(
@@ -306,10 +271,8 @@
 		return propertyDescriptor;
 	}
 
-	private <A extends Annotation> void initClassConstraints(Class clazz) {
-		if ( ignoreAnnotationOnClass.contains( clazz ) ||
-				( ignoreAnnotationDefaults.containsKey( clazz ) && ignoreAnnotationDefaults.get( clazz ) ) ) {
-			log.debug( "Class level annotation are getting ignored for " + clazz.getName() );
+	private <A extends Annotation> void initClassConstraints(Class clazz, AnnotationIgnores annotationIgnores) {
+		if ( annotationIgnores.isIgnoreAnnotations( clazz ) ) {
 			return;
 		}
 		List<ConstraintDescriptorImpl> classMetadata = findClassLevelConstraints( clazz );

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-04-08 11:23:35 UTC (rev 16278)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImpl.java	2009-04-08 12:48:10 UTC (rev 16279)
@@ -81,16 +81,17 @@
 	private final ConstraintHelper constraintHelper = new ConstraintHelper();
 	private static final String PACKAGE_SEPERATOR = ".";
 
-	private final Map<Class<?>, Boolean> ignoreAnnotationDefaults = new HashMap<Class<?>, Boolean>();
-	private final Map<Class<?>, List<Member>> ignoreAnnotationOnMember = new HashMap<Class<?>, List<Member>>();
-	private final List<Class<?>> ignoreAnnotationOnClass = new ArrayList<Class<?>>();
-	private final Map<Class<?>, List<MetaConstraint<?, ?>>> constraintMap = new HashMap<Class<?>, List<MetaConstraint<?, ?>>>();
+	private AnnotationIgnores annotationIgnores;
+	private Map<Class<?>, List<MetaConstraint<?, ?>>> constraintMap;
 
 	public ValidatorFactoryImpl(ConfigurationState configurationState) {
 		this.messageInterpolator = configurationState.getMessageInterpolator();
 		this.constraintValidatorFactory = configurationState.getConstraintValidatorFactory();
 		this.traversableResolver = configurationState.getTraversableResolver();
 
+		annotationIgnores = new AnnotationIgnores();
+		constraintMap = new HashMap<Class<?>, List<MetaConstraint<?, ?>>>();
+
 		parseMappingFiles( configurationState.getMappingStreams() );
 		initBeanMetaData();
 	}
@@ -140,8 +141,7 @@
 				for ( BeanType bean : mappings.getBean() ) {
 					Class<?> beanClass = getClass( bean.getClazz(), defaultPackage );
 					checkClassHasNotBeenProcessed( processedClasses, beanClass );
-					Boolean ignoreAnnotations = bean.isIgnoreAnnotations() == null ? false : bean.isIgnoreAnnotations();
-					ignoreAnnotationDefaults.put( beanClass, ignoreAnnotations );
+					annotationIgnores.setDefaultIgnoreAnnotation( beanClass, bean.isIgnoreAnnotations() );
 					parseClassLevelOverrides( bean.getClassType(), beanClass, defaultPackage );
 					parseFieldLevelOverrides( bean.getField(), beanClass, defaultPackage );
 					parsePropertyLevelOverrides( bean.getGetter(), beanClass, defaultPackage );
@@ -174,7 +174,7 @@
 			Field field = ReflectionHelper.getField( beanClass, fieldName );
 			boolean ignoreFieldAnnotation = fieldType.isIgnoreAnnotations() == null ? false : fieldType.isIgnoreAnnotations();
 			if ( ignoreFieldAnnotation ) {
-				addMemberToIgnoreList( beanClass, field );
+				annotationIgnores.setIgnoreAnnotationsOnMember( field );
 			}
 			for ( ConstraintType constraint : fieldType.getConstraint() ) {
 				MetaConstraint<?, ?> metaConstraint = createMetaConstraint(
@@ -185,17 +185,6 @@
 		}
 	}
 
-	private void addMemberToIgnoreList(Class<?> beanClass, Member member) {
-		if ( ignoreAnnotationOnMember.get( beanClass ) == null ) {
-			List<Member> ignoredAnnotationOnMember = new ArrayList<Member>();
-			ignoredAnnotationOnMember.add( member );
-			ignoreAnnotationOnMember.put( beanClass, ignoredAnnotationOnMember );
-		}
-		else {
-			ignoreAnnotationOnMember.get( beanClass ).add( member );
-		}
-	}
-
 	private void parsePropertyLevelOverrides(List<GetterType> getters, Class<?> beanClass, String defaultPackage) {
 		for ( GetterType getter : getters ) {
 			String getterName = getter.getName();
@@ -205,7 +194,7 @@
 			Method method = ReflectionHelper.getMethod( beanClass, getterName );
 			boolean ignoreGetterAnnotation = getter.isIgnoreAnnotations() == null ? false : getter.isIgnoreAnnotations();
 			if ( ignoreGetterAnnotation ) {
-				addMemberToIgnoreList( beanClass, method );
+				annotationIgnores.setIgnoreAnnotationsOnMember( method );
 			}
 			for ( ConstraintType constraint : getter.getConstraint() ) {
 				MetaConstraint<?, ?> metaConstraint = createMetaConstraint(
@@ -222,7 +211,7 @@
 		}
 		boolean ignoreClassAnnotation = classType.isIgnoreAnnotations() == null ? false : classType.isIgnoreAnnotations();
 		if ( ignoreClassAnnotation ) {
-			ignoreAnnotationOnClass.add( beanClass );
+			annotationIgnores.setIgnoreAnnotationsOnClass( beanClass );
 		}
 		for ( ConstraintType constraint : classType.getConstraint() ) {
 			MetaConstraint<?, ?> metaConstraint = createMetaConstraint( constraint, beanClass, null, defaultPackage );
@@ -466,13 +455,7 @@
 
 	private void initBeanMetaData() {
 		for ( Map.Entry<Class<?>, List<MetaConstraint<?, ?>>> entry : constraintMap.entrySet() ) {
-			BeanMetaDataImpl<?> metaData = new BeanMetaDataImpl(
-					entry.getKey(),
-					constraintHelper,
-					ignoreAnnotationDefaults,
-					ignoreAnnotationOnClass,
-					ignoreAnnotationOnMember
-			);
+			BeanMetaDataImpl<?> metaData = new BeanMetaDataImpl( entry.getKey(), constraintHelper, annotationIgnores );
 			for ( MetaConstraint<?, ?> metaConstraint : entry.getValue() ) {
 				metaData.addMetaConstraint( metaConstraint );
 			}

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternValidatorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternValidatorTest.java	2009-04-08 11:23:35 UTC (rev 16278)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternValidatorTest.java	2009-04-08 12:48:10 UTC (rev 16279)
@@ -42,7 +42,6 @@
 		PatternValidator constraint = new PatternValidator();
 		constraint.initialize( p );
 
-
 		assertTrue( constraint.isValid( null, null ) );
 		assertFalse( constraint.isValid( "", null ) );
 		assertFalse( constraint.isValid( "bla bla", null ) );

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/User.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/User.java	2009-04-08 11:23:35 UTC (rev 16278)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/User.java	2009-04-08 12:48:10 UTC (rev 16279)
@@ -1,6 +1,7 @@
 package org.hibernate.validation.engine.xml;
 
 import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
 import javax.validation.groups.Default;
 
 /**
@@ -14,7 +15,7 @@
 
 	private String lastname;
 
-	//@Pattern(regexp = "[0-9 -]?", groups = Optional.class)
+	@Pattern(regexp = "[0-9 -]+", message = "A phone nmber can only contain numbers, whitespaces and dashes.")
 	private String phoneNumber;
 
 	@NotNull(groups = Default.class)

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/XmlConfigurationTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/XmlConfigurationTest.java	2009-04-08 11:23:35 UTC (rev 16278)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/xml/XmlConfigurationTest.java	2009-04-08 12:48:10 UTC (rev 16279)
@@ -82,4 +82,24 @@
 		constraintViolations = validator.validate( user );
 		assertNumberOfViolations( constraintViolations, 0 );
 	}
+
+	@Test
+	public void testAnnotationDefinedConstraintApplies() {
+		Validator validator = getValidator();
+
+		User user = new User();
+		user.setConsistent( true );
+		user.setPhoneNumber( "police" );
+
+		Set<ConstraintViolation<User>> constraintViolations = validator.validate( user );
+		assertNumberOfViolations( constraintViolations, 1 );
+		TestUtil.assertConstraintViolation(
+				constraintViolations.iterator().next(),
+				"A phone nmber can only contain numbers, whitespaces and dashes."
+		);
+
+		user.setPhoneNumber( "112" );
+		constraintViolations = validator.validate( user );
+		assertNumberOfViolations( constraintViolations, 0 );
+	}
 }

Modified: validator/trunk/hibernate-validator/src/test/resources/META-INF/validation/user-constraints.xml
===================================================================
--- validator/trunk/hibernate-validator/src/test/resources/META-INF/validation/user-constraints.xml	2009-04-08 11:23:35 UTC (rev 16278)
+++ validator/trunk/hibernate-validator/src/test/resources/META-INF/validation/user-constraints.xml	2009-04-08 12:48:10 UTC (rev 16279)
@@ -25,7 +25,7 @@
         <field name="lastname">
             <constraint annotation="javax.validation.constraints.Pattern">
                 <message>Last name has to start with with a capital letter.</message>
-                <element name="regexp">^[A-Z].*</element>
+                <element name="regexp">^[A-Z][a-z]+</element>
                 <!--element name="patterns">
                     <annotation>
                         <element name="value">myRegExp</element>




More information about the hibernate-commits mailing list