[hibernate-commits] Hibernate SVN: r17598 - validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Sep 30 16:27:36 EDT 2009


Author: hardy.ferentschik
Date: 2009-09-30 16:27:35 -0400 (Wed, 30 Sep 2009)
New Revision: 17598

Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java
Log:
HV-242

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java	2009-09-30 19:36:08 UTC (rev 17597)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConstraintTree.java	2009-09-30 20:27:35 UTC (rev 17598)
@@ -20,10 +20,10 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.ConstraintViolation;
@@ -51,7 +51,7 @@
 	private final List<ConstraintTree<?>> children;
 	private final ConstraintDescriptor<A> descriptor;
 
-	private final Map<Class<? extends ConstraintValidator<?, ?>>, ConstraintValidator<A, ?>> constraintValidatorCache;
+	private final Map<ValidatorCacheKey, ConstraintValidator<A, ?>> constraintValidatorCache;
 
 	public ConstraintTree(ConstraintDescriptor<A> descriptor) {
 		this( descriptor, null );
@@ -60,7 +60,7 @@
 	private ConstraintTree(ConstraintDescriptor<A> descriptor, ConstraintTree<?> parent) {
 		this.parent = parent;
 		this.descriptor = descriptor;
-		this.constraintValidatorCache = new HashMap<Class<? extends ConstraintValidator<?, ?>>, ConstraintValidator<A, ?>>();
+		this.constraintValidatorCache = new ConcurrentHashMap<ValidatorCacheKey, ConstraintValidator<A, ?>>();
 
 		final Set<ConstraintDescriptor<?>> composingConstraints = descriptor.getComposingConstraints();
 		children = new ArrayList<ConstraintTree<?>>( composingConstraints.size() );
@@ -174,26 +174,37 @@
 	private <V> ConstraintValidator<A, V> getInitializedValidator(Type type, ConstraintValidatorFactory constraintFactory) {
 		Class<? extends ConstraintValidator<?, ?>> validatorClass = findMatchingValidatorClass( type );
 
+		// check if we have the default validator factory. If not we don't use caching (see HV-242)
+		if(! (constraintFactory instanceof ConstraintValidatorFactoryImpl)) {
+			return createAndInitializeValidator( constraintFactory, validatorClass );
+		}
+
 		ConstraintValidator<A, V> constraintValidator;
-
-		if ( !constraintValidatorCache.containsKey( validatorClass ) ) {
-			constraintValidator = ( ConstraintValidator<A, V> ) constraintFactory.getInstance(
-					validatorClass
-			);
-			if ( constraintValidator == null ) {
-				throw new ValidationException(
-						"Constraint factory returned null when trying to create instance of " + validatorClass.getName()
-				);
-			}
-			constraintValidatorCache.put( validatorClass, constraintValidator );
+		ValidatorCacheKey key = new ValidatorCacheKey( constraintFactory, validatorClass );
+		if ( !constraintValidatorCache.containsKey( key ) ) {
+			constraintValidator = createAndInitializeValidator( constraintFactory, validatorClass );
+			constraintValidatorCache.put( key, constraintValidator );
 		}
 		else {
 			if ( log.isTraceEnabled() ) {
 				log.trace( "Constraint validator {} found in cache" );
 			}
-			constraintValidator = ( ConstraintValidator<A, V> ) constraintValidatorCache.get( validatorClass );
+			constraintValidator = ( ConstraintValidator<A, V> ) constraintValidatorCache.get( key );
 		}
+		return constraintValidator;
+	}
 
+	@SuppressWarnings("unchecked")
+	private <V> ConstraintValidator<A, V> createAndInitializeValidator(ConstraintValidatorFactory constraintFactory, Class<? extends ConstraintValidator<?, ?>> validatorClass) {
+		ConstraintValidator<A, V> constraintValidator;
+		constraintValidator = ( ConstraintValidator<A, V> ) constraintFactory.getInstance(
+				validatorClass
+		);
+		if ( constraintValidator == null ) {
+			throw new ValidationException(
+					"Constraint factory returned null when trying to create instance of " + validatorClass.getName()
+			);
+		}
 		initializeConstraint( descriptor, constraintValidator );
 		return constraintValidator;
 	}
@@ -303,4 +314,42 @@
 		sb.append( '}' );
 		return sb.toString();
 	}
+
+	private static class ValidatorCacheKey {
+		private ConstraintValidatorFactory constraintValidatorFactory;
+		private Class<? extends ConstraintValidator<?, ?>> validatorType;
+
+		private ValidatorCacheKey(ConstraintValidatorFactory constraintValidatorFactory, Class<? extends ConstraintValidator<?, ?>> validatorType) {
+			this.constraintValidatorFactory = constraintValidatorFactory;
+			this.validatorType = validatorType;
+		}
+
+		@Override
+		public boolean equals(Object o) {
+			if ( this == o ) {
+				return true;
+			}
+			if ( o == null || getClass() != o.getClass() ) {
+				return false;
+			}
+
+			ValidatorCacheKey that = ( ValidatorCacheKey ) o;
+
+			if ( constraintValidatorFactory != null ? !constraintValidatorFactory.equals( that.constraintValidatorFactory ) : that.constraintValidatorFactory != null ) {
+				return false;
+			}
+			if ( validatorType != null ? !validatorType.equals( that.validatorType ) : that.validatorType != null ) {
+				return false;
+			}
+
+			return true;
+		}
+
+		@Override
+		public int hashCode() {
+			int result = constraintValidatorFactory != null ? constraintValidatorFactory.hashCode() : 0;
+			result = 31 * result + ( validatorType != null ? validatorType.hashCode() : 0 );
+			return result;
+		}
+	}
 }



More information about the hibernate-commits mailing list