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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Oct 28 11:39:45 EDT 2008


Author: hardy.ferentschik
Date: 2008-10-28 11:39:45 -0400 (Tue, 28 Oct 2008)
New Revision: 15412

Removed:
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java
Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.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/ValidatorImplTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java
Log:
Some more refactorings towards implementing composite constraints


Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java	2008-10-28 15:02:46 UTC (rev 15411)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java	2008-10-28 15:39:45 UTC (rev 15412)
@@ -239,29 +239,30 @@
 	private <A extends Annotation> List<ConstraintDescriptorImpl> findConstraintAnnotations(A annotation) {
 		List<ConstraintDescriptorImpl> constraintDescriptors = new ArrayList<ConstraintDescriptorImpl>();
 
-		List<Annotation> constraintCandidates = new ArrayList<Annotation>();
-		constraintCandidates.add( annotation );
+		List<Annotation> constraints = new ArrayList<Annotation>();
+		if ( ReflectionHelper.isConstraintAnnotation( annotation ) ||
+				ReflectionHelper.isBuiltInConstraintAnnotation( annotation) ) {
+			constraints.add( annotation );
+		}
 
 		// check if we have a multi value constraint
-		Annotation[] annotations = getMultiValueConstraintsCandidates( annotation );
-		constraintCandidates.addAll( Arrays.asList( annotations ) );
+		constraints.addAll( ReflectionHelper.getMultiValueConstraints( annotation ) );
 
-		for ( Annotation constraintCandiate : constraintCandidates ) {
-
-			if ( ReflectionHelper.isBuiltInConstraintAnnotation( constraintCandiate ) ) {
-				Class constraintClass = ReflectionHelper.getBuiltInConstraint( constraintCandiate );
+		for ( Annotation constraint : constraints ) {
+			if ( ReflectionHelper.isBuiltInConstraintAnnotation( constraint ) ) {
+				Class constraintClass = ReflectionHelper.getBuiltInConstraint( constraint );
 				final ConstraintDescriptorImpl constraintDescriptor = buildConstraintDescriptor(
-						constraintCandiate, constraintClass
+						constraint, constraintClass
 				);
 				constraintDescriptors.add( constraintDescriptor );
 				continue;
 			}
 
-			if ( ReflectionHelper.isConstraintAnnotation( constraintCandiate ) ) {
-				ConstraintValidator constraintValidator = constraintCandiate.annotationType()
+			if ( ReflectionHelper.isConstraintAnnotation( constraint ) ) {
+				ConstraintValidator constraintValidator = constraint.annotationType()
 						.getAnnotation( ConstraintValidator.class );
 				final ConstraintDescriptorImpl constraintDescriptor = buildConstraintDescriptor(
-						constraintCandiate, constraintValidator.value()
+						constraint, constraintValidator.value()
 				);
 				constraintDescriptors.add( constraintDescriptor );
 			}
@@ -298,31 +299,6 @@
 	}
 
 	/**
-	 * Checks whether the given annotation has a value parameter which returns an array of annotations.
-	 *
-	 * @param annotation the annotation to check.
-	 *
-	 * @return The list of potential constraint annotations or the empty array.
-	 *
-	 * @todo Not only check that the return type of value is an array, but an array of annotaitons. Need to check syntax.
-	 */
-	private <A extends Annotation> Annotation[] getMultiValueConstraintsCandidates(A annotation) {
-		try {
-			Method m = annotation.getClass().getMethod( "value" );
-			Class returnType = m.getReturnType();
-			if ( returnType.isArray() ) {
-				return ( Annotation[] ) m.invoke( annotation );
-			}
-			else {
-				return new Annotation[0];
-			}
-		}
-		catch ( Exception e ) {
-			return new Annotation[0];
-		}
-	}
-
-	/**
 	 * Finds all constraint annotations defined for the given class and returns them in a list of
 	 * constraint descriptors.
 	 *

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	2008-10-28 15:02:46 UTC (rev 15411)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java	2008-10-28 15:39:45 UTC (rev 15412)
@@ -34,10 +34,13 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.ArrayList;
 import javax.validation.ConstraintValidator;
 import javax.validation.ValidationException;
 import javax.validation.constraints.NotNull;
 
+import org.slf4j.Logger;
+
 import org.hibernate.validation.constraints.NotNullConstraint;
 
 /**
@@ -47,6 +50,8 @@
  */
 public class ReflectionHelper {
 
+	private static final Logger log = LoggerFactory.make();
+
 	/**
 	 * Private constructor in order to avoid instantiation.
 	 */
@@ -67,6 +72,13 @@
 		}
 	}
 
+	/**
+	 * Checks whether the given annotation is a builtin constraint annotation defined as defined by the specs.
+	 *
+	 * @param annotation the annotation to check
+	 *
+	 * @return <code>true</code> if the annotation is a builtin constraint, <code>false</code> otherwise.
+	 */
 	public static boolean isBuiltInConstraintAnnotation(Annotation annotation) {
 		boolean isBuiltInConstraintAnnotation = false;
 
@@ -77,33 +89,80 @@
 		return isBuiltInConstraintAnnotation;
 	}
 
+	/**
+	 * Checks whehter the specified annotation is a valid constraint annotation. A constraint annotations has to
+	 * fulfill the following conditions:
+	 * <ul>
+	 * <li>Has to contain a <code>ConstraintValidator</code> implementation.</li>
+	 * <li>Defines a message parameter.</li>
+	 * <li>Defines a group parameter.</li>
+	 * </ul>
+	 *
+	 * @param annotation The annotation to test.
+	 *
+	 * @return <code>true</code> if the annotation fulfills the above condtions, <code>false</code> otherwise.
+	 */
 	public static boolean isConstraintAnnotation(Annotation annotation) {
-		boolean isConstraintAnnotation = true;
 
 		ConstraintValidator constraintValidator = annotation.annotationType()
 				.getAnnotation( ConstraintValidator.class );
 		if ( constraintValidator == null ) {
-			isConstraintAnnotation = false;
-			return isConstraintAnnotation;
+			return false;
 		}
 
 		try {
 			getAnnotationParameter( annotation, "message", String.class );
-		} 	catch ( Exception e ) {
-			throw new ValidationException( "Constraint annotation has to define message element." );
 		}
+		catch ( Exception e ) {
+			String msg = annotation.annotationType().getName() + " contains ConstraintValidator annotation, but does " +
+					"not contain a message parameter. Annotation is getting ignored.";
+			log.warn( msg );
+			return false;
+		}
 
 		try {
 			getAnnotationParameter( annotation, "groups", String[].class );
 		}
 		catch ( Exception e ) {
-			throw new ValidationException( "Constraint annotation has to define groups element." );
+			String msg = annotation.annotationType().getName() + " contains ConstraintValidator annotation, but does " +
+					"not contain a groups parameter. Annotation is getting ignored.";
+			log.warn( msg );
+			return false;
 		}
 
-		return isConstraintAnnotation;
+		return true;
 	}
 
+	/**
+	 * Checks whether a given annotation is a multi value constraint and returns the contained constraints if so.
+	 *
+	 * @param annotation the annotation to check.
+	 *
+	 * @return A list of constraint annotations or the empty list if <code>annotation</code> is not a multi constraint
+	 *         annotation.
+	 *
+	 */
+	public static <A extends Annotation> List<Annotation> getMultiValueConstraints(A annotation) {
+		List<Annotation> annotationList = new ArrayList<Annotation>();
+		try {
+			Method m = annotation.getClass().getMethod( "value" );
+			Class returnType = m.getReturnType();
+			if ( returnType.isArray() && returnType.getComponentType().isAnnotation() ) {
+				Annotation[] annotations = ( Annotation[] ) m.invoke( annotation );
+				for (Annotation a : annotations) {
+					if( isConstraintAnnotation( a ) || isBuiltInConstraintAnnotation( a )) {
+						annotationList.add( a );
+					}
+				}
+			}
+		}
+		catch ( Exception e ) {
+			// ignore
+		}
+		return annotationList;
+	}
 
+
 	@SuppressWarnings("unchecked")
 	public static <T> T getAnnotationParameter(Annotation annotation, String parameterName, Class<T> type) {
 		try {

Deleted: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java	2008-10-28 15:02:46 UTC (rev 15411)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Female.java	2008-10-28 15:39:45 UTC (rev 15412)
@@ -1,51 +0,0 @@
-// $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.eg;
-
-import org.hibernate.validation.eg.constraint.NoGroups;
-
-/**
- * @author Hardy Ferentschik
- */
-public class Female implements Person {
-
-	// @NoGroups is an invalid annotation (missing group paramter)
-	@NoGroups
-	private String firstName;
-	private String lastName;
-
-	public String getFirstName() {
-		return firstName;
-	}
-
-	public void setFirstName(String firstName) {
-		this.firstName = firstName;
-	}
-
-	public String getLastName() {
-		return lastName;
-	}
-
-	public void setLastName(String lastName) {
-		this.lastName = lastName;
-	}
-
-	public String getMiddleName() {
-		return null;
-	}
-}
\ No newline at end of file

Deleted: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java	2008-10-28 15:02:46 UTC (rev 15411)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Male.java	2008-10-28 15:39:45 UTC (rev 15412)
@@ -1,50 +0,0 @@
-// $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.eg;
-
-import org.hibernate.validation.eg.constraint.NoMessage;
-
-/**
- * @author Hardy Ferentschik
- */
-public class Male implements Person {
-    // @NoMessage is an invalid annotation (no message paramter)
-	@NoMessage
-	private String firstName;
-	private String lastName;
-
-	public String getFirstName() {
-		return firstName;
-	}
-
-	public void setFirstName(String firstName) {
-		this.firstName = firstName;
-	}
-
-	public String getLastName() {
-		return lastName;
-	}
-
-	public void setLastName(String lastName) {
-		this.lastName = lastName;
-	}
-
-	public String getMiddleName() {
-		return null;
-	}
-}
\ No newline at end of file

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java	2008-10-28 15:02:46 UTC (rev 15411)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java	2008-10-28 15:39:45 UTC (rev 15412)
@@ -38,8 +38,6 @@
 import org.hibernate.validation.eg.Dictonary;
 import org.hibernate.validation.eg.Engine;
 import org.hibernate.validation.eg.EnglishDictonary;
-import org.hibernate.validation.eg.Female;
-import org.hibernate.validation.eg.Male;
 import org.hibernate.validation.eg.Order;
 import org.hibernate.validation.eg.Unconstraint;
 
@@ -50,39 +48,8 @@
  */
 public class ValidatorImplTest {
 
-	/**
-	 * JSR 303: Constraint definition properties - message (2.1.1.1)
-	 */
-	@Test
-	public void testConstraintWithNoMessage() {
-		try {
-			new ValidatorImpl<Male>( Male.class );
-			fail();
-		}
-		catch ( ValidationException e ) {
-			assertEquals(
-					"Wrong error message", "Constraint annotation has to define message element.", e.getMessage()
-			);
-		}
-	}
 
 	/**
-	 * JSR 303: Constraint definition properties - groups (2.1.1.2)
-	 */
-	@Test
-	public void testConstraintWithNoGroups() {
-		try {
-			new ValidatorImpl<Female>( Female.class );
-			fail();
-		}
-		catch ( ValidationException e ) {
-			assertEquals(
-					"Wrong error message", "Constraint annotation has to define groups element.", e.getMessage()
-			);
-		}
-	}
-
-	/**
 	 * JSR 303: Requirements on classes to be validates (3.1)
 	 */
 	@Test
@@ -101,12 +68,12 @@
 	}
 
 
-	@Test( expected = IllegalArgumentException.class)
+	@Test(expected = IllegalArgumentException.class)
 	public void testNullParamterToValidatorImplConstructor() {
-		new ValidatorImpl<Unconstraint>( null);
+		new ValidatorImpl<Unconstraint>( null );
 	}
 
-	@Test	
+	@Test
 	public void testUnconstraintClass() {
 		Validator<Unconstraint> validator = new ValidatorImpl<Unconstraint>( Unconstraint.class );
 		assertTrue( "There should be no constraints", !validator.hasConstraints() );

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java	2008-10-28 15:02:46 UTC (rev 15411)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ReflectionHelperTest.java	2008-10-28 15:39:45 UTC (rev 15412)
@@ -18,7 +18,7 @@
 package org.hibernate.validation.util;
 
 import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -27,11 +27,20 @@
 import javax.validation.constraints.NotNull;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import org.junit.Test;
 
+import org.hibernate.validation.constraints.Pattern;
+import org.hibernate.validation.constraints.Patterns;
+import org.hibernate.validation.eg.Engine;
+import org.hibernate.validation.eg.Order;
+import org.hibernate.validation.eg.constraint.NoGroups;
+import org.hibernate.validation.eg.constraint.NoMessage;
+
 /**
  * Tests for the <code>ReflectionHelper</code>.
  *
@@ -112,7 +121,76 @@
 			fail();
 		}
 		catch ( ValidationException e ) {
-			assertTrue( "Wrong exception message", e.getMessage().startsWith( "The specified annotation defines no parameter" ) );
+			assertTrue(
+					"Wrong exception message",
+					e.getMessage().startsWith( "The specified annotation defines no parameter" )
+			);
 		}
 	}
+
+	/**
+	 * JSR 303: Constraint definition properties - message (2.1.1.1)
+	 */
+	@Test
+	public void testConstraintWithNoMessage() {
+		Annotation annotation = new NoGroups() {
+			public String message() {
+				return "";
+			}
+
+			public Class<? extends Annotation> annotationType() {
+				return this.getClass();
+			}
+		};
+		assertFalse(
+				"The constraint annotation should not be valid", ReflectionHelper.isConstraintAnnotation( annotation )
+		);
+	}
+
+	/**
+	 * JSR 303: Constraint definition properties - groups (2.1.1.2)
+	 */
+	@Test
+	public void testConstraintWithNoGroups() {
+		Annotation annotation = new NoMessage() {
+			public String[] groups() {
+				return null;
+			}
+
+			public Class<? extends Annotation> annotationType() {
+				return this.getClass();
+			}
+		};
+		assertFalse(
+				"The constraint annotation should not be valid", ReflectionHelper.isConstraintAnnotation( annotation )
+		);
+	}
+
+	@Test
+	public void testGetMultiValueConstraints() throws Exception {
+		Engine engine = new Engine();
+		Field[] fields = engine.getClass().getDeclaredFields();
+		assertNotNull( fields );
+		assertTrue( fields.length == 1 );
+		ReflectionHelper.setAccessibility( fields[0] );
+
+		Annotation annotation = fields[0].getAnnotation( Patterns.class );
+		assertNotNull( annotation );
+		List<Annotation> multiValueConstraintAnnotations = ReflectionHelper.getMultiValueConstraints( annotation );
+		assertTrue( "There should be two constraint annotations", multiValueConstraintAnnotations.size() == 2 );
+		assertTrue( "Wrong constraint annotation", multiValueConstraintAnnotations.get( 0 ) instanceof Pattern );
+		assertTrue( "Wrong constraint annotation", multiValueConstraintAnnotations.get( 1 ) instanceof Pattern );
+
+
+		Order order = new Order();
+		fields = order.getClass().getDeclaredFields();
+		assertNotNull( fields );
+		assertTrue( fields.length == 1 );
+		ReflectionHelper.setAccessibility( fields[0] );
+
+		annotation = fields[0].getAnnotation( NotNull.class );
+		assertNotNull( annotation );
+		multiValueConstraintAnnotations = ReflectionHelper.getMultiValueConstraints( annotation );
+		assertTrue( "There should be two constraint annotations", multiValueConstraintAnnotations.size() == 0 );			
+	}
 }




More information about the hibernate-commits mailing list