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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed May 19 12:44:40 EDT 2010


Author: hardy.ferentschik
Date: 2010-05-19 12:44:39 -0400 (Wed, 19 May 2010)
New Revision: 19561

Added:
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/Marathon.java
Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/cfg/ConstraintMapping.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
Log:
HV-274 Initial integration with ValidatorFactory (work in progress!)

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java	2010-05-19 16:21:20 UTC (rev 19560)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/HibernateValidatorConfiguration.java	2010-05-19 16:44:39 UTC (rev 19561)
@@ -19,6 +19,7 @@
 
 import javax.validation.Configuration;
 
+import org.hibernate.validator.cfg.ConstraintMapping;
 import org.hibernate.validator.resourceloading.ResourceBundleLocator;
 
 /**
@@ -62,4 +63,5 @@
 	 */
 	ResourceBundleLocator getDefaultResourceBundleLocator();
 
+	HibernateValidatorConfiguration addMapping(ConstraintMapping mapping);
 }

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/cfg/ConstraintMapping.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/cfg/ConstraintMapping.java	2010-05-19 16:21:20 UTC (rev 19560)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/cfg/ConstraintMapping.java	2010-05-19 16:44:39 UTC (rev 19561)
@@ -18,7 +18,6 @@
 package org.hibernate.validator.cfg;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -39,12 +38,13 @@
 
 	protected void addConstraintConfig(ConstraintDefinition<?> definition) {
 		Class<?> beanClass = definition.getBeanType();
-		if(configData.containsKey( beanClass )) {
+		if ( configData.containsKey( beanClass ) ) {
 			configData.get( beanClass ).add( definition );
-		} else {
+		}
+		else {
 			List<ConstraintDefinition<?>> definitionList = new ArrayList<ConstraintDefinition<?>>();
 			definitionList.add( definition );
-			configData.put(beanClass, definitionList);
+			configData.put( beanClass, definitionList );
 		}
 	}
 


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

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java	2010-05-19 16:21:20 UTC (rev 19560)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ConfigurationImpl.java	2010-05-19 16:44:39 UTC (rev 19561)
@@ -36,6 +36,7 @@
 import org.slf4j.Logger;
 
 import org.hibernate.validator.HibernateValidatorConfiguration;
+import org.hibernate.validator.cfg.ConstraintMapping;
 import org.hibernate.validator.engine.resolver.DefaultTraversableResolver;
 import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
 import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator;
@@ -46,7 +47,7 @@
 import org.hibernate.validator.xml.ValidationXmlParser;
 
 /**
- * Hibernate specific <code>Configuration</code> implementation.
+ * Hibernate specific {@code Configuration} implementation.
  *
  * @author Emmanuel Bernard
  * @author Hardy Ferentschik
@@ -72,8 +73,8 @@
 
 	private ValidationBootstrapParameters validationBootstrapParameters;
 	private boolean ignoreXmlConfiguration = false;
-
 	private Set<InputStream> configurationStreams = new HashSet<InputStream>();
+	private ConstraintMapping mapping;
 
 	public ConfigurationImpl(BootstrapState state) {
 		if ( state.getValidationProviderResolver() == null ) {
@@ -126,6 +127,7 @@
 		return this;
 	}
 
+
 	public ValidatorFactory buildValidatorFactory() {
 		parseValidationXml();
 		ValidatorFactory factory = null;
@@ -210,6 +212,15 @@
 		return defaultResourceBundleLocator;
 	}
 
+	public HibernateValidatorConfiguration addMapping(ConstraintMapping mapping) {
+		this.mapping = mapping;
+		return this;
+	}
+
+	public ConstraintMapping getMapping() {
+		return mapping;
+	}
+
 	private boolean isSpecificProvider() {
 		return validationBootstrapParameters.provider != null;
 	}

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java	2010-05-19 16:21:20 UTC (rev 19560)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validator/engine/ValidatorFactoryImpl.java	2010-05-19 16:44:39 UTC (rev 19561)
@@ -20,6 +20,7 @@
 import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Member;
+import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -34,6 +35,8 @@
 import javax.validation.ValidatorFactory;
 import javax.validation.spi.ConfigurationState;
 
+import org.hibernate.validator.cfg.ConstraintDefinition;
+import org.hibernate.validator.cfg.ConstraintMapping;
 import org.hibernate.validator.metadata.AnnotationIgnores;
 import org.hibernate.validator.metadata.BeanMetaDataCache;
 import org.hibernate.validator.metadata.BeanMetaDataImpl;
@@ -41,11 +44,15 @@
 import org.hibernate.validator.metadata.ConstraintHelper;
 import org.hibernate.validator.metadata.ConstraintOrigin;
 import org.hibernate.validator.metadata.MetaConstraint;
+import org.hibernate.validator.util.GetDeclaredField;
 import org.hibernate.validator.util.ReflectionHelper;
+import org.hibernate.validator.util.annotationfactory.AnnotationDescriptor;
+import org.hibernate.validator.util.annotationfactory.AnnotationFactory;
 import org.hibernate.validator.xml.XmlMappingParser;
 
 /**
- * Factory returning initialized <code>Validator</code> instances.
+ * Factory returning initialized <code>Validator</code> instances. This is Hibernate Validator's default
+ * implementation of the {@code ValidatorFactory} interface.
  *
  * @author Emmanuel Bernard
  * @author Hardy Ferentschik
@@ -56,6 +63,10 @@
 	private final TraversableResolver traversableResolver;
 	private final ConstraintValidatorFactory constraintValidatorFactory;
 	private final ConstraintHelper constraintHelper;
+
+	/**
+	 * Used to cache the constraint meta data for validated entities
+	 */
 	private final BeanMetaDataCache beanMetaDataCache;
 
 	public ValidatorFactoryImpl(ConfigurationState configurationState) {
@@ -66,10 +77,17 @@
 		this.constraintHelper = new ConstraintHelper();
 		this.beanMetaDataCache = new BeanMetaDataCache();
 
-		//HV-302; don't load XmlMappingParser if not necessary
+		// HV-302; don't load XmlMappingParser if not necessary
 		if ( !configurationState.getMappingStreams().isEmpty() ) {
-			initBeanMetaData( configurationState.getMappingStreams() );
+			initXmlConfiguration( configurationState.getMappingStreams() );
 		}
+
+		if ( configurationState instanceof ConfigurationImpl ) {
+			ConfigurationImpl hibernateSpecificConfig = ( ConfigurationImpl ) configurationState;
+			if ( hibernateSpecificConfig.getMapping() != null ) {
+				initProgrammaticConfiguration( hibernateSpecificConfig.getMapping() );
+			}
+		}
 	}
 
 	public Validator getValidator() {
@@ -102,23 +120,83 @@
 		);
 	}
 
-	private <T> void initBeanMetaData(Set<InputStream> mappingStreams) {
+	private <A extends Annotation, T> void initProgrammaticConfiguration(ConstraintMapping mapping) {
+		Map<Class<?>, List<ConstraintDefinition<?>>> configData = mapping.getConfigData();
+		for ( Map.Entry<Class<?>, List<ConstraintDefinition<?>>> entry : configData.entrySet() ) {
+			Map<Class<?>, List<MetaConstraint<T, ?>>> constraints = new HashMap<Class<?>, List<MetaConstraint<T, ?>>>();
+			for ( ConstraintDefinition<?> config : entry.getValue() ) {
+				AnnotationDescriptor<A> annotationDescriptor = new AnnotationDescriptor<A>(
+						( Class<A> ) config.getConstraintType()
+				);
+				for ( Map.Entry<String, Object> parameter : config.getParameters().entrySet() ) {
+					annotationDescriptor.setValue( parameter.getKey(), parameter.getValue() );
+				}
 
+				A annotation;
+				try {
+					annotation = AnnotationFactory.create( annotationDescriptor );
+				}
+				catch ( RuntimeException e ) {
+					throw new ValidationException(
+							"Unable to create annotation for configured constraint: " + e.getMessage(), e
+					);
+				}
+
+				ConstraintDescriptorImpl<A> constraintDescriptor = new ConstraintDescriptorImpl<A>(
+						annotation, constraintHelper, config.getElementType(), ConstraintOrigin.DEFINED_LOCALLY
+				);
+
+				final Member member;
+				GetDeclaredField action = GetDeclaredField.action( config.getBeanType(), config.getProperty() );
+				if ( System.getSecurityManager() != null ) {
+					member = AccessController.doPrivileged( action );
+				}
+				else {
+					member = action.run();
+				}
+				MetaConstraint<T, ?> metaConstraint = new MetaConstraint(
+						config.getBeanType(), member, constraintDescriptor
+				);
+				List<MetaConstraint<T, ?>> constraintList = new ArrayList<MetaConstraint<T, ?>>();
+				constraintList.add( metaConstraint );
+				constraints.put( config.getBeanType(), constraintList );
+
+
+				BeanMetaDataImpl<T> metaData = new BeanMetaDataImpl<T>(
+						( Class<T> ) config.getBeanType(),
+						constraintHelper,
+						new ArrayList<Class<?>>(),
+						constraints,
+						new ArrayList<Member>(),
+						new AnnotationIgnores(),
+						beanMetaDataCache
+				);
+
+				beanMetaDataCache.addBeanMetaData( ( Class<T> ) config.getBeanType(), metaData );
+			}
+		}
+	}
+
+	private <T> void initXmlConfiguration(Set<InputStream> mappingStreams) {
+
 		XmlMappingParser mappingParser = new XmlMappingParser( constraintHelper );
 		mappingParser.parse( mappingStreams );
 
-		Set<Class<?>> processedClasses = mappingParser.getProcessedClasses();
+		Set<Class<?>> xmlConfiguredClasses = mappingParser.getXmlConfiguredClasses();
 		AnnotationIgnores annotationIgnores = mappingParser.getAnnotationIgnores();
-		for ( Class<?> clazz : processedClasses ) {
+		for ( Class<?> clazz : xmlConfiguredClasses ) {
 			@SuppressWarnings("unchecked")
 			Class<T> beanClass = ( Class<T> ) clazz;
 
-			List<Class<?>> classes = new ArrayList<Class<?>>();
-			ReflectionHelper.computeClassHierarchy( beanClass, classes );
+			List<Class<?>> classes = ReflectionHelper.computeClassHierarchy( beanClass );
 			Map<Class<?>, List<MetaConstraint<T, ?>>> constraints = new HashMap<Class<?>, List<MetaConstraint<T, ?>>>();
 			List<Member> cascadedMembers = new ArrayList<Member>();
+			// we need to collect all constraints which apply for a single class. Due to constraint inheritance
+			// some constraints might be configured in super classes or interfaces. The xml configuration does not
+			// imply any order so we have to check whether any of the super classes or interfaces of a given bean has
+			// as well been configured via xml
 			for ( Class<?> classInHierarchy : classes ) {
-				if ( processedClasses.contains( classInHierarchy ) ) {
+				if ( xmlConfiguredClasses.contains( classInHierarchy ) ) {
 					addXmlConfiguredConstraints( mappingParser, beanClass, classInHierarchy, constraints );
 					addXmlCascadedMember( mappingParser, classInHierarchy, cascadedMembers );
 				}

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java	2010-05-19 16:44:39 UTC (rev 19561)
@@ -0,0 +1,106 @@
+// $Id:$
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.hibernate.validator.test.cfg;
+
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+import org.testng.annotations.Test;
+
+import org.hibernate.validator.HibernateValidator;
+import org.hibernate.validator.HibernateValidatorConfiguration;
+import org.hibernate.validator.cfg.ConstraintMapping;
+import org.hibernate.validator.cfg.MinDefinition;
+import org.hibernate.validator.cfg.NotNullDefinition;
+import org.hibernate.validator.test.util.TestUtil;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static org.hibernate.validator.test.util.TestUtil.assertConstraintViolation;
+import static org.hibernate.validator.test.util.TestUtil.assertNumberOfViolations;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ConstraintMappingTest {
+	@Test
+	public void testConstraintMapping() {
+		ConstraintMapping mapping = new ConstraintMapping();
+		mapping.type( Marathon.class )
+				.property( "name", METHOD )
+				.constraint( NotNullDefinition.class )
+				.property( "numberOfRunners", FIELD )
+				.constraint( MinDefinition.class ).value( 1 );
+
+		assertTrue( mapping.getConfigData().containsKey( Marathon.class ) );
+		assertTrue( mapping.getConfigData().get( Marathon.class ).size() == 2 );
+	}
+
+	@Test
+	public void testNoConstraintViolationForUnmappedEntity() {
+		HibernateValidatorConfiguration config = TestUtil.getConfiguration( HibernateValidator.class );
+		ValidatorFactory factory = config.buildValidatorFactory();
+		Validator validator = factory.getValidator();
+
+		Set<ConstraintViolation<Marathon>> violations = validator.validate( new Marathon() );
+		assertNumberOfViolations( violations, 0 );
+	}
+
+	@Test
+	public void testSingleConstraint() {
+		HibernateValidatorConfiguration config = TestUtil.getConfiguration( HibernateValidator.class );
+
+		ConstraintMapping mapping = new ConstraintMapping();
+		mapping.type( Marathon.class )
+				.property( "name", METHOD )
+				.constraint( NotNullDefinition.class );
+
+		config.addMapping( mapping );
+
+		ValidatorFactory factory = config.buildValidatorFactory();
+		Validator validator = factory.getValidator();
+
+		Set<ConstraintViolation<Marathon>> violations = validator.validate( new Marathon() );
+		assertNumberOfViolations( violations, 1 );
+		assertConstraintViolation( violations.iterator().next(), "may not be null" );
+	}
+
+//	@Test
+//	public void testSingleConstraintWrongAccessType() {
+//		HibernateValidatorConfiguration config = TestUtil.getConfiguration( HibernateValidator.class );
+//
+//		ConstraintMapping mapping = new ConstraintMapping();
+//		mapping.type( Marathon.class )
+//				.property( "numberOfRunners", METHOD )
+//				.constraint( NotNullDefinition.class );
+//
+//		config.addMapping( mapping );
+//
+//		ValidatorFactory factory = config.buildValidatorFactory();
+//		Validator validator = factory.getValidator();
+//
+//		Set<ConstraintViolation<Marathon>> violations = validator.validate( new Marathon() );
+//		assertNumberOfViolations( violations, 1 );
+//		assertConstraintViolation( violations.iterator().next(), "may not be null" );
+//	}
+}
+
+


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/ConstraintMappingTest.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/Marathon.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/Marathon.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/Marathon.java	2010-05-19 16:44:39 UTC (rev 19561)
@@ -0,0 +1,40 @@
+// $Id:$
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.hibernate.validator.test.cfg;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Marathon {
+	private String name;
+
+	private long numberOfRunners;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}
+
+


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validator/test/cfg/Marathon.java
___________________________________________________________________
Name: svn:keywords
   + Id



More information about the hibernate-commits mailing list