Author: epbernard
Date: 2008-11-19 12:38:55 -0500 (Wed, 19 Nov 2008)
New Revision: 15600
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImplementor.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/engine/ValidationContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
validator/trunk/validation-api/src/main/java/javax/validation/Validator.java
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java
Log:
BVAL-77 Move from Validator<T> to Validator and <T> at the method level
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-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaDataProviderImpl.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -50,6 +50,7 @@
* instantiate an instance of this class and delegate the metadata extraction to it.
*
* @author Hardy Ferentschik
+ * FIXME create an interface for MetadataProvider
*/
public class MetaDataProviderImpl<T> implements MetaDataProvider<T> {
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java 2008-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidationContext.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -70,7 +70,7 @@
/**
* Stack for keep track of the currently validated object.
*/
- private Stack<Object> validatedobjectStack = new Stack<Object>();
+ private Stack<ValidatedBean> validatedobjectStack = new
Stack<ValidatedBean>();
public ValidationContext(T object) {
@@ -79,18 +79,22 @@
public ValidationContext(T rootBean, Object object) {
this.rootBean = rootBean;
- validatedobjectStack.push( object );
+ validatedobjectStack.push( new ValidatedBean(object) );
processedObjects = new HashMap<String, IdentitySet>();
propertyPath = "";
failingConstraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
}
public Object peekValidatedObject() {
- return validatedobjectStack.peek();
+ return validatedobjectStack.peek().bean;
}
+ public Class<?> peekValidatedObjectType() {
+ return validatedobjectStack.peek().beanType;
+ }
+
public void pushValidatedObject(Object validatedObject) {
- validatedobjectStack.push( validatedObject );
+ validatedobjectStack.push( new ValidatedBean(validatedObject) );
}
public void popValidatedObject() {
@@ -111,11 +115,11 @@
public void markProcessedForCurrentGroup() {
if ( processedObjects.containsKey( currentGroup ) ) {
- processedObjects.get( currentGroup ).add( validatedobjectStack.peek() );
+ processedObjects.get( currentGroup ).add( validatedobjectStack.peek().bean );
}
else {
IdentitySet set = new IdentitySet();
- set.add( validatedobjectStack.peek() );
+ set.add( validatedobjectStack.peek().bean );
processedObjects.put( currentGroup, set );
}
}
@@ -181,4 +185,21 @@
public boolean needsValidation(Set<String> groups) {
return groups.contains( currentGroup );
}
+
+ //TODO caching the object class is useful?
+ private static class ValidatedBean {
+
+ final Object bean;
+ final Class<?> beanType;
+
+ private ValidatedBean(Object bean) {
+ this.bean = bean;
+ if (bean == null) {
+ this.beanType = null;
+ }
+ else {
+ this.beanType = bean.getClass();
+ }
+ }
+ }
}
\ No newline at end of file
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImplementor.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImplementor.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorFactoryImplementor.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -0,0 +1,14 @@
+package org.hibernate.validation.engine;
+
+import javax.validation.ValidatorFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface ValidatorFactoryImplementor extends ValidatorFactory {
+ /**
+ * Gives access to the required parsed meta data.
+ * This never returns an null object
+ */
+ <T> MetaDataProviderImpl<T> getMetadataProvider(Class<T> clazz);
+}
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2008-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -27,23 +27,19 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
+import javax.validation.BeanDescriptor;
import javax.validation.ConstraintDescriptor;
-import javax.validation.ConstraintFactory;
import javax.validation.ConstraintViolation;
import javax.validation.MessageResolver;
-import javax.validation.Validator;
import javax.validation.PropertyDescriptor;
-import javax.validation.BeanDescriptor;
+import javax.validation.Validator;
-import org.hibernate.validation.Version;
import org.hibernate.validation.ValidatorConstants;
+import org.hibernate.validation.Version;
import org.hibernate.validation.impl.ConstraintDescriptorImpl;
-import org.hibernate.validation.impl.ConstraintFactoryImpl;
import org.hibernate.validation.impl.ConstraintViolationImpl;
-import org.hibernate.validation.impl.ResourceBundleMessageResolver;
-import org.hibernate.validation.util.ReflectionHelper;
import org.hibernate.validation.util.PropertyIterator;
+import org.hibernate.validation.util.ReflectionHelper;
/**
* The main Bean Validation class.
@@ -52,9 +48,9 @@
* @author Hardy Ferentschik
* @todo Make all properties transient for serializability.
*/
-public class ValidatorImpl<T> implements Validator<T> {
+public class ValidatorImpl implements Validator {
- private static final Set<Class> INDEXABLE_CLASS = new HashSet<Class>();
+ private static final Set<Class<?>> INDEXABLE_CLASS = new
HashSet<Class<?>>();
static {
INDEXABLE_CLASS.add( Integer.class );
@@ -62,46 +58,36 @@
INDEXABLE_CLASS.add( String.class );
}
+
+ //TODO move to Factory at least
static {
Version.touch();
}
- @SuppressWarnings("unchecked")
- private final List<ConstraintViolationImpl<T>> EMPTY_CONSTRAINTS_LIST =
Collections.EMPTY_LIST;
-
+ //TODO remove
/**
* A map for caching validators for cascaded entities.
*/
- private final Map<Class<?>, ValidatorImpl> subValidators = new
ConcurrentHashMap<Class<?>, ValidatorImpl>();
+ //private final Map<Class<?>, ValidatorImpl> subValidators = new
ConcurrentHashMap<Class<?>, ValidatorImpl>();
+
/**
- * Gives access to the required parsed meta data.
- */
- private final MetaDataProvider<T> metaDataProvider;
-
- /**
* Message resolver used for interpolating error messages.
*/
private final MessageResolver messageResolver;
+
+ private final ValidatorFactoryImplementor factory;
- public ValidatorImpl(Class<T> beanClass, ConstraintFactory constraintFactory,
MessageResolver messageResolver) {
- if ( beanClass == null ) {
- throw new IllegalArgumentException( "Bean class paramter cannot be null" );
- }
-
- metaDataProvider = new MetaDataProviderImpl<T>( beanClass, constraintFactory );
+ public ValidatorImpl(ValidatorFactoryImplementor factory, MessageResolver
messageResolver) {
+ this.factory = factory;
this.messageResolver = messageResolver;
}
- public ValidatorImpl(Class<T> beanClass) {
- this( beanClass, new ConstraintFactoryImpl(), new ResourceBundleMessageResolver() );
- }
-
/**
* {@inheritDoc}
*/
- public Set<ConstraintViolation<T>> validate(T object, String... groups) {
+ public <T> Set<ConstraintViolation<T>> validate(T object, String...
groups) {
if ( object == null ) {
throw new IllegalArgumentException( "Validation of a null object" );
}
@@ -123,9 +109,9 @@
* @todo Currently we iterate the cascaded fields multiple times. Maybe we should change
to an approach where we iterate the object graph only once.
* @todo Context root bean can be a different object than the current Validator<T>
hence two different generics variables
*/
- private List<ConstraintViolationImpl<T>> validate(ValidationContext<T>
context, List<String> groups) {
+ private <T> List<ConstraintViolationImpl<T>>
validate(ValidationContext<T> context, List<String> groups) {
if ( context.peekValidatedObject() == null ) {
- return EMPTY_CONSTRAINTS_LIST;
+ return Collections.emptyList();
}
// if no group is specified use the default
@@ -137,7 +123,7 @@
boolean isGroupSequence;
for ( String group : groups ) {
expandedGroups = new ArrayList<String>();
- isGroupSequence = expandGroupName( group, expandedGroups );
+ isGroupSequence = expandGroupName( context.peekValidatedObjectType(), group,
expandedGroups );
for ( String expandedGroupName : expandedGroups ) {
context.setCurrentGroup( expandedGroupName );
@@ -158,7 +144,11 @@
*
* @param context The current validation context.
*/
- private void validateConstraints(ValidationContext<T> context) {
+ private <T> void validateConstraints(ValidationContext<T> context) {
+ //casting rely on the fact that root object is at the top of the stack
+ @SuppressWarnings( "unchecked" )
+ MetaDataProviderImpl<T> metaDataProvider =
+ ( MetaDataProviderImpl<T> ) factory.getMetadataProvider(
context.peekValidatedObjectType() );
for ( MetaConstraint metaConstraint : metaDataProvider.getConstraintMetaDataList() ) {
ConstraintDescriptorImpl constraintDescriptor = metaConstraint.getDescriptor();
context.pushProperty( metaConstraint.getPropertyName() );
@@ -197,7 +187,7 @@
context.markProcessedForCurrentGroup();
}
- private void validateCascadedConstraint(ValidationContext<T> context, Type type,
Object value) {
+ private <T> void validateCascadedConstraint(ValidationContext<T> context,
Type type, Object value) {
if ( value == null ) {
return;
}
@@ -226,8 +216,8 @@
validateCascadedConstraint( context, iter );
}
- private void validateCascadedConstraints(ValidationContext<T> context) {
- List<Member> cascadedMembers = getMetaDataProvider().getCascadedMembers();
+ private <T> void validateCascadedConstraints(ValidationContext<T> context)
{
+ List<Member> cascadedMembers = factory.getMetadataProvider(
context.peekValidatedObjectType() ).getCascadedMembers();
for ( Member member : cascadedMembers ) {
Type type = ReflectionHelper.typeOf( member );
context.pushProperty( ReflectionHelper.getPropertyName( member ) );
@@ -238,7 +228,7 @@
}
}
- private void validateCascadedConstraint(ValidationContext<T> context,
Iterator<?> iter) {
+ private <T> void validateCascadedConstraint(ValidationContext<T> context,
Iterator<?> iter) {
Object actualValue;
String propertyIndex;
int i = 0;
@@ -260,10 +250,8 @@
context.replacePropertyIndex( propertyIndex );
- Class cascadedClass = actualValue.getClass();
- ValidatorImpl validatorImpl = getValidatorForClass( cascadedClass );
context.pushValidatedObject( actualValue );
- validatorImpl.validate( context, Arrays.asList( context.getCurrentGroup() ) );
+ validate( context, Arrays.asList( context.getCurrentGroup() ) );
context.popValidatedObject();
i++;
}
@@ -273,16 +261,19 @@
/**
* {@inheritDoc}
*/
- public Set<ConstraintViolation<T>> validateProperty(T object, String
propertyName, String... groups) {
+ public <T> Set<ConstraintViolation<T>> validateProperty(T object,
String propertyName, String... groups) {
List<ConstraintViolationImpl<T>> failingConstraintViolations = new
ArrayList<ConstraintViolationImpl<T>>();
validateProperty( object, new PropertyIterator( propertyName ),
failingConstraintViolations, groups );
return new HashSet<ConstraintViolation<T>>( failingConstraintViolations );
}
- private void validateProperty(T object, PropertyIterator propertyIter,
List<ConstraintViolationImpl<T>> failingConstraintViolations, String...
groups) {
- DesrciptorValueWrapper wrapper = getConstraintDescriptorAndValueForPath( this,
propertyIter, object );
+ private <T> void validateProperty(T object, PropertyIterator propertyIter,
List<ConstraintViolationImpl<T>> failingConstraintViolations, String...
groups) {
+ @SuppressWarnings( "unchecked" )
+ final Class<T> beanType = (Class<T>) object.getClass();
+ DesrciptorValueWrapper wrapper = getConstraintDescriptorAndValueForPath( beanType,
propertyIter, object );
+
if ( wrapper == null ) {
return;
}
@@ -296,7 +287,7 @@
boolean isGroupSequence;
for ( String group : groups ) {
expandedGroups = new ArrayList<String>();
- isGroupSequence = expandGroupName( group, expandedGroups );
+ isGroupSequence = expandGroupName( beanType, group, expandedGroups );
for ( String expandedGroupName : expandedGroups ) {
@@ -316,7 +307,7 @@
ConstraintViolationImpl<T> failingConstraintViolation = new
ConstraintViolationImpl<T>(
message,
object,
- ( Class<T> ) object.getClass(),
+ beanType,
object,
wrapper.value,
propertyIter.getOriginalProperty(), //FIXME use error.getProperty()
@@ -337,15 +328,15 @@
/**
* {@inheritDoc}
*/
- public Set<ConstraintViolation<T>> validateValue(String propertyName, Object
value, String... groups) {
+ public <T> Set<ConstraintViolation<T>> validateValue(Class<T>
beanType, String propertyName, Object value, String... groups) {
List<ConstraintViolationImpl<T>> failingConstraintViolations = new
ArrayList<ConstraintViolationImpl<T>>();
- validateValue( value, new PropertyIterator( propertyName ),
failingConstraintViolations, groups );
+ validateValue( beanType, value, new PropertyIterator( propertyName ),
failingConstraintViolations, groups );
return new HashSet<ConstraintViolation<T>>( failingConstraintViolations );
}
- private void validateValue(Object object, PropertyIterator propertyIter,
List<ConstraintViolationImpl<T>> failingConstraintViolations, String...
groups) {
- ConstraintDescriptorImpl constraintDescriptor = getConstraintDescriptorForPath( this,
propertyIter );
+ private <T> void validateValue(Class<T> beanType, Object object,
PropertyIterator propertyIter, List<ConstraintViolationImpl<T>>
failingConstraintViolations, String... groups) {
+ ConstraintDescriptorImpl constraintDescriptor = getConstraintDescriptorForPath(
beanType, propertyIter );
if ( constraintDescriptor == null ) {
return;
@@ -360,7 +351,7 @@
boolean isGroupSequence;
for ( String group : groups ) {
expandedGroups = new ArrayList<String>();
- isGroupSequence = expandGroupName( group, expandedGroups );
+ isGroupSequence = expandGroupName( beanType, group, expandedGroups );
for ( String expandedGroupName : expandedGroups ) {
@@ -407,18 +398,18 @@
* a constraint descriptor will be returned.
* </p>
*
- * @param validator the validator to check for constraints.
+ * @param clazz the class type to check for constraints.
* @param propertyIter an instance of <code>PropertyIterator</code>
*
* @return The constraint descriptor matching the given path.
*/
- private ConstraintDescriptorImpl getConstraintDescriptorForPath(ValidatorImpl<?>
validator, PropertyIterator propertyIter) {
+ private ConstraintDescriptorImpl getConstraintDescriptorForPath(Class<?> clazz,
PropertyIterator propertyIter) {
ConstraintDescriptorImpl matchingConstraintDescriptor = null;
propertyIter.split();
if ( !propertyIter.hasNext() ) {
- List<MetaConstraint> metaConstraintList =
validator.getMetaDataProvider().getConstraintMetaDataList();
+ List<MetaConstraint> metaConstraintList =
factory.getMetadataProvider(clazz).getConstraintMetaDataList();
for ( MetaConstraint metaConstraint : metaConstraintList ) {
ConstraintDescriptor constraintDescriptor = metaConstraint.getDescriptor();
if ( metaConstraint.getPropertyName().equals( propertyIter.getHead() ) ) {
@@ -427,7 +418,7 @@
}
}
else {
- List<Member> cascadedMembers =
validator.getMetaDataProvider().getCascadedMembers();
+ List<Member> cascadedMembers =
factory.getMetadataProvider(clazz).getCascadedMembers();
for ( Member m : cascadedMembers ) {
if ( ReflectionHelper.getPropertyName( m ).equals( propertyIter.getHead() ) ) {
Type type = ReflectionHelper.typeOf( m );
@@ -439,8 +430,7 @@
}
}
- ValidatorImpl v = getValidatorForClass( ( Class ) type );
- matchingConstraintDescriptor = v.getConstraintDescriptorForPath( v, propertyIter );
+ matchingConstraintDescriptor = getConstraintDescriptorForPath( (Class<?>)
type, propertyIter );
}
}
}
@@ -449,7 +439,7 @@
}
- private DesrciptorValueWrapper
getConstraintDescriptorAndValueForPath(ValidatorImpl<?> validator, PropertyIterator
propertyIter, Object value) {
+ private DesrciptorValueWrapper getConstraintDescriptorAndValueForPath(Class<?>
clazz, PropertyIterator propertyIter, Object value) {
DesrciptorValueWrapper wrapper = null;
propertyIter.split();
@@ -457,7 +447,7 @@
// bottom out - there is only one token left
if ( !propertyIter.hasNext() ) {
- List<MetaConstraint> metaConstraintList =
validator.getMetaDataProvider().getConstraintMetaDataList();
+ List<MetaConstraint> metaConstraintList =
factory.getMetadataProvider(clazz).getConstraintMetaDataList();
for ( MetaConstraint metaConstraint : metaConstraintList ) {
ConstraintDescriptor constraintDescriptor = metaConstraint.getDescriptor();
if ( metaConstraint.getPropertyName().equals( propertyIter.getHead() ) ) {
@@ -468,20 +458,19 @@
}
}
else {
- List<Member> cascadedMembers =
validator.getMetaDataProvider().getCascadedMembers();
+ List<Member> cascadedMembers =
factory.getMetadataProvider(clazz).getCascadedMembers();
for ( Member m : cascadedMembers ) {
if ( ReflectionHelper.getPropertyName( m ).equals( propertyIter.getHead() ) ) {
ReflectionHelper.setAccessibility( m );
- Object newValue = null;
+ Object newValue;
if ( propertyIter.isIndexed() ) {
newValue = ReflectionHelper.getValue( m, value );
}
else {
newValue = ReflectionHelper.getIndexedValue( value, propertyIter.getIndex() );
}
- ValidatorImpl cascadedValidator = getValidatorForClass( newValue.getClass() );
- wrapper = cascadedValidator.getConstraintDescriptorAndValueForPath(
- cascadedValidator, propertyIter, newValue
+ wrapper = getConstraintDescriptorAndValueForPath(
+ newValue.getClass(), propertyIter, newValue
);
}
}
@@ -491,7 +480,7 @@
}
- private void addFailingConstraint(List<ConstraintViolationImpl<T>>
failingConstraintViolations, ConstraintViolationImpl<T> failingConstraintViolation)
{
+ private <T> void addFailingConstraint(List<ConstraintViolationImpl<T>>
failingConstraintViolations, ConstraintViolationImpl<T> failingConstraintViolation)
{
int i = failingConstraintViolations.indexOf( failingConstraintViolation );
if ( i == -1 ) {
failingConstraintViolations.add( failingConstraintViolation );
@@ -505,26 +494,23 @@
/**
* @todo add child validation
*/
- public boolean hasConstraints() {
- return metaDataProvider.getConstraintMetaDataList().size() > 0;
+ public boolean hasConstraints(Class<?> clazz) {
+ return factory.getMetadataProvider( clazz ).getConstraintMetaDataList().size() > 0;
}
- public BeanDescriptor getConstraintsForClass() {
- return metaDataProvider.getBeanDescriptor();
+ public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
+ return factory.getMetadataProvider( clazz ).getBeanDescriptor();
}
- public PropertyDescriptor getConstraintsForProperty(String propertyName) {
- return metaDataProvider.getPropertyDescriptors().get( propertyName );
+ public PropertyDescriptor getConstraintsForProperty(Class<?> clazz, String
propertyName) {
+ return factory.getMetadataProvider( clazz ).getPropertyDescriptors().get( propertyName
);
}
- public Set<String> getPropertiesWithConstraints() {
- return Collections.unmodifiableSet( metaDataProvider.getPropertyDescriptors()
- .keySet() );
+ public Set<String> getPropertiesWithConstraints(Class<?> clazz) {
+ final MetaDataProviderImpl<?> dataProvider = factory.getMetadataProvider( clazz
);
+ return Collections.unmodifiableSet( dataProvider.getPropertyDescriptors().keySet() );
}
- public MetaDataProvider<T> getMetaDataProvider() {
- return metaDataProvider;
- }
/**
* Checks whether the provided group name is a group sequence and if so expands the
group name and add the expanded
@@ -536,13 +522,13 @@
*
* @return <code>true</code> if an expansion took place,
<code>false</code> otherwise.
*/
- private boolean expandGroupName(String groupName, List<String> expandedGroupNames)
{
+ private <T> boolean expandGroupName(Class<T> beanType, String groupName,
List<String> expandedGroupNames) {
if ( expandedGroupNames == null ) {
throw new IllegalArgumentException( "List cannot be empty" );
}
boolean isGroupSequence;
-
+ MetaDataProviderImpl<T> metaDataProvider = factory.getMetadataProvider( beanType
);
if ( metaDataProvider.getGroupSequences().containsKey( groupName ) ) {
expandedGroupNames.addAll( metaDataProvider.getGroupSequences().get( groupName ) );
isGroupSequence = true;
@@ -554,16 +540,6 @@
return isGroupSequence;
}
- @SuppressWarnings("unchecked")
- private <V> ValidatorImpl<V> getValidatorForClass(Class<V>
cascadedClass) {
- ValidatorImpl<V> validatorImpl = subValidators.get( cascadedClass );
- if ( validatorImpl == null ) {
- validatorImpl = new ValidatorImpl<V>( cascadedClass );
- subValidators.put( cascadedClass, validatorImpl );
- }
- return validatorImpl;
- }
-
private class DesrciptorValueWrapper {
final ConstraintDescriptorImpl descriptor;
final Object value;
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java 2008-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ValidatorFactoryImpl.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -17,6 +17,8 @@
*/
package org.hibernate.validation.impl;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import javax.validation.ConstraintFactory;
import javax.validation.MessageResolver;
import javax.validation.Validator;
@@ -24,17 +26,23 @@
import javax.validation.spi.ValidatorFactoryConfiguration;
import org.hibernate.validation.engine.ValidatorImpl;
+import org.hibernate.validation.engine.ValidatorFactoryImplementor;
+import org.hibernate.validation.engine.MetaDataProviderImpl;
/**
* @author Emmanuel Bernard
* @author Hardy Ferentschik
*/
-public class ValidatorFactoryImpl implements ValidatorFactory {
+public class ValidatorFactoryImpl implements ValidatorFactoryImplementor {
private final MessageResolver messageResolver;
private final ConstraintFactory constraintFactory;
+ //TODO is there a way to replace ? by so kind of <T> to express the correlation?
+ private Map<Class<?>, MetaDataProviderImpl<?>> metadataProviders
+ = new ConcurrentHashMap<Class<?>, MetaDataProviderImpl<?>>(10);
+
public ValidatorFactoryImpl(ValidatorFactoryConfiguration configuration) {
this.messageResolver = configuration.getMessageResolver();
this.constraintFactory = configuration.getConstraintFactory();
@@ -44,15 +52,27 @@
/**
* {@inheritDoc}
*/
- public <T> Validator<T> getValidator(Class<T> clazz) {
- return new ValidatorImpl<T>( clazz, constraintFactory, messageResolver );
+ public Validator getValidator() {
+ return new ValidatorImpl( this, messageResolver );
}
- public <T> Validator<T> getValidator(Class<T> clazz, MessageResolver
messageResolver) {
- return new ValidatorImpl<T>( clazz, constraintFactory, messageResolver );
+ public Validator getValidator(MessageResolver messageResolver) {
+ return new ValidatorImpl( this, messageResolver );
}
public MessageResolver getMessageResolver() {
return messageResolver;
}
+
+ public <T> MetaDataProviderImpl<T> getMetadataProvider(Class<T>
beanClass) {
+ //FIXME make sure a optimized mock is provided when no constraints are present.
+ if (beanClass == null) throw new IllegalArgumentException( "Class cannot be
null" );
+ @SuppressWarnings( "unchecked")
+ MetaDataProviderImpl<T> metadata = ( MetaDataProviderImpl<T> )
metadataProviders.get(beanClass);
+ if (metadata == null) {
+ metadata = new MetaDataProviderImpl<T>(beanClass, constraintFactory);
+ metadataProviders.put( beanClass, metadata );
+ }
+ return metadata;
+ }
}
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 2008-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/bootstrap/ValidationTest.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -77,7 +77,7 @@
assertDefaultBuilderAndFactory( builder );
ValidatorFactory factory = builder.build();
- Validator<Customer> validator = factory.getValidator( Customer.class );
+ Validator validator = factory.getValidator();
Customer customer = new Customer();
customer.setFirstName( "John" );
@@ -100,7 +100,7 @@
assertDefaultBuilderAndFactory( builder );
ValidatorFactory factory = builder.build();
- Validator<Customer> validator = factory.getValidator( Customer.class );
+ Validator validator = factory.getValidator( );
Customer customer = new Customer();
customer.setFirstName( "John" );
@@ -124,7 +124,7 @@
}
);
factory = builder.build();
- validator = factory.getValidator( Customer.class );
+ validator = factory.getValidator( );
constraintViolations = validator.validate( customer );
assertEquals( "Wrong number of constraints", 1, constraintViolations.size()
);
constraintViolation = constraintViolations.iterator().next();
@@ -138,7 +138,7 @@
assertDefaultBuilderAndFactory( builder );
ValidatorFactory factory = builder.build();
- Validator<Customer> validator = factory.getValidator( Customer.class );
+ Validator validator = factory.getValidator( );
Customer customer = new Customer();
customer.setFirstName( "John" );
@@ -161,7 +161,7 @@
}
);
factory = builder.build();
- validator = factory.getValidator( Customer.class );
+ validator = factory.getValidator( );
constraintViolations = validator.validate( customer );
assertEquals( "Wrong number of constraints", 0, constraintViolations.size()
);
}
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-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -22,6 +22,7 @@
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
import javax.validation.Validator;
+import javax.validation.Validation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -40,6 +41,7 @@
import org.hibernate.validation.eg.EnglishDictonary;
import org.hibernate.validation.eg.Order;
import org.hibernate.validation.eg.Unconstraint;
+import org.hibernate.validation.HibernateValidatorFactoryBuilder;
/**
* Tests for the implementation of <code>Validator</code>.
@@ -48,14 +50,27 @@
*/
public class ValidatorImplTest {
+ private Validator hibernateValidator;
+ //TODO should not be Hibernate specific in most case
+ private Validator getHibernateValidator() {
+ if (hibernateValidator == null) {
+ HibernateValidatorFactoryBuilder builder = Validation
+ .builderType( HibernateValidatorFactoryBuilder.class )
+ .getBuilder();
+ hibernateValidator = builder.build().getValidator();
+ }
+ return hibernateValidator;
+ }
+
+
/**
* JSR 303: Requirements on classes to be validates (3.1)
*/
@Test
public void testWrongMethodName() {
try {
- new ValidatorImpl<Boy>( Boy.class );
+ getHibernateValidator().hasConstraints( Boy.class );
fail();
}
catch ( ValidationException e ) {
@@ -70,36 +85,36 @@
@Test(expected = IllegalArgumentException.class)
public void testNullParamterToValidatorImplConstructor() {
- new ValidatorImpl<Unconstraint>( null );
+ getHibernateValidator().hasConstraints( null );
}
@Test
public void testUnconstraintClass() {
- Validator<Unconstraint> validator = new ValidatorImpl<Unconstraint>(
Unconstraint.class );
- assertTrue( "There should be no constraints", !validator.hasConstraints() );
+ Validator validator = getHibernateValidator();
+ assertTrue( "There should be no constraints", !validator.hasConstraints(
Unconstraint.class ) );
}
@Test
public void testHasConstraints() {
- Validator<Customer> validatorCustomer = new ValidatorImpl<Customer>(
Customer.class );
- assertTrue( "There should be constraints", validatorCustomer.hasConstraints()
);
+ Validator validator = getHibernateValidator();
+ assertTrue( "There should be constraints", validator.hasConstraints(
Customer.class ) );
}
@Test(expected = IllegalArgumentException.class)
public void testValidateWithNull() {
- Validator<Customer> validatorCustomer = new ValidatorImpl<Customer>(
Customer.class );
- validatorCustomer.validate( null );
+ Validator validator = getHibernateValidator();
+ validator.validate( null );
}
@Test(expected = IllegalArgumentException.class)
public void testValidateWithNullProperty() {
- Validator<Customer> validatorCustomer = new ValidatorImpl<Customer>(
Customer.class );
- validatorCustomer.validate( null, "firstName" );
+ Validator validator = getHibernateValidator();
+ validator.validate( null, "firstName" );
}
@Test
public void testGroups() {
- Validator<Book> validator = new ValidatorImpl<Book>( Book.class );
+ Validator validator = getHibernateValidator();
Author author = new Author();
author.setLastName( "" );
@@ -155,7 +170,7 @@
@Test
public void testDefaultGroupSequence() {
- Validator<Book> validator = new ValidatorImpl<Book>( Book.class );
+ Validator validator = getHibernateValidator();
Author author = new Author();
author.setLastName( "" );
@@ -198,7 +213,7 @@
@Test
public void testBasicValidation() {
- Validator<Customer> validator = new ValidatorImpl<Customer>( Customer.class
);
+ Validator validator = getHibernateValidator();
Customer customer = new Customer();
customer.setFirstName( "John" );
@@ -214,7 +229,7 @@
@Test
public void testGroupSequences() {
- Validator<Dictonary> validator = new ValidatorImpl<Dictonary>(
Dictonary.class );
+ Validator validator = getHibernateValidator();
Dictonary dictonary = new Dictonary();
dictonary.setTitle( "English - German" );
@@ -230,7 +245,7 @@
@Test
public void testValidationFailureInMultipleGroups() {
- Validator<Animal> validator = new ValidatorImpl<Animal>( Animal.class );
+ Validator validator = getHibernateValidator();
Animal elepfant = new Animal();
elepfant.setName( "" );
elepfant.setDomain( Animal.Domain.EUKARYOTA );
@@ -255,12 +270,13 @@
@Test(expected = ValidationException.class)
public void testInvalidSequenceName() {
- new ValidatorImpl<EnglishDictonary>( EnglishDictonary.class );
+ Validator validator = getHibernateValidator();
+ validator.hasConstraints( EnglishDictonary.class );
}
@Test
public void testValidationMethod() {
- Validator<Address> validator = new ValidatorImpl<Address>( Address.class
);
+ Validator validator = getHibernateValidator();
Address address = new Address();
address.setAddressline1( null );
@@ -288,7 +304,7 @@
constraintViolations.size()
);
- constraintViolations = validator.validateValue( "city", "Paris" );
+ constraintViolations = validator.validateValue( Address.class, "city",
"Paris" );
assertEquals(
"Paris should be a valid city name.",
0,
@@ -298,7 +314,7 @@
@Test
public void testValidateList() {
- Validator<Customer> validator = new ValidatorImpl<Customer>( Customer.class
);
+ Validator validator = getHibernateValidator();
Customer customer = new Customer();
customer.setFirstName( "John" );
@@ -326,7 +342,7 @@
*/
@Test
public void testMultiValueConstraint() {
- Validator<Engine> validator = new ValidatorImpl<Engine>( Engine.class );
+ Validator validator = getHibernateValidator();
Engine engine = new Engine();
engine.setSerialNumber( "mail(a)foobar.com" );
@@ -348,6 +364,8 @@
*/
@Test
public void testGraphValidation() {
+ Validator validator = getHibernateValidator();
+
Actor clint = new Actor( "Clint", "Eastwood" );
Actor morgan = new Actor( "Morgan", "" );
Actor charlie = new Actor( "Charlie", "Sheen" );
@@ -359,7 +377,7 @@
morgan.addPlayedWith( clint );
clint.addPlayedWith( morgan );
- Validator<Actor> validator = new ValidatorImpl<Actor>( Actor.class );
+
Set<ConstraintViolation<Actor>> constraintViolations = validator.validate(
clint );
ConstraintViolation constraintViolation = constraintViolations.iterator().next();
assertEquals( "Wrong number of constraints", 1, constraintViolations.size()
);
@@ -372,12 +390,12 @@
@Test
public void testValidateValue() {
- Validator<Customer> validator = new ValidatorImpl<Customer>( Customer.class
);
+ Validator validator = getHibernateValidator();
Order order = new Order();
Set<ConstraintViolation<Customer>> constraintViolations =
validator.validateValue(
- "orderList[0].orderNumber", null
+ Customer.class, "orderList[0].orderNumber", null
);
assertEquals( "Wrong number of constraints", 1, constraintViolations.size()
);
@@ -389,7 +407,7 @@
assertEquals( "Wrong value", order.getOrderNumber(),
constraintViolation.getInvalidValue() );
assertEquals( "Wrong propertyName", "orderList[0].orderNumber",
constraintViolation.getPropertyPath() );
- constraintViolations = validator.validateValue( "orderList[0].orderNumber",
"1234" );
+ constraintViolations = validator.validateValue( Customer.class,
"orderList[0].orderNumber", "1234" );
assertEquals( "Wrong number of constraints", 0, constraintViolations.size()
);
}
}
Modified: validator/trunk/validation-api/src/main/java/javax/validation/Validator.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/Validator.java 2008-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/validation-api/src/main/java/javax/validation/Validator.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -21,14 +21,14 @@
import java.util.Set;
/**
- * Validate a given object type.
+ * Validate objects
* Implementations of this interface must be thread-safe
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
* @todo Should Serializable be part of the definition?
*/
-public interface Validator<T> extends Serializable {
+public interface Validator extends Serializable {
/**
* validate all constraints on object
*
@@ -40,7 +40,7 @@
*
* @throws IllegalArgumentException e if object is null
*/
- Set<ConstraintViolation<T>> validate(T object, String... groups);
+ <T> Set<ConstraintViolation<T>> validate(T object, String... groups);
/**
* validate all constraints on <code>propertyName</code>
property of object
@@ -54,7 +54,7 @@
*
* @throws IllegalArgumentException e if object is null
*/
- Set<ConstraintViolation<T>> validateProperty(T object, String propertyName,
String... groups);
+ <T> Set<ConstraintViolation<T>> validateProperty(T object, String
propertyName, String... groups);
/**
* validate all constraints on <code>propertyName</code> property
@@ -69,32 +69,41 @@
*
* @return constraint violations or an empty Set if none
*/
- Set<ConstraintViolation<T>> validateValue(String propertyName, Object value,
String... groups);
+ <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType,
String propertyName, Object value, String... groups);
/**
* return true if at least one constraint declaration is present for the given bean
* or if one property is marked for validation cascade
+ *
+ * @param clazz class type evaluated
*/
- boolean hasConstraints();
+ boolean hasConstraints(Class<?> clazz);
/**
* Return the class level constraints
* The returned object (and associated objects including ConstraintDescriptors)
* are immutable.
+ *
+ * @param clazz class type evaluated
*/
- BeanDescriptor getConstraintsForClass();
+ BeanDescriptor getConstraintsForClass(Class<?> clazz);
/**
* Return the property level constraints for a given propertyName
* or null if either the property does not exist or has no constraint
* The returned object (and associated objects including ConstraintDescriptors)
* are immutable.
+ *
+ * @param clazz class type evaluated
+ * @param propertyName property evaludated
*/
- PropertyDescriptor getConstraintsForProperty(String propertyName);
+ PropertyDescriptor getConstraintsForProperty(Class<?> clazz, String
propertyName);
/**
* return the property names having at least a constraint defined
+ *
+ * @param clazz class type evaluated
*/
- Set<String> getPropertiesWithConstraints();
+ Set<String> getPropertiesWithConstraints(Class<?> clazz);
}
Modified:
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java
===================================================================
---
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java 2008-11-19
17:34:11 UTC (rev 15599)
+++
validator/trunk/validation-api/src/main/java/javax/validation/ValidatorFactory.java 2008-11-19
17:38:55 UTC (rev 15600)
@@ -26,23 +26,21 @@
*/
public interface ValidatorFactory {
/**
- * return an initialized Validator instance for the specific class.
+ * return an initialized Validator instance.
* Validator instances can be pooled and shared by the implementation
*
- * @param clazz the object class the validator validates
*/
- <T> Validator<T> getValidator(Class<T> clazz);
+ Validator getValidator();
/**
- * return an initialized Validator instance for the specific class.
+ * return an initialized Validator instance.
* Validator instances can be pooled and shared by the implementation
*
* The returned Validator instance must use the MessageResolver instance
* passed as a parameter to resolve error messages.
*
- * @param clazz the object class the validator validates
*/
- <T> Validator<T> getValidator(Class<T> clazz, MessageResolver
messageResolver);
+ Validator getValidator(MessageResolver messageResolver);
/**
* Returns the MessageResolver instance configured at initialization time