[hibernate-commits] Hibernate SVN: r15829 - in validator/trunk: hibernate-validator/src/main/java/org/hibernate/validation/engine and 10 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Jan 29 00:20:27 EST 2009


Author: epbernard
Date: 2009-01-29 00:20:27 -0500 (Thu, 29 Jan 2009)
New Revision: 15829

Added:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorTypeHelper.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ValidatorTypeTest.java
Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraintValidator.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraintValidator.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraintValidator.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintValidatorFactoryImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/FrenchZipcodeConstraintValidator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/GermanZipcodeConstraintValidator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/UKZipcodeConstraintValidator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoGroupsConstraintValidator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoMessageConstraintValidator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
   validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
   validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
   validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java
   validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorFactory.java
   validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java
   validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/FineGrainedLengthConstraintValidator.java
   validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/LengthConstraintValidator.java
Log:
BVAL-98 type-safe constraintValidator BVAL-97 ElementDescriptor.getConstraintDescriptors() List->Set

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/LengthConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -26,7 +26,7 @@
  * @author Emmanuel Bernard
  * @author Gavin King
  */
-public class LengthConstraintValidator implements ConstraintValidator<Length> {
+public class LengthConstraintValidator implements ConstraintValidator<Length, String> {
 	private int min;
 	private int max;
 
@@ -35,15 +35,11 @@
 		max = parameters.max();
 	}
 
-	public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
+	public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
 		if ( value == null ) {
 			return true;
 		}
-		if ( !( value instanceof String ) ) {
-			throw new IllegalArgumentException( "Expected String type." );                                                              
-		}
-		String string = ( String ) value;
-		int length = string.length();
+		int length = value.length();
 		return length >= min && length <= max;
 	}
 

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotEmptyConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -24,20 +24,16 @@
  * @author Hardy Ferentschik
  * @todo Extend to not only support strings, but also collections and maps. Needs to be specified first though.
  */
-public class NotEmptyConstraintValidator implements ConstraintValidator<NotEmpty> {
+public class NotEmptyConstraintValidator implements ConstraintValidator<NotEmpty, String> {
 
 	public void initialize(NotEmpty parameters) {
 	}
 
-	public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
+	public boolean isValid(String object, ConstraintValidatorContext constraintValidatorContext) {
 		if ( object == null ) {
 			return true;
 		}
-		if ( !( object instanceof String ) ) {
-			throw new IllegalArgumentException( "Expected String type." );
-		}
-		String string = ( String ) object;
-		int length = string.length();
+		int length = object.length();
 		return length > 0;
 	}
 }

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/NotNullConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -26,7 +26,7 @@
  *
  * @author Emmanuel Bernard
  */
-public class NotNullConstraintValidator implements ConstraintValidator<NotNull> {
+public class NotNullConstraintValidator implements ConstraintValidator<NotNull, Object> {
 
 	public void initialize(NotNull parameters) {
 	}

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/PatternConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -24,7 +24,7 @@
 /**
  * @author Hardy Ferentschik
  */
-public class PatternConstraintValidator implements ConstraintValidator<Pattern> {
+public class PatternConstraintValidator implements ConstraintValidator<Pattern, String> {
 
 	private java.util.regex.Pattern pattern;
 
@@ -35,15 +35,11 @@
 		);
 	}
 
-	public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
+	public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
 		if ( value == null ) {
 			return true;
 		}
-		if ( !( value instanceof String ) ) {
-			throw new IllegalArgumentException( "Expected String type." );
-		}
-		String string = ( String ) value;
-		Matcher m = pattern.matcher( string );
+		Matcher m = pattern.matcher( value );
 		return m.matches();
 	}
 }

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -29,7 +29,8 @@
  * @author Emmanuel Bernard
  * @author Gavin King
  */
-public class SizeConstraintValidator implements ConstraintValidator<Size> {
+//FIXME split into several type-safe validators
+public class SizeConstraintValidator implements ConstraintValidator<Size, Object> {
 	private int min;
 	private int max;
 

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -19,6 +19,7 @@
 
 import java.util.List;
 import java.util.ArrayList;
+import java.lang.annotation.Annotation;
 import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintDescriptor;
 import javax.validation.ValidationException;
@@ -56,7 +57,7 @@
 		this.descriptor = descriptor;
 		this.constraintValidatorFactory = constraintValidatorFactory;
 		this.messageInterpolator = messageInterpolator;
-		this.constraintValidator = getConstraint( descriptor );
+		this.constraintValidator = getConstraintValidator( descriptor );
 		children = new ArrayList<ConstraintTree>( descriptor.getComposingConstraints().size() );
 
 		for ( ConstraintDescriptor composingDescriptor : descriptor.getComposingConstraints() ) {
@@ -142,15 +143,15 @@
 		validationContext.addConstraintFailure( failingConstraintViolation );
 	}
 
-	@SuppressWarnings("unchecked")
-	private ConstraintValidator getConstraint(ConstraintDescriptor descriptor) {
+	private ConstraintValidator getConstraintValidator(ConstraintDescriptor descriptor) {
 		ConstraintValidator constraintValidator;
 		try {
-			//unchecked
-			constraintValidator = constraintValidatorFactory.getInstance( descriptor.getConstraintValidatorClass() );
+			//FIXME do choose the right validator depending on the object validated
+			constraintValidator = constraintValidatorFactory.getInstance( descriptor.getConstraintValidatorClasses()[0] );
 		}
 		catch ( RuntimeException e ) {
-			throw new ValidationException( "Unable to instantiate " + descriptor.getConstraintValidatorClass(), e );
+			//FIXME do choose the right validator depending on the object validated
+			throw new ValidationException( "Unable to instantiate " + descriptor.getConstraintValidatorClasses()[0], e );
 		}
 
 		try {

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -49,20 +49,20 @@
  * @author Emmanuel Bernard
  * @author Hardy Ferentschik
  */
-public class ConstraintDescriptorImpl implements ConstraintDescriptor {
+public class ConstraintDescriptorImpl<U extends Annotation> implements ConstraintDescriptor {
 	private static final Logger log = LoggerFactory.make();
 	private static final Class<?>[] DEFAULT_GROUP = new Class<?>[] { Default.class };
 	private static final int OVERRIDES_PARAMETER_DEFAULT_INDEX = -1;
 
-	private final Annotation annotation;
-	private final Class<? extends ConstraintValidator> constraintClass;
+	private final U annotation;
+	private final Class<? extends ConstraintValidator<U,?>>[] constraintClasses;
 	private final Set<Class<?>> groups;
 	private final Map<String, Object> parameters;
 	private final Set<ConstraintDescriptor> composingConstraints = new HashSet<ConstraintDescriptor>();
 	private final Map<ClassIndexWrapper, Map<String, Object>> overrideParameters = new HashMap<ClassIndexWrapper, Map<String, Object>>();
 	private final boolean isReportAsSingleInvalidConstraint;
 
-	public ConstraintDescriptorImpl(Annotation annotation, Class<?>[] groups) {
+	public ConstraintDescriptorImpl(U annotation, Class<?>[] groups) {
 		this( annotation, new HashSet<Class<?>>() );
 		if ( groups.length == 0 ) {
 			groups = DEFAULT_GROUP;
@@ -70,7 +70,7 @@
 		this.groups.addAll( Arrays.asList( groups ) );
 	}
 
-	public ConstraintDescriptorImpl(Annotation annotation, Set<Class<?>> groups) {
+	public ConstraintDescriptorImpl(U annotation, Set<Class<?>> groups) {
 		this.annotation = annotation;
 		this.groups = groups;
 		this.parameters = getAnnotationParameters( annotation );
@@ -81,12 +81,14 @@
 
 
 		if ( ReflectionHelper.isBuiltInConstraintAnnotation( annotation ) ) {
-			this.constraintClass = ReflectionHelper.getBuiltInConstraint( annotation );
+			this.constraintClasses = (Class<? extends ConstraintValidator<U,?>>[])
+					ReflectionHelper.getBuiltInConstraints( annotation );
 		}
 		else {
 			Constraint constraint = annotation.annotationType()
 					.getAnnotation( Constraint.class );
-			this.constraintClass = constraint.validatedBy();
+			this.constraintClasses = (Class<? extends ConstraintValidator<U,?>>[])
+					constraint.validatedBy();
 		}
 
 		parseOverrideParameters();
@@ -96,7 +98,7 @@
 	/**
 	 * {@inheritDoc}
 	 */
-	public Annotation getAnnotation() {
+	public U getAnnotation() {
 		return annotation;
 	}
 
@@ -110,8 +112,9 @@
 	/**
 	 * {@inheritDoc}
 	 */
-	public Class<? extends ConstraintValidator> getConstraintValidatorClass() {
-		return constraintClass;
+	public Class<? extends ConstraintValidator<U,?>>[]
+			getConstraintValidatorClasses() {
+		return constraintClasses;
 	}
 
 	/**
@@ -139,7 +142,7 @@
 	public String toString() {
 		return "ConstraintDescriptorImpl{" +
 				"annotation=" + annotation +
-				", constraintClass=" + constraintClass +
+				", constraintClasses=" + constraintClasses +
 				", groups=" + groups +
 				", parameters=" + parameters +
 				", composingConstraints=" + composingConstraints +

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintValidatorFactoryImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintValidatorFactoryImpl.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintValidatorFactoryImpl.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -17,6 +17,7 @@
 */
 package org.hibernate.validation.impl;
 
+import java.lang.annotation.Annotation;
 import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.ValidationException;
@@ -31,7 +32,7 @@
 	/**
 	 * {@inheritDoc}
 	 */
-	public <T extends ConstraintValidator> T getInstance(Class<T> key) {
+	public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
 		try {
 			return key.newInstance();
 		}

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ElementDescriptorImpl.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -21,6 +21,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
 import javax.validation.ConstraintDescriptor;
 import javax.validation.ElementDescriptor;
 import javax.validation.BeanDescriptor;
@@ -38,7 +40,7 @@
 public class ElementDescriptorImpl implements PropertyDescriptor {
 	private final Class<?> returnType;
 	private final boolean cascaded;
-	private final List<ConstraintDescriptor> constraintDescriptors = new ArrayList<ConstraintDescriptor>();
+	private final Set<ConstraintDescriptor> constraintDescriptors = new HashSet<ConstraintDescriptor>();
 	private final String propertyPath;
 
 
@@ -75,8 +77,8 @@
 	/**
 	 * {@inheritDoc}
 	 */
-	public List<ConstraintDescriptor> getConstraintDescriptors() {
-		return Collections.unmodifiableList( constraintDescriptors );
+	public Set<ConstraintDescriptor> getConstraintDescriptors() {
+		return Collections.unmodifiableSet( constraintDescriptors );
 	}
 
 	/**

Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorTypeHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorTypeHelper.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorTypeHelper.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -0,0 +1,112 @@
+package org.hibernate.validation.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.HashMap;
+import java.util.Map;
+import javax.validation.ConstraintValidator;
+import javax.validation.ValidationException;
+
+
+/**
+ * Helper methods around ConstraintValidator types
+ */
+public class ValidatorTypeHelper {
+	private static final int VALIDATOR_TYPE_INDEX = 1;
+
+	/**
+	 * for a lsit of validators, return a Map<Class, Class&lt;? extends ConstraintValidator&gt;&gt;
+	 * The key is the type the validator accepts, the value is the validator class itself
+
+	 */
+	public static Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>>
+	    getValidatorsTypes(Class<? extends ConstraintValidator<? extends Annotation,?>>[] validators) {
+		if (validators == null || validators.length == 0) {
+			//TODObe more contextually specific
+			throw new ValidationException("No ConstraintValidators associated to @Constraint");
+		}
+		else {
+			Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>> validatorsTypes =
+					new HashMap<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>>();
+			for (Class<? extends ConstraintValidator<? extends Annotation,?>> validator : validators) {
+				validatorsTypes.put( extractType(validator), validator );
+			}
+			return validatorsTypes;
+		}
+	}
+
+	private static Class<?> extractType(Class<? extends ConstraintValidator<?,?>> validator) {
+
+		Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
+		Type constraintValidatorType = resolveTypes(resolvedTypes, validator);
+
+		//we now have all bind from a type to its resolution at one level
+
+		//FIXME throw assertion exception if constraintValidatorType == null
+		Type validatorType = ( (ParameterizedType) constraintValidatorType ).getActualTypeArguments()[VALIDATOR_TYPE_INDEX];
+		while ( resolvedTypes.containsKey( validatorType ) ) {
+			validatorType = resolvedTypes.get( validatorType );
+		}
+		//FIXME raise an exception if validatorType is not a class
+		return (Class<?>) validatorType;
+	}
+
+	//TEst method, remove
+	public static Type extractTypeLoose(Class<? extends ConstraintValidator<?,?>> validator) {
+
+		Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
+		Type constraintValidatorType = resolveTypes(resolvedTypes, validator);
+
+		//we now have all bind from a type to its resolution at one level
+
+		//FIXME throw assertion exception if constraintValidatorType == null
+		Type validatorType = ( (ParameterizedType) constraintValidatorType ).getActualTypeArguments()[VALIDATOR_TYPE_INDEX];
+		while ( resolvedTypes.containsKey( validatorType ) ) {
+			validatorType = resolvedTypes.get( validatorType );
+		}
+		//FIXME raise an exception if validatorType is not a class
+		return validatorType;
+	}
+
+	private static Type resolveTypes(Map<Type, Type> resolvedTypes, Type type) {
+		if (type == null) {
+			return null;
+		}
+		else if ( type instanceof Class ) {
+			Class<?> clazz = ( Class<?> ) type;
+			Type returnedType = resolveTypes(resolvedTypes, clazz.getGenericSuperclass() );
+			if (returnedType != null) return returnedType;
+			for (Type genericInterface : clazz.getGenericInterfaces() ) {
+				returnedType = resolveTypes(resolvedTypes, genericInterface );
+				if (returnedType != null) return returnedType;
+			}
+		}
+		else if ( type instanceof ParameterizedType ) {
+			ParameterizedType paramType = (ParameterizedType) type;
+			if ( ! ( paramType.getRawType() instanceof Class ) ) return null; //don't know what to do here
+			Class<?> rawType = (Class<?>) paramType.getRawType();
+
+			TypeVariable<?>[] originalTypes = rawType.getTypeParameters();
+			Type[] partiallyResolvedTypes = paramType.getActualTypeArguments();
+			int nbrOfParams = originalTypes.length;
+			for (int i = 0 ; i < nbrOfParams; i++) {
+				resolvedTypes.put( originalTypes[i], partiallyResolvedTypes[i] );
+			}
+
+			if ( rawType.equals( ConstraintValidator.class ) ) {
+				//we found our baby
+				return type;
+			}
+			else {
+				resolveTypes(resolvedTypes, rawType.getGenericSuperclass() );
+				for (Type genericInterface : rawType.getGenericInterfaces() ) {
+					resolveTypes(resolvedTypes, genericInterface );
+				}
+			}
+		}
+		//else we don't care I think
+		return null;
+	}
+}

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-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -70,8 +70,10 @@
 	private ReflectionHelper() {
 	}
 
-
-	public static Class<? extends ConstraintValidator> getBuiltInConstraint(Annotation annotation) {
+	@SuppressWarnings( "unchecked")
+	//FIXME do make it truely multivalidators
+	//FIXME don't rely on properties files, what's the point
+	public static Class<? extends ConstraintValidator<?,?>>[] getBuiltInConstraints(Annotation annotation) {
 		Class constraint = null;
 		String annotationType = annotation.annotationType().getName();
 		if ( builtInConstraints.containsKey( annotationType ) ) {
@@ -87,7 +89,7 @@
 			}
 
 		}
-		return constraint;
+		return new Class[] {constraint};
 	}
 
 	/**

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -21,6 +21,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.Locale;
+import java.lang.annotation.Annotation;
 import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintDescriptor;
 import javax.validation.ConstraintValidatorFactory;
@@ -152,9 +153,11 @@
 		// now we modify the configuration, get a new factory and valiator and try again
 		configuration.constraintValidatorFactory(
 				new ConstraintValidatorFactory() {
-					public <T extends ConstraintValidator> T getInstance(Class<T> key) {
+
+					public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
 						if ( key == NotNullConstraintValidator.class ) {
-							return ( T ) new BadlyBehavedNotNullConstraintValidator();
+							T result = ( T ) new BadlyBehavedNotNullConstraintValidator();
+							return result;
 						}
 						return new ConstraintValidatorFactoryImpl().getInstance( key );
 					}

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/LengthConstraintTest.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -77,15 +77,4 @@
 
 	}
 
-	@Test
-	@SpecAssertion(section = "2.1", note = "Incompatible type cause runtime error")
-	public void testIncompatibleType() {
-		try {
-			constraint.isValid( new Object(), null );
-			fail();
-		}
-		catch ( IllegalArgumentException e ) {
-			// success
-		}
-	}
 }

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/NotEmptyConstraintTest.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -46,16 +46,4 @@
 
 		assertFalse( constraint.isValid( "", null ) );
 	}
-
-	@Test
-	@SpecAssertion(section = "2.1", note = "Incompatible type cause runtime error")
-	public void testIncompatibleType() {
-		try {
-			constraint.isValid( new Object(), null );
-			fail();
-		}
-		catch ( IllegalArgumentException e ) {
-			// success
-		}
-	}
 }

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/PatternConstraintTest.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -70,25 +70,6 @@
 		assertFalse( constraint.isValid( "", null ) );
 		assertFalse( constraint.isValid( "bla bla", null ) );
 		assertFalse( constraint.isValid( "This test is not foobar", null ) );
-
-		try {
-			constraint.isValid( new Object(), null );
-			fail();
-		}
-		catch ( IllegalArgumentException e ) {
-			// success
-		}
 	}
 
-	@Test
-	@SpecAssertion(section = "2.1", note = "Incompatible type cause runtime error")
-	public void testIncompatibleType() {
-		try {
-			constraint.isValid( new Object(), null );
-			fail();
-		}
-		catch ( IllegalArgumentException e ) {
-			// success
-		}
-	}
 }

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/FrenchZipcodeConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/FrenchZipcodeConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/FrenchZipcodeConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -23,12 +23,12 @@
 /**
  * @author Hardy Ferentschik
  */
-public class FrenchZipcodeConstraintValidator implements ConstraintValidator<FrenchZipcode> {
+public class FrenchZipcodeConstraintValidator implements ConstraintValidator<FrenchZipcode, String> {
 
 	public void initialize(FrenchZipcode parameters) {
 	}
 
-	public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
+	public boolean isValid(String object, ConstraintValidatorContext constraintValidatorContext) {
 		return true;
 	}
 }

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/GermanZipcodeConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/GermanZipcodeConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/GermanZipcodeConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -23,12 +23,12 @@
 /**
  * @author Hardy Ferentschik
  */
-public class GermanZipcodeConstraintValidator implements ConstraintValidator<GermanZipcode> {
+public class GermanZipcodeConstraintValidator implements ConstraintValidator<GermanZipcode, String> {
 
 	public void initialize(GermanZipcode parameters) {
 	}
 
-	public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
+	public boolean isValid(String object, ConstraintValidatorContext constraintValidatorContext) {
 		return true;
 	}
 }
\ No newline at end of file

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/UKZipcodeConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/UKZipcodeConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/UKZipcodeConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -23,12 +23,12 @@
 /**
  * @author Hardy Ferentschik
  */
-public class UKZipcodeConstraintValidator implements ConstraintValidator<UKZipcode> {
+public class UKZipcodeConstraintValidator implements ConstraintValidator<UKZipcode, String> {
 
 	public void initialize(UKZipcode parameters) {
 	}
 
-	public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
+	public boolean isValid(String object, ConstraintValidatorContext constraintValidatorContext) {
 		return false;
 	}
 }
\ No newline at end of file

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoGroupsConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoGroupsConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoGroupsConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -25,7 +25,7 @@
 /**
  * @author Hardy Ferentschik
  */
-public class NoGroupsConstraintValidator implements ConstraintValidator<NoGroups> {
+public class NoGroupsConstraintValidator implements ConstraintValidator<NoGroups, Object> {
 
 	public void initialize(NoGroups parameters) {
 	}

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoMessageConstraintValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoMessageConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/incomplete/NoMessageConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -23,7 +23,7 @@
 /**
  * @author Hardy Ferentschik
  */
-public class NoMessageConstraintValidator implements ConstraintValidator<NoMessage> {
+public class NoMessageConstraintValidator implements ConstraintValidator<NoMessage, Object> {
 
 	public void initialize(NoMessage parameters) {
 	}

Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ValidatorTypeTest.java (from rev 15817, validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ResourceBundleMessageInterpolatorTest.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ValidatorTypeTest.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ValidatorTypeTest.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -0,0 +1,74 @@
+// $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.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.NotNull;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+import org.hibernate.validation.constraints.composition.FrenchZipcodeConstraintValidator;
+
+/**
+ * Tests for message resolution.
+ *
+ * @author Emmanuel Bernard
+ */
+public class ValidatorTypeTest {
+
+	@Test
+	public void testTypeDiscovery() {
+		Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>> validatorsTypes = ValidatorTypeHelper
+				.getValidatorsTypes( new Class[] { FrenchZipcodeConstraintValidator.class } );
+		assertEquals( FrenchZipcodeConstraintValidator.class, validatorsTypes.get( String.class ) );
+
+		Type type = ValidatorTypeHelper
+				.extractTypeLoose( TestValidator.class );
+
+
+		Type type2 = ValidatorTypeHelper
+				.extractTypeLoose( TestValidator2.class  );
+		assertEquals( type, type2 );
+
+	}
+
+	public static class TestValidator implements ConstraintValidator<NotNull, Set<String>> {
+		public void initialize(NotNull constraintAnnotation) {
+			//To change body of implemented methods use File | Settings | File Templates.
+		}
+
+		public boolean isValid(Set<String> object, ConstraintValidatorContext constraintValidatorContext) {
+			return false;  //To change body of implemented methods use File | Settings | File Templates.
+		}
+}
+
+	public static class TestValidator2 implements ConstraintValidator<NotNull, Set<String>> {
+		public void initialize(NotNull constraintAnnotation) {
+		}
+
+		public boolean isValid(Set<String> object, ConstraintValidatorContext constraintValidatorContext) {
+			return true;
+		}
+	}
+}
\ No newline at end of file


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/impl/ValidatorTypeTest.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:mergeinfo
   + 

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -88,7 +88,7 @@
 		assertEquals(
 				"Wrong constraint error Type",
 				constraintType,
-				violation.getConstraintDescriptor().getConstraintValidatorClass()
+				violation.getConstraintDescriptor().getConstraintValidatorClasses()[0]
 		);
 		assertConstraintViolation( violation, errorMessage );
 	}

Modified: validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -22,13 +22,14 @@
 import java.lang.annotation.Retention;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 import java.lang.annotation.Target;
+import java.lang.annotation.Annotation;
 
 
 /**
- * Link between a constraint annotation and it's constraint validation implementation.
+ * Link between a constraint annotation and its constraint validation implementations.
  * <p/>
- * An given constraint annotation should be annotated by a @ConstraintValidator
- * annotation which refers to its constraint validation implementation.
+ * A given constraint annotation should be annotated by a @Constraint
+ * annotation which refers to its list of constraint validation implementation.
  *
  * @author Emmanuel Bernard (emmanuel at hibernate.org)
  * @author Gavin King
@@ -39,7 +40,10 @@
 @Retention(RUNTIME)
 public @interface Constraint {
 	/**
-	 * @return The class implementing the constraint validation logic
+	 * ConstraintValidator classes must reference distinct target types.
+	 * If two validators refer to the same type, an exception will occur
+	 * 
+	 * @return aray of ConstraintValidator classes implementing the constraint
 	 */
-	public Class<? extends ConstraintValidator> validatedBy();
+	public Class<? extends ConstraintValidator<?,?>>[] validatedBy();
 }
\ No newline at end of file

Modified: validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -45,7 +45,8 @@
 	/**
 	 * @return the constraint validation implementation class
 	 */
-	Class<? extends ConstraintValidator> getConstraintValidatorClass();
+	Class<? extends ConstraintValidator<?,?>>[]
+	    getConstraintValidatorClasses();
 
 	/**
 	 * Returns a map containing the annotation parameter names as keys and the
@@ -73,4 +74,4 @@
 	 * @return true if the constraint is annotated with @ReportAsViolationFromCompositeConstraint
 	 */
 	boolean isReportAsViolationFromCompositeConstraint();
-}
+}
\ No newline at end of file

Modified: validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -20,12 +20,15 @@
 import java.lang.annotation.Annotation;
 
 /**
- * Define the logic to validate a given constraint.
+ * Defines the logic to validate a given constraint A
+ * for a given object type T.
+ * Implementations must comply to the following restriction:
+ * T must resolve to a non parameterized type
  *
  * @author Emmanuel Bernard
  * @author Hardy Ferentschik
  */
-public interface ConstraintValidator<A extends Annotation> {
+public interface ConstraintValidator<A extends Annotation, T> {
 	/**
 	 * Validator parameters for a given constraint definition
 	 * Annotations parameters are passed as key/value into parameters
@@ -46,6 +49,6 @@
 	 *
 	 * @return false if <code>object</code> does not pass the constraint
 	 */
-	boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext);
+	boolean isValid(T object, ConstraintValidatorContext constraintValidatorContext);
 }
  
\ No newline at end of file

Modified: validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorFactory.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorFactory.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorFactory.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -19,7 +19,8 @@
 
 /**
  * Instantiate a <code>ConstraintValidator</code> instance from its class.
- * The <code>ConstraintValidatorFactory</code> is <b>not</b> responsible for calling {@link ConstraintValidator#initialize(java.lang.annotation.Annotation)}.
+ * The <code>ConstraintValidatorFactory</code> is <b>not</b> responsible
+ * for calling {@link ConstraintValidator#initialize(java.lang.annotation.Annotation)}.
  *
  * @author Dhanji R. Prasanna
  * @author Emmanuel Bernard
@@ -32,5 +33,5 @@
 	 *
 	 * @return An constraint validator instance of the specified class.
 	 */
-	<T extends ConstraintValidator> T getInstance(Class<T> key);
+	<T extends ConstraintValidator<?,?>> T getInstance(Class<T> key);
 }

Modified: validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ElementDescriptor.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -17,8 +17,7 @@
 */
 package javax.validation;
 
-import java.lang.annotation.ElementType;
-import java.util.List;
+import java.util.Set;
 
 /**
  * Describes a validated element (class, field or property).
@@ -43,6 +42,5 @@
 	/**
 	 * @return All the constraint descriptors for this element.
 	 */
-	List<ConstraintDescriptor> getConstraintDescriptors();
-
+	Set<ConstraintDescriptor> getConstraintDescriptors();
 }

Modified: validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/FineGrainedLengthConstraintValidator.java
===================================================================
--- validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/FineGrainedLengthConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/FineGrainedLengthConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -9,7 +9,7 @@
  *  - constraint.length.min if the min limit is reached
  *  - constraint.length.max if the max limit is reached
  */
-public class FineGrainedLengthConstraintValidator implements ConstraintValidator<Length> {
+public class FineGrainedLengthConstraintValidator implements ConstraintValidator<Length, String> {
     private int min;
     private int max;
 
@@ -28,13 +28,9 @@
      * returns false if the specified value does not conform to the definition
      * @exception IllegalArgumentException if the object is not of type String
      */
-    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
+    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
         if ( value == null ) return true;
-        if ( !( value instanceof String ) ) {
-            throw new IllegalArgumentException("Expected String type");
-        }
-        String string = (String) value;
-        int length = string.length();
+         int length = value.length();
 
 		//remove default error
 		constraintValidatorContext.disableDefaultError();

Modified: validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/LengthConstraintValidator.java
===================================================================
--- validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/LengthConstraintValidator.java	2009-01-28 17:26:47 UTC (rev 15828)
+++ validator/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s2/s4/LengthConstraintValidator.java	2009-01-29 05:20:27 UTC (rev 15829)
@@ -7,7 +7,7 @@
  * Check that a string length is between min and max
  *
  */
-public class LengthConstraintValidator implements ConstraintValidator<Length> {
+public class LengthConstraintValidator implements ConstraintValidator<Length, String> {
     private int min;
     private int max;
 
@@ -26,13 +26,10 @@
      * returns false if the specified value does not conform to the definition
      * @exception IllegalArgumentException if the object is not of type String
      */
-    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
+    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
         if ( value == null ) return true;
-        if ( !( value instanceof String ) ) {
-            throw new IllegalArgumentException("Expected String type");
-        }
-        String string = (String) value;
-        int length = string.length();
+
+        int length = value.length();
         return length >= min && length <= max;
     }
 }




More information about the hibernate-commits mailing list