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