Author: hardy.ferentschik
Date: 2009-03-18 09:45:24 -0400 (Wed, 18 Mar 2009)
New Revision: 16182
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java
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/ExecutionContext.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java
Log:
HV-126 Code refactoring and some more tests.
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-03-18
11:16:04 UTC (rev 16181)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-03-18
13:45:24 UTC (rev 16182)
@@ -29,6 +29,7 @@
import javax.validation.ConstraintValidatorFactory;
import javax.validation.UnexpectedTypeException;
import javax.validation.ValidationException;
+import javax.validation.ConstraintViolation;
import com.googlecode.jtype.TypeUtils;
import org.slf4j.Logger;
@@ -101,7 +102,7 @@
* @param <T> Type of the root bean for the current validation.
* @param <V> Type of the value to be validated.
*/
- public <T, V> void validateConstraints(V value, Type type,
ExecutionContext<T> executionContext, List<ConstraintViolationImpl<T>>
constraintViolations) {
+ public <T, V> void validateConstraints(V value, Type type,
ExecutionContext<T> executionContext, List<ConstraintViolation<T>>
constraintViolations) {
for ( ConstraintTree<?> tree : getChildren() ) {
tree.validateConstraints( value, type, executionContext, constraintViolations );
}
@@ -112,16 +113,18 @@
ConstraintValidator<A, V> validator = getInitalizedValidator(
value, type, executionContext.getConstraintValidatorFactory()
);
- executionContext.setCurrentConstraintDescriptor( descriptor );
- if ( !validator.isValid( value, executionContext ) ) {
- constraintViolations.addAll( executionContext.createConstraintViolations( value ) );
+ ConstraintValidatorContextImpl constraintValidatorContext = new
ConstraintValidatorContextImpl(
+ executionContext.peekParentPath(), executionContext.peekProperty(), descriptor
+ );
+ if ( !validator.isValid( value, constraintValidatorContext ) ) {
+ constraintViolations.addAll( executionContext.createConstraintViolations( value,
constraintValidatorContext ) );
}
if ( reportAsSingleViolation() && constraintViolations.size() > 0 ) {
constraintViolations.clear();
final String message = ( String ) getParent().getDescriptor().getAttributes().get(
"message" );
final String property = executionContext.peekPropertyPath();
- ExecutionContext<T>.ErrorMessage error = executionContext.new ErrorMessage(
message, property );
- constraintViolations.add( executionContext.createConstraintViolation( value, error )
);
+ ConstraintValidatorContextImpl.ErrorMessage error = constraintValidatorContext.new
ErrorMessage( message, property );
+ constraintViolations.add( executionContext.createConstraintViolation( value, error,
descriptor ) );
}
}
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java
(rev 0)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java 2009-03-18
13:45:24 UTC (rev 16182)
@@ -0,0 +1,106 @@
+// $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.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class ConstraintValidatorContextImpl implements ConstraintValidatorContext {
+
+ private final List<ErrorMessage> errorMessages = new
ArrayList<ErrorMessage>( 3 );
+ private final String property;
+ private final String propertyParent;
+ private final ConstraintDescriptor<?> constraintDescriptor;
+ private boolean defaultDisabled;
+
+
+ public ConstraintValidatorContextImpl(String propertyParent, String property,
ConstraintDescriptor<?> constraintDescriptor) {
+ this.property = property;
+ this.propertyParent = propertyParent;
+ this.constraintDescriptor = constraintDescriptor;
+ }
+
+ public void disableDefaultError() {
+ defaultDisabled = true;
+ }
+
+ public String getDefaultErrorMessage() {
+ return ( String ) constraintDescriptor.getAttributes().get( "message" );
+ }
+
+ public void addError(String message) {
+ errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent,
property ) ) );
+ }
+
+ public void addError(String message, String property) {
+ errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent,
property ) ) );
+ }
+
+ public ConstraintDescriptor<?> getConstraintDescriptor() {
+ return constraintDescriptor;
+ }
+
+ public boolean isDefaultErrorDisabled() {
+ return defaultDisabled;
+ }
+
+ public List<ErrorMessage> getErrorMessages() {
+ List<ErrorMessage> returnedErrorMessages = new ArrayList<ErrorMessage>(
errorMessages );
+ if ( !defaultDisabled ) {
+ returnedErrorMessages.add(
+ new ErrorMessage( getDefaultErrorMessage(), buildPropertyPath( propertyParent,
property ) )
+ );
+ }
+ return returnedErrorMessages;
+ }
+
+ private String buildPropertyPath(String parent, String leaf) {
+ if ( ExecutionContext.PROPERTY_ROOT.equals( parent ) ) {
+ return leaf;
+ }
+ else {
+ return new StringBuilder().append( parent )
+ .append( ExecutionContext.PROPERTY_PATH_SEPERATOR )
+ .append( leaf )
+ .toString();
+ }
+ }
+
+ public class ErrorMessage {
+ private final String message;
+ private final String property;
+
+ public ErrorMessage(String message, String property) {
+ this.message = message;
+ this.property = property;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+ }
+}
Property changes on:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintValidatorContextImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-03-18
11:16:04 UTC (rev 16181)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ExecutionContext.java 2009-03-18
13:45:24 UTC (rev 16182)
@@ -26,10 +26,10 @@
import java.util.Set;
import java.util.Stack;
import javax.validation.ConstraintDescriptor;
-import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
+import javax.validation.ConstraintViolation;
import org.hibernate.validation.util.IdentitySet;
@@ -42,11 +42,11 @@
* @todo Look for ways to improve this data structure. It is quite fragile and depends on
the right oder of calls
* in order to work.
*/
-public class ExecutionContext<T> implements ConstraintValidatorContext {
+public class ExecutionContext<T> {
- private static final String PROPERTY_ROOT = "";
+ public static final String PROPERTY_ROOT = "";
- private static final String PROPERTY_PATH_SEPERATOR = ".";
+ public static final String PROPERTY_PATH_SEPERATOR = ".";
/**
* The root bean of the validation.
@@ -67,7 +67,7 @@
/**
* A list of all failing constraints so far.
*/
- private final List<ConstraintViolationImpl<T>> failingConstraintViolations;
+ private final List<ConstraintViolation<T>> failingConstraintViolations;
/**
* The current property based based from the root bean.
@@ -80,12 +80,6 @@
private Class<?> currentGroup;
/**
- * Reference to a <code>ValidatedProperty</code> keeping track of the
property we are currently validating,
- * together with required meta data.
- */
- private ValidatedProperty currentValidatedProperty;
-
- /**
* Stack for keeping track of the currently validated bean.
*/
private Stack<Object> beanStack = new Stack<Object>();
@@ -126,38 +120,13 @@
processedObjects = new HashMap<Class<?>, IdentitySet>();
processedPaths = new IdentityHashMap<Object, Set<String>>();
propertyPath = new ArrayList<String>();
- failingConstraintViolations = new ArrayList<ConstraintViolationImpl<T>>();
+ failingConstraintViolations = new ArrayList<ConstraintViolation<T>>();
}
public ConstraintValidatorFactory getConstraintValidatorFactory() {
return constraintValidatorFactory;
}
- public void disableDefaultError() {
- assert currentValidatedProperty != null;
- currentValidatedProperty.disableDefaultError();
- }
-
- public String getDefaultErrorMessage() {
- assert currentValidatedProperty != null;
- return currentValidatedProperty.getDefaultErrorMessage();
- }
-
- public void addError(String message) {
- assert currentValidatedProperty != null;
- currentValidatedProperty.addError( message );
- }
-
- public void addError(String message, String property) {
- assert currentValidatedProperty != null;
- currentValidatedProperty.addError( message, property );
- }
-
- public void setCurrentConstraintDescriptor(ConstraintDescriptor constraintDescriptor) {
- assert currentValidatedProperty != null;
- currentValidatedProperty.setConstraintDescriptor( constraintDescriptor );
- }
-
public Object peekCurrentBean() {
return beanStack.peek();
}
@@ -220,13 +189,13 @@
return objectsProcessedInCurrentGroups != null &&
objectsProcessedInCurrentGroups.contains( value );
}
- public void addConstraintFailures(List<ConstraintViolationImpl<T>>
failingConstraintViolations) {
- for ( ConstraintViolationImpl<T> violation : failingConstraintViolations ) {
+ public void addConstraintFailures(List<ConstraintViolation<T>>
failingConstraintViolations) {
+ for ( ConstraintViolation<T> violation : failingConstraintViolations ) {
addConstraintFailure( violation );
}
}
- public List<ConstraintViolationImpl<T>> getFailingConstraints() {
+ public List<ConstraintViolation<T>> getFailingConstraints() {
return failingConstraintViolations;
}
@@ -236,7 +205,6 @@
* @param property the new property to add to the current path.
*/
public void pushProperty(String property) {
- currentValidatedProperty = new ValidatedProperty( peekPropertyPath(), property );
propertyPath.add( property );
}
@@ -246,7 +214,6 @@
public void popProperty() {
if ( propertyPath.size() > 0 ) {
propertyPath.remove( propertyPath.size() - 1 );
- currentValidatedProperty = null;
}
}
@@ -267,14 +234,7 @@
}
public String peekPropertyPath() {
- StringBuilder builder = new StringBuilder();
- for ( int i = 0; i <= propertyPath.size() - 1; i++ ) {
- builder.append( propertyPath.get( i ) );
- if ( i < propertyPath.size() - 1 ) {
- builder.append( PROPERTY_PATH_SEPERATOR );
- }
- }
- return builder.toString();
+ return buildPath( propertyPath.size() - 1 );
}
public String peekProperty() {
@@ -284,6 +244,10 @@
return propertyPath.get( propertyPath.size() - 1 );
}
+ public String peekParentPath() {
+ return buildPath( propertyPath.size() - 2 );
+ }
+
public boolean isValidationRequired(MetaConstraint metaConstraint) {
if ( !metaConstraint.getGroupList().contains( currentGroup ) ) {
return false;
@@ -299,16 +263,18 @@
);
}
- public List<ConstraintViolationImpl<T>> createConstraintViolations(Object
value) {
+ public List<ConstraintViolationImpl<T>> createConstraintViolations(Object
value, ConstraintValidatorContextImpl constraintValidatorContext) {
List<ConstraintViolationImpl<T>> constraintViolations = new
ArrayList<ConstraintViolationImpl<T>>();
- for ( ErrorMessage error : currentValidatedProperty.getErrorMessages() ) {
- constraintViolations.add( createConstraintViolation( value, error ) );
+ for ( ConstraintValidatorContextImpl.ErrorMessage error :
constraintValidatorContext.getErrorMessages() ) {
+ ConstraintViolationImpl<T> violation = createConstraintViolation(
+ value, error, constraintValidatorContext.getConstraintDescriptor()
+ );
+ constraintViolations.add( violation );
}
return constraintViolations;
}
- public ConstraintViolationImpl<T> createConstraintViolation(Object value,
ErrorMessage error) {
- ConstraintDescriptor descriptor = currentValidatedProperty.getConstraintDescriptor();
+ public ConstraintViolationImpl<T> createConstraintViolation(Object value,
ConstraintValidatorContextImpl.ErrorMessage error, ConstraintDescriptor<?>
descriptor) {
String messageTemplate = error.getMessage();
String interpolatedMessage = messageInterpolator.interpolate(
messageTemplate,
@@ -325,6 +291,17 @@
);
}
+ private String buildPath(int index) {
+ StringBuilder builder = new StringBuilder();
+ for ( int i = 0; i <= index; i++ ) {
+ builder.append( propertyPath.get( i ) );
+ if ( i < index ) {
+ builder.append( PROPERTY_PATH_SEPERATOR );
+ }
+ }
+ return builder.toString();
+ }
+
private void markProcessed() {
markProcessForCurrentGroup();
if ( allowOneValidationPerPath ) {
@@ -354,90 +331,10 @@
}
}
- private void addConstraintFailure(ConstraintViolationImpl<T>
failingConstraintViolation) {
+ private void addConstraintFailure(ConstraintViolation<T>
failingConstraintViolation) {
int i = failingConstraintViolations.indexOf( failingConstraintViolation );
if ( i == -1 ) {
failingConstraintViolations.add( failingConstraintViolation );
}
}
-
- class ValidatedProperty {
-
- private final List<ErrorMessage> errorMessages = new
ArrayList<ErrorMessage>( 3 );
- private final String property;
- private final String propertyParent;
- private ConstraintDescriptor<?> constraintDescriptor;
- private boolean defaultDisabled;
-
-
- private ValidatedProperty(String propertyParent, String property) {
- this.property = property;
- this.propertyParent = propertyParent;
- }
-
- public void setConstraintDescriptor(ConstraintDescriptor<?> constraintDescriptor)
{
- this.constraintDescriptor = constraintDescriptor;
- }
-
- public ConstraintDescriptor<?> getConstraintDescriptor() {
- return constraintDescriptor;
- }
-
- void disableDefaultError() {
- defaultDisabled = true;
- }
-
- public boolean isDefaultErrorDisabled() {
- return defaultDisabled;
- }
-
- public String getDefaultErrorMessage() {
- return ( String ) constraintDescriptor.getAttributes().get( "message" );
- }
-
- public void addError(String message) {
- errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent,
property ) ) );
- }
-
- public void addError(String message, String property) {
- errorMessages.add( new ErrorMessage( message, buildPropertyPath( propertyParent,
property ) ) );
- }
-
- public List<ErrorMessage> getErrorMessages() {
- List<ErrorMessage> returnedErrorMessages = new ArrayList<ErrorMessage>(
errorMessages );
- if ( !defaultDisabled ) {
- returnedErrorMessages.add(
- new ErrorMessage( getDefaultErrorMessage(), buildPropertyPath( propertyParent,
property ) )
- );
- }
- return returnedErrorMessages;
- }
-
- private String buildPropertyPath(String parent, String leaf) {
- if ( PROPERTY_ROOT.equals( parent ) ) {
- return leaf;
- }
- else {
- return new StringBuilder().append( parent ).append( PROPERTY_PATH_SEPERATOR ).append(
leaf ).toString();
- }
- }
- }
-
- public class ErrorMessage {
- private final String message;
- private final String property;
-
- public ErrorMessage(String message, String property) {
- this.message = message;
- this.property = property;
- }
-
- public String getMessage() {
- return message;
- }
-
- public String getProperty() {
- return property;
- }
- }
}
\ No newline at end of file
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java
===================================================================
---
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-03-18
11:16:04 UTC (rev 16181)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/MetaConstraint.java 2009-03-18
13:45:24 UTC (rev 16182)
@@ -28,6 +28,7 @@
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintDescriptor;
+import javax.validation.ConstraintViolation;
import org.hibernate.validation.util.ReflectionHelper;
@@ -139,7 +140,7 @@
public <T> boolean validateConstraint(ExecutionContext<T> executionContext)
{
final Object leafBeanInstance = executionContext.peekCurrentBean();
Object value = getValue( leafBeanInstance );
- List<ConstraintViolationImpl<T>> constraintViolations = new
ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> constraintViolations = new
ArrayList<ConstraintViolation<T>>();
constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext,
constraintViolations );
if ( constraintViolations.size() > 0 ) {
executionContext.addConstraintFailures( constraintViolations );
@@ -149,7 +150,7 @@
}
public <T> boolean validateConstraint(Object value, ExecutionContext<T>
executionContext) {
- List<ConstraintViolationImpl<T>> constraintViolations = new
ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> constraintViolations = new
ArrayList<ConstraintViolation<T>>();
constraintTree.validateConstraints( value, typeOfAnnoatedElement(), executionContext,
constraintViolations );
if ( constraintViolations.size() > 0 ) {
executionContext.addConstraintFailures( constraintViolations );
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 2009-03-18
11:16:04 UTC (rev 16181)
+++
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-03-18
13:45:24 UTC (rev 16182)
@@ -113,7 +113,7 @@
object, messageInterpolator, constraintValidatorFactory, traversableResolver
);
- List<ConstraintViolationImpl<T>> list = validateInContext( context,
groupChain );
+ List<ConstraintViolation<T>> list = validateInContext( context, groupChain
);
return new HashSet<ConstraintViolation<T>>( list );
}
@@ -127,7 +127,7 @@
sanityCheckPropertyPath( propertyName );
GroupChain groupChain = determineGroupExecutionOrder( groups );
- List<ConstraintViolationImpl<T>> failingConstraintViolations = new
ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> failingConstraintViolations = new
ArrayList<ConstraintViolation<T>>();
validateProperty( object, new PropertyIterator( propertyName ),
failingConstraintViolations, groupChain );
return new HashSet<ConstraintViolation<T>>( failingConstraintViolations );
}
@@ -142,7 +142,7 @@
sanityCheckPropertyPath( propertyName );
GroupChain groupChain = determineGroupExecutionOrder( groups );
- List<ConstraintViolationImpl<T>> failingConstraintViolations = new
ArrayList<ConstraintViolationImpl<T>>();
+ List<ConstraintViolation<T>> failingConstraintViolations = new
ArrayList<ConstraintViolation<T>>();
validateValue( beanType, value, new PropertyIterator( propertyName ),
failingConstraintViolations, groupChain );
return new HashSet<ConstraintViolation<T>>( failingConstraintViolations );
}
@@ -182,7 +182,7 @@
*
* @return List of invalid constraints.
*/
- private <T> List<ConstraintViolationImpl<T>>
validateInContext(ExecutionContext<T> context, GroupChain groupChain) {
+ private <T> List<ConstraintViolation<T>>
validateInContext(ExecutionContext<T> context, GroupChain groupChain) {
if ( context.peekCurrentBean() == null ) {
return Collections.emptyList();
}
@@ -349,7 +349,7 @@
}
}
- private <T> void validateProperty(T object, PropertyIterator propertyIter,
List<ConstraintViolationImpl<T>> failingConstraintViolations, GroupChain
groupChain) {
+ private <T> void validateProperty(T object, PropertyIterator propertyIter,
List<ConstraintViolation<T>> failingConstraintViolations, GroupChain
groupChain) {
@SuppressWarnings("unchecked")
final Class<T> beanType = ( Class<T> ) object.getClass();
@@ -390,7 +390,7 @@
}
}
- private <T> void validatePropertyForGroup(T object, PropertyIterator propertyIter,
List<ConstraintViolationImpl<T>> failingConstraintViolations,
Set<MetaConstraint<T, ?>> metaConstraints, Object hostingBeanInstance, Group
group) {
+ private <T> void validatePropertyForGroup(T object, PropertyIterator propertyIter,
List<ConstraintViolation<T>> failingConstraintViolations,
Set<MetaConstraint<T, ?>> metaConstraints, Object hostingBeanInstance, Group
group) {
int numberOfConstraintViolationsBefore = failingConstraintViolations.size();
BeanMetaData<T> beanMetaData = getBeanMetaData(
metaConstraints.iterator().next().getBeanClass() );
@@ -427,7 +427,7 @@
}
@SuppressWarnings("unchecked")
- private <T> void validateValue(Class<T> beanType, Object value,
PropertyIterator propertyIter, List<ConstraintViolationImpl<T>>
failingConstraintViolations, GroupChain groupChain) {
+ private <T> void validateValue(Class<T> beanType, Object value,
PropertyIterator propertyIter, List<ConstraintViolation<T>>
failingConstraintViolations, GroupChain groupChain) {
Set<MetaConstraint<T, ?>> metaConstraints = new
HashSet<MetaConstraint<T, ?>>();
collectMetaConstraintsForPath( beanType, null, propertyIter, metaConstraints );
@@ -469,7 +469,7 @@
}
}
- private <T> void validateValueForGroup(Object value, PropertyIterator
propertyIter, List<ConstraintViolationImpl<T>> failingConstraintViolations,
Set<MetaConstraint<T, ?>> metaConstraints, Group group) {
+ private <T> void validateValueForGroup(Object value, PropertyIterator
propertyIter, List<ConstraintViolation<T>> failingConstraintViolations,
Set<MetaConstraint<T, ?>> metaConstraints, Group group) {
int numberOfConstraintViolations = failingConstraintViolations.size();
BeanMetaData<T> beanMetaData = getBeanMetaData(
metaConstraints.iterator().next().getBeanClass() );
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java 2009-03-18
11:16:04 UTC (rev 16181)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/GraphNavigationTest.java 2009-03-18
13:45:24 UTC (rev 16182)
@@ -17,11 +17,14 @@
*/
package org.hibernate.validation.engine.graphnavigation;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.hibernate.validation.util.TestUtil;
@@ -59,5 +62,55 @@
Set<ConstraintViolation<Order>> constraintViolations = validator.validate(
order );
assertEquals( "Wrong number of constraints", 3, constraintViolations.size()
);
+
+ List<String> expectedErrorMessages = new ArrayList<String>();
+ expectedErrorMessages.add( "shippingAddress.addressline1" );
+ expectedErrorMessages.add( "customer.addresses[0].addressline1" );
+ expectedErrorMessages.add(
"billingAddress.inhabitant.addresses[0].addressline1" );
+
+ for ( ConstraintViolation<Order> violation : constraintViolations ) {
+ if ( expectedErrorMessages.contains( violation.getPropertyPath() ) ) {
+ expectedErrorMessages.remove( violation.getPropertyPath() );
+ }
+ }
+
+ assertTrue( "All error messages should have occured once",
expectedErrorMessages.size() == 0 );
}
+
+ @Test
+ public void testNoEndlessLoop() {
+ User john = new User( "John", null );
+ john.knows( john );
+
+ Validator validator = TestUtil.getValidator();
+
+ Set<ConstraintViolation<User>> constraintViolations = validator.validate(
john );
+ assertEquals( "Wrong number of constraints", 1, constraintViolations.size()
);
+ TestUtil.assertConstraintViolation(
+ constraintViolations.iterator().next(), "may not be null", User.class,
null, "lastName"
+ );
+
+
+ User jane = new User( "Jane", "Doe" );
+ jane.knows( john );
+ john.knows( jane );
+
+ constraintViolations = validator.validate( john );
+ assertEquals( "Wrong number of constraints", 1, constraintViolations.size()
);
+ TestUtil.assertConstraintViolation(
+ constraintViolations.iterator().next(), "may not be null", User.class,
null, "lastName"
+ );
+
+ constraintViolations = validator.validate( jane );
+ assertEquals( "Wrong number of constraints", 1, constraintViolations.size()
);
+ TestUtil.assertConstraintViolation(
+ constraintViolations.iterator().next(), "may not be null", User.class,
null, "knowsUser[0].lastName"
+ );
+
+ john.setLastName( "Doe" );
+ constraintViolations = validator.validate( john );
+ assertEquals( "Wrong number of constraints", 0, constraintViolations.size()
);
+
+
+ }
}
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java
===================================================================
---
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java 2009-03-18
11:16:04 UTC (rev 16181)
+++
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/graphnavigation/User.java 2009-03-18
13:45:24 UTC (rev 16182)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
@@ -17,11 +17,11 @@
*/
package org.hibernate.validation.engine.graphnavigation;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.List;
+import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;
-import javax.validation.Valid;
/**
* @author Hardy Ferentschik
@@ -35,8 +35,11 @@
private String lastName;
@Valid
- private Set<Address> addresses = new HashSet<Address>();
+ private List<Address> addresses = new ArrayList<Address>();
+ @Valid
+ private List<User> knowsUser = new ArrayList<User>();
+
public User() {
}
@@ -45,7 +48,7 @@
this.lastName = lastName;
}
- public Set<Address> getAddresses() {
+ public List<Address> getAddresses() {
return addresses;
}
@@ -53,6 +56,14 @@
addresses.add( address );
}
+ public void knows(User user) {
+ knowsUser.add( user );
+ }
+
+ public List<User> getKnowsUser() {
+ return knowsUser;
+ }
+
public String getFirstName() {
return firstName;
}