[hibernate-commits] Hibernate SVN: r17088 - beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition and 7 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jul 14 07:45:55 EDT 2009


Author: hardy.ferentschik
Date: 2009-07-14 07:45:54 -0400 (Tue, 14 Jul 2009)
New Revision: 17088

Added:
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint1.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint2.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint3.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint4.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/NestedConstraintCompositionTest.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraint.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraintSingleViolation.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/CompositeConstraintTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/Person.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidName.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidNameSingleViolation.java
Modified:
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/ConstraintCompositionTest.java
   beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/util/TestUtil.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
   validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml
Log:
HV-182 
There were really two bugs in the code. One in the recursive traversal of the constraint tree. 
This was causing the wrong annotation type problem. 
The problem with the wrong interpolated message was a bug in ResourceBundleMessageInterpolator.
I added tests for both cases (including tests in the TCK for nested composed constraints)



Modified: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/ConstraintCompositionTest.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/ConstraintCompositionTest.java	2009-07-13 23:41:18 UTC (rev 17087)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/ConstraintCompositionTest.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -23,8 +23,8 @@
 import java.util.Set;
 import javax.validation.ConstraintDefinitionException;
 import javax.validation.ConstraintViolation;
-import javax.validation.Validator;
 import javax.validation.UnexpectedTypeException;
+import javax.validation.Validator;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;
 import javax.validation.constraints.Size;
@@ -113,9 +113,7 @@
 		address.setZipCode( "00000" );
 		Set<ConstraintViolation<FrenchAddress>> constraintViolations = validator.validate( address );
 		assertCorrectNumberOfViolations( constraintViolations, 1 );
-		assertCorrectConstraintTypes(
-				constraintViolations, new Class<?>[] { FrenchZipcode.class }
-		);
+		assertCorrectConstraintTypes( constraintViolations, FrenchZipcode.class );
 		assertCorrectConstraintViolationMessages( constraintViolations, "00000 is a reserved code" );
 	}
 
@@ -134,9 +132,7 @@
 		address.setZipCode( "abc" );
 		Set<ConstraintViolation<FrenchAddress>> constraintViolations = validator.validate( address );
 		assertCorrectNumberOfViolations( constraintViolations, 3 );
-		assertCorrectConstraintTypes(
-				constraintViolations, new Class<?>[] { Pattern.class, Pattern.class, Size.class }
-		);
+		assertCorrectConstraintTypes( constraintViolations, Pattern.class, Pattern.class, Size.class );
 		for ( ConstraintViolation<FrenchAddress> violation : constraintViolations ) {
 			assertConstraintViolation(
 					violation,
@@ -149,9 +145,7 @@
 		address.setZipCode( "123" );
 		constraintViolations = validator.validate( address );
 		assertCorrectNumberOfViolations( constraintViolations, 2 );
-		assertCorrectConstraintTypes(
-				constraintViolations, new Class<?>[] { Pattern.class, Size.class }
-		);
+		assertCorrectConstraintTypes( constraintViolations, Pattern.class, Size.class );
 		for ( ConstraintViolation<FrenchAddress> violation : constraintViolations ) {
 			assertConstraintViolation(
 					violation,

Added: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint1.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint1.java	                        (rev 0)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint1.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,43 @@
+// $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.jsr303.tck.tests.constraints.constraintcomposition.nestedconstraintcomposition;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.constraints.Pattern;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Target({ METHOD, FIELD })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+ at Pattern(regexp = "abc", message = "Pattern must match {regexp}")
+ at SecondCompositeConstraintSingleViolation
+public @interface FirstCompositeConstraint1 {
+	public abstract String message() default "FirstCompositeConstraint1 failed.";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends ConstraintPayload>[] payload() default { };
+}

Added: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint2.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint2.java	                        (rev 0)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint2.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,45 @@
+// $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.jsr303.tck.tests.constraints.constraintcomposition.nestedconstraintcomposition;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import javax.validation.constraints.Pattern;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.ReportAsSingleViolation;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Pattern(regexp = "abc")
+ at Target({ METHOD, FIELD })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+ at SecondCompositeConstraintSingleViolation
+ at ReportAsSingleViolation
+public @interface FirstCompositeConstraint2 {
+	public abstract String message() default "FirstCompositeConstraint2 failed.";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends ConstraintPayload>[] payload() default { };
+}
\ No newline at end of file

Added: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint3.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint3.java	                        (rev 0)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint3.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,44 @@
+// $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.jsr303.tck.tests.constraints.constraintcomposition.nestedconstraintcomposition;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import javax.validation.constraints.Pattern;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.ReportAsSingleViolation;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Pattern(regexp = "abc", message = "Pattern must match {regexp}")
+ at Target({ METHOD, FIELD })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+ at SecondCompositeConstraint
+public @interface FirstCompositeConstraint3 {
+	public abstract String message() default "FirstCompositeConstraint3 failed.";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends ConstraintPayload>[] payload() default { };
+}
\ No newline at end of file

Added: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint4.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint4.java	                        (rev 0)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/FirstCompositeConstraint4.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,45 @@
+// $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.jsr303.tck.tests.constraints.constraintcomposition.nestedconstraintcomposition;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import javax.validation.constraints.Pattern;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.ReportAsSingleViolation;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Pattern(regexp = "abc")
+ at Target({ METHOD, FIELD })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+ at SecondCompositeConstraint
+ at ReportAsSingleViolation
+public @interface FirstCompositeConstraint4 {
+	public abstract String message() default "FirstCompositeConstraint4 failed.";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends ConstraintPayload>[] payload() default { };
+}
\ No newline at end of file

Copied: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/NestedConstraintCompositionTest.java (from rev 17087, beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/ConstraintCompositionTest.java)
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/NestedConstraintCompositionTest.java	                        (rev 0)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/NestedConstraintCompositionTest.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,128 @@
+// $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.jsr303.tck.tests.constraints.constraintcomposition.nestedconstraintcomposition;
+
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+import org.jboss.testharness.AbstractTest;
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.ArtifactType;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.testng.annotations.Test;
+
+import org.hibernate.jsr303.tck.util.TestUtil;
+import static org.hibernate.jsr303.tck.util.TestUtil.assertCorrectConstraintTypes;
+import static org.hibernate.jsr303.tck.util.TestUtil.assertCorrectConstraintViolationMessages;
+import static org.hibernate.jsr303.tck.util.TestUtil.assertCorrectNumberOfViolations;
+
+/**
+ * Tests for composing constraints.
+ *
+ * @author Hardy Ferentschik
+ */
+ at Artifact(artifactType = ArtifactType.JSR303)
+ at Classes({ TestUtil.class, TestUtil.PathImpl.class, TestUtil.NodeImpl.class })
+public class NestedConstraintCompositionTest extends AbstractTest {
+
+	@Test
+	public void testFirstConstraintAllViolationsSecondConstraintSingleViolation() {
+		Validator validator = TestUtil.getDefaultValidator();
+		DummyEntity1 dummy = new DummyEntity1( "" );
+		Set<ConstraintViolation<DummyEntity1>> constraintViolations = validator.validate( dummy );
+		assertCorrectNumberOfViolations( constraintViolations, 2 );
+		assertCorrectConstraintTypes(
+				constraintViolations, Pattern.class, SecondCompositeConstraintSingleViolation.class
+		);
+		assertCorrectConstraintViolationMessages(
+				constraintViolations, "Pattern must match abc", "SecondCompositeConstraintSingleViolation failed."
+		);
+	}
+
+	@Test
+	public void testFirstConstraintSingleViolationSecondConstraintSingleViolation() {
+		Validator validator = TestUtil.getDefaultValidator();
+		DummyEntity2 dummy = new DummyEntity2( "" );
+		Set<ConstraintViolation<DummyEntity2>> constraintViolations = validator.validate( dummy );
+		assertCorrectNumberOfViolations( constraintViolations, 1 );
+		assertCorrectConstraintTypes( constraintViolations, FirstCompositeConstraint2.class );
+		assertCorrectConstraintViolationMessages( constraintViolations, "FirstCompositeConstraint2 failed." );
+	}
+
+	@Test
+	public void testFirstConstraintAllViolationSecondConstraintAllViolations() {
+		Validator validator = TestUtil.getDefaultValidator();
+		DummyEntity3 dummy = new DummyEntity3( "" );
+		Set<ConstraintViolation<DummyEntity3>> constraintViolations = validator.validate( dummy );
+		assertCorrectNumberOfViolations( constraintViolations, 3 );
+		assertCorrectConstraintTypes( constraintViolations, Pattern.class, Pattern.class, Size.class );
+		assertCorrectConstraintViolationMessages(
+				constraintViolations, "Pattern must match abc", "Pattern must match ...", "Size must be 3"
+		);
+	}
+
+	@Test
+	public void testFirstConstraintSingleViolationSecondConstraintAllViolations() {
+		Validator validator = TestUtil.getDefaultValidator();
+		DummyEntity4 dummy = new DummyEntity4( "" );
+		Set<ConstraintViolation<DummyEntity4>> constraintViolations = validator.validate( dummy );
+		assertCorrectNumberOfViolations( constraintViolations, 1 );
+		assertCorrectConstraintTypes( constraintViolations, FirstCompositeConstraint4.class );
+		assertCorrectConstraintViolationMessages( constraintViolations, "FirstCompositeConstraint4 failed." );
+	}
+
+
+	class DummyEntity1 {
+		@FirstCompositeConstraint1
+		String string;
+
+		DummyEntity1(String s) {
+			this.string = s;
+		}
+	}
+
+	class DummyEntity2 {
+		@FirstCompositeConstraint2
+		String string;
+
+		DummyEntity2(String s) {
+			this.string = s;
+		}
+	}
+
+	class DummyEntity3 {
+		@FirstCompositeConstraint3
+		String string;
+
+		DummyEntity3(String s) {
+			this.string = s;
+		}
+	}
+
+	class DummyEntity4 {
+		@FirstCompositeConstraint4
+		String string;
+
+		DummyEntity4(String s) {
+			this.string = s;
+		}
+	}
+}
\ No newline at end of file

Added: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraint.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraint.java	                        (rev 0)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraint.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,46 @@
+// $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.jsr303.tck.tests.constraints.constraintcomposition.nestedconstraintcomposition;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Pattern(regexp = "...", message = "Pattern must match {regexp}")
+ at Size(min = 3, max = 3, message = "Size must be {min}")
+ at Target({ METHOD, FIELD, TYPE })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+public @interface SecondCompositeConstraint {
+	public abstract String message() default "SecondCompositeConstraintSingleViolation failed.";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends ConstraintPayload>[] payload() default { };
+}
\ No newline at end of file

Added: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraintSingleViolation.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraintSingleViolation.java	                        (rev 0)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/tests/constraints/constraintcomposition/nestedconstraintcomposition/SecondCompositeConstraintSingleViolation.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,47 @@
+// $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.jsr303.tck.tests.constraints.constraintcomposition.nestedconstraintcomposition;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at Pattern(regexp = "...", message = "Pattern must match {regexp}")
+ at Size(min = 3, max = 3, message = "Size must be {min}")
+ at Target({ METHOD, FIELD, TYPE })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+ at ReportAsSingleViolation
+public @interface SecondCompositeConstraintSingleViolation {
+	public abstract String message() default "SecondCompositeConstraintSingleViolation failed.";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends ConstraintPayload>[] payload() default { };
+}
\ No newline at end of file

Modified: beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/util/TestUtil.java
===================================================================
--- beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/util/TestUtil.java	2009-07-13 23:41:18 UTC (rev 17087)
+++ beanvalidation/trunk/validation-tck/src/main/java/org/hibernate/jsr303/tck/util/TestUtil.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -71,7 +71,7 @@
 		for ( String expectedMessage : messages ) {
 			assertTrue(
 					actualMessages.contains( expectedMessage ),
-					"The message " + expectedMessage + " should have been in the st of error messages"
+					"The message '" + expectedMessage + "' should have been in the list of actual messages: " + actualMessages
 			);
 			actualMessages.remove( expectedMessage );
 		}

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-07-13 23:41:18 UTC (rev 17087)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -98,7 +98,9 @@
 	public <T, U, V> void validateConstraints(Type type, GlobalExecutionContext<T> executionContext, LocalExecutionContext<U, V> localExecutionContext, List<ConstraintViolation<T>> constraintViolations) {
 		// first validate composing constraints
 		for ( ConstraintTree<?> tree : getChildren() ) {
-			tree.validateConstraints( type, executionContext, localExecutionContext, constraintViolations );
+			List<ConstraintViolation<T>> tmpViolations = new ArrayList<ConstraintViolation<T>>();
+			tree.validateConstraints( type, executionContext, localExecutionContext, tmpViolations );
+			constraintViolations.addAll( tmpViolations );
 		}
 
 		ConstraintValidatorContextImpl constraintValidatorContext = new ConstraintValidatorContextImpl(
@@ -131,15 +133,14 @@
 
 		if ( reportAsSingleViolation() && constraintViolations.size() > 0 ) {
 			constraintViolations.clear();
-			final String message = ( String ) getParent().getDescriptor().getAttributes().get( "message" );
+			final String message = ( String ) getDescriptor().getAttributes().get( "message" );
 			ConstraintValidatorContextImpl.ErrorMessage error = constraintValidatorContext.new ErrorMessage(
 					message, localExecutionContext.getPropertyPath()
 			);
-			constraintViolations.add(
-					executionContext.createConstraintViolation(
-							localExecutionContext, error, descriptor
-					)
+			ConstraintViolation<T> violation = executionContext.createConstraintViolation(
+					localExecutionContext, error, descriptor
 			);
+			constraintViolations.add( violation );
 		}
 	}
 
@@ -161,8 +162,7 @@
 	}
 
 	private boolean reportAsSingleViolation() {
-		return getParent() != null
-				&& getParent().getDescriptor().isReportAsSingleViolation();
+		return getDescriptor().isReportAsSingleViolation();
 	}
 
 	/**
@@ -295,8 +295,7 @@
 		final StringBuilder sb = new StringBuilder();
 		sb.append( "ConstraintTree" );
 		sb.append( "{ descriptor=" ).append( descriptor );
-		sb.append( ", parent=" ).append( parent );
-		sb.append( ", children=" ).append( children );
+		sb.append( ", isRoot=" ).append( parent == null );
 		sb.append( ", constraintValidatorCache=" ).append( constraintValidatorCache );
 		sb.append( '}' );
 		return sb.toString();

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java	2009-07-13 23:41:18 UTC (rev 17087)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -221,7 +221,7 @@
 				resolvedParameterValue = escapeMetaCharacters( variable.toString() );
 			}
 			else {
-				resolvedParameterValue = message;
+				resolvedParameterValue = parameter;
 			}
 			matcher.appendReplacement( sb, resolvedParameterValue );
 		}

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/CompositeConstraintTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/CompositeConstraintTest.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/CompositeConstraintTest.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,101 @@
+// $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.constraints.composition;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+import org.hibernate.validation.util.TestUtil;
+import static org.hibernate.validation.util.TestUtil.assertCorrectConstraintTypes;
+import static org.hibernate.validation.util.TestUtil.assertCorrectConstraintViolationMessages;
+import static org.hibernate.validation.util.TestUtil.assertNumberOfViolations;
+
+/**
+ * @author Gerhard Petracek
+ * @author Hardy Ferentschik
+ */
+public class CompositeConstraintTest {
+
+	/**
+	 * HV-182
+	 */
+	@Test
+	public void testCorrectAnnotationTypeForWithReportAsSingleViolation() {
+
+		Validator currentValidator = TestUtil.getValidator();
+
+		for ( int i = 0; i < 100; i++ ) {
+			Set<ConstraintViolation<Person>> constraintViolations = currentValidator.validate(
+					new Person(
+							null, "Gerhard"
+					)
+			);
+
+			assertNumberOfViolations( constraintViolations, 1 );
+			assertCorrectConstraintTypes( constraintViolations, ValidNameSingleViolation.class );
+			assertCorrectConstraintViolationMessages( constraintViolations, "invalid name" );
+
+			constraintViolations = currentValidator.validate(
+					new Person(
+							"G", "Gerhard"
+					)
+			);
+			assertNumberOfViolations( constraintViolations, 1 );
+			assertCorrectConstraintTypes( constraintViolations, ValidNameSingleViolation.class );
+			assertCorrectConstraintViolationMessages( constraintViolations, "invalid name" );
+		}
+	}
+
+	/**
+	 * HV-182
+	 */
+	@Test
+	public void testCorrectAnnotationTypeReportMultipleViolations() {
+
+		Validator currentValidator = TestUtil.getValidator();
+
+		for ( int i = 0; i < 100; i++ ) {
+			Set<ConstraintViolation<Person>> constraintViolations = currentValidator.validate(
+					new Person(
+							"Gerd", null
+					)
+			);
+
+			assertNumberOfViolations( constraintViolations, 1 );
+			assertCorrectConstraintTypes( constraintViolations, NotNull.class );
+			assertCorrectConstraintViolationMessages( constraintViolations, "may not be null" );
+
+			constraintViolations = currentValidator.validate(
+					new Person(
+							"Gerd", "G"
+					)
+			);
+			assertNumberOfViolations( constraintViolations, 1 );
+			assertCorrectConstraintTypes( constraintViolations, Size.class );
+			assertCorrectConstraintViolationMessages( constraintViolations, "size must be between 2 and 10" );
+		}
+	}
+}
+

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/Person.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/Person.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/Person.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,54 @@
+// $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.constraints.composition;
+
+/**
+ * Test mode for HV-182.
+ *
+ * @author Gerhard Petracek
+ * @author Hardy Ferentschik
+ */
+
+public class Person {
+	@ValidNameSingleViolation
+	private String nickName;
+
+	@ValidName
+	private String name;
+
+	public Person(String nickName, String name) {
+		this.nickName = nickName;
+		this.name = name;
+	}
+
+	public String getNickName() {
+		return nickName;
+	}
+
+	public void setNickName(String nickName) {
+		this.nickName = nickName;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+}

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidName.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidName.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidName.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,48 @@
+// $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.constraints.composition;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+/**
+ * Test constraint for HV-182.
+ *
+ * @author Gerhard Petracek
+ * @author Hardy Ferentschik
+ */
+ at NotNull
+ at Size(min = 2, max = 10)
+ at Target({ METHOD, FIELD })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+public @interface ValidName {
+	public abstract String message() default "invalid name";
+
+	public abstract Class<?>[] groups() default { };
+
+	public abstract Class<? extends ConstraintPayload>[] payload() default { };
+}
\ No newline at end of file

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidNameSingleViolation.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidNameSingleViolation.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/constraints/composition/ValidNameSingleViolation.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -0,0 +1,49 @@
+// $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.constraints.composition;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.validation.Constraint;
+import javax.validation.ConstraintPayload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+/**
+ * Test constraint for HV-182.
+ *
+ * @author Gerhard Petracek
+ * @author Hardy Ferentschik
+ */
+ at NotNull
+ at Size(min = 2, max = 10)
+ at ReportAsSingleViolation
+ at Target({ METHOD, FIELD })
+ at Retention(RUNTIME)
+ at Constraint(validatedBy = { })
+public @interface ValidNameSingleViolation {
+	String message() default "invalid name";
+
+	Class<?>[] groups() default { };
+
+	Class<? extends ConstraintPayload>[] payload() default { };
+}

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java	2009-07-13 23:41:18 UTC (rev 17087)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolatorTest.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -197,11 +197,36 @@
 		String expected = "{replace.in.default.bundle2}";
 		String actual = interpolator.interpolate( max.message(), context );
 		assertEquals(
-				expected, actual, "Within default bundle replacement parameter evauation should not be recursive!"
+				actual, expected, "Within default bundle replacement parameter evauation should not be recursive!"
 		);
 	}
 
 	/**
+	 * HV-182
+	 */
+	@Test
+	public void testCorrectMessageInterpolationIfParameterCannotBeReplaced() {
+		AnnotationDescriptor<Max> descriptor = new AnnotationDescriptor<Max>( Max.class );
+		String message = "Message should stay unchanged since {fubar} is not replacable";
+		descriptor.setValue( "message", message );
+		descriptor.setValue( "value", 10l );
+		Max max = AnnotationFactory.create( descriptor );
+
+
+		ConstraintDescriptorImpl<Max> constraintDescriptor = new ConstraintDescriptorImpl<Max>(
+				max, new ConstraintHelper()
+		);
+
+		interpolator = new ResourceBundleMessageInterpolator( new TestResourceBundle() );
+		MessageInterpolator.Context context = new MessageInterpolatorContext( constraintDescriptor, null );
+
+		String actual = interpolator.interpolate( max.message(), context );
+		assertEquals(
+				actual, message, "The message should not have changed."
+		);
+	}
+
+	/**
 	 * A dummy resource bundle which can be passed to the constructor of ResourceBundleMessageInterpolator to replace
 	 * the user specified resource bundle.
 	 */

Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java	2009-07-13 23:41:18 UTC (rev 17087)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java	2009-07-14 11:45:54 UTC (rev 17088)
@@ -18,8 +18,13 @@
 package org.hibernate.validation.util;
 
 import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import javax.validation.ConstraintViolation;
+import javax.validation.Path;
 import javax.validation.Validation;
 import javax.validation.Validator;
 import javax.validation.metadata.ConstraintDescriptor;
@@ -29,6 +34,7 @@
 import org.slf4j.Logger;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
+import static org.testng.FileAssert.fail;
 
 import org.hibernate.validation.HibernateValidationProvider;
 import org.hibernate.validation.engine.HibernateValidatorConfiguration;
@@ -103,6 +109,67 @@
 		return elementDescriptor.getConstraintDescriptors();
 	}
 
+	public static <T> void assertCorrectConstraintViolationMessages(Set<ConstraintViolation<T>> violations, String... messages) {
+		List<String> actualMessages = new ArrayList<String>();
+		for ( ConstraintViolation<?> violation : violations ) {
+			actualMessages.add( violation.getMessage() );
+		}
+
+		assertTrue( actualMessages.size() == messages.length, "Wrong number or error messages" );
+
+		for ( String expectedMessage : messages ) {
+			assertTrue(
+					actualMessages.contains( expectedMessage ),
+					"The message '" + expectedMessage + "' should have been in the list of actual messages: " + actualMessages
+			);
+			actualMessages.remove( expectedMessage );
+		}
+		assertTrue(
+				actualMessages.isEmpty(), "Actual messages contained more messages as specidied expected messages"
+		);
+	}
+
+	public static <T> void assertCorrectConstraintTypes(Set<ConstraintViolation<T>> violations, Class<?>... expectedConsraintTypes) {
+		List<String> actualConstraintTypes = new ArrayList<String>();
+		for ( ConstraintViolation<?> violation : violations ) {
+			actualConstraintTypes.add(
+					( ( Annotation ) violation.getConstraintDescriptor().getAnnotation() ).annotationType().getName()
+			);
+		}
+
+		assertEquals(
+				expectedConsraintTypes.length, actualConstraintTypes.size(), "Wrong number of constraint types."
+		);
+
+		for ( Class<?> expectedConstraintType : expectedConsraintTypes ) {
+			assertTrue(
+					actualConstraintTypes.contains( expectedConstraintType.getName() ),
+					"The constraint type " + expectedConstraintType.getName() + " should have been violated."
+			);
+		}
+	}
+
+	public static <T> void assertCorrectPropertyPaths(Set<ConstraintViolation<T>> violations, String... propertyPaths) {
+		List<Path> propertyPathsOfViolations = new ArrayList<Path>();
+		for ( ConstraintViolation<?> violation : violations ) {
+			propertyPathsOfViolations.add( violation.getPropertyPath() );
+		}
+
+		for ( String propertyPath : propertyPaths ) {
+			Path expectedPath = PathImpl.createPathFromString( propertyPath );
+			boolean containsPath = false;
+			for ( Path actualPath : propertyPathsOfViolations ) {
+				if ( assertEqualPaths( expectedPath, actualPath ) ) {
+					containsPath = true;
+					break;
+				}
+			}
+			if ( !containsPath ) {
+				fail( expectedPath + " is not in the list of path instances contained in the actual constraint violations" );
+			}
+		}
+	}
+
 	public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class rootBean, Object invalidValue, String propertyPath, Class leafBean) {
 		assertEquals(
 
@@ -148,6 +215,53 @@
 		assertEquals( violations.size(), expectedViolations, "Wrong number of constraint violations" );
 	}
 
+	public static boolean assertEqualPaths(Path p1, Path p2) {
+		Iterator<Path.Node> p1Iterator = p1.iterator();
+		Iterator<Path.Node> p2Iterator = p2.iterator();
+		while ( p1Iterator.hasNext() ) {
+			Path.Node p1Node = p1Iterator.next();
+			if ( !p2Iterator.hasNext() ) {
+				return false;
+			}
+			Path.Node p2Node = p2Iterator.next();
+
+			// do the comparison on the node values
+			if ( p2Node.getName() == null ) {
+				if ( p1Node.getName() != null ) {
+					return false;
+				}
+			}
+			else if ( !p2Node.getName().equals( p1Node.getName() ) ) {
+				return false;
+			}
+
+			if ( p2Node.isInIterable() != p1Node.isInIterable() ) {
+				return false;
+			}
+
+
+			if ( p2Node.getIndex() == null ) {
+				if ( p1Node.getIndex() != null ) {
+					return false;
+				}
+			}
+			else if ( !p2Node.getIndex().equals( p1Node.getIndex() ) ) {
+				return false;
+			}
+
+			if ( p2Node.getKey() == null ) {
+				if ( p1Node.getKey() != null ) {
+					return false;
+				}
+			}
+			else if ( !p2Node.getKey().equals( p1Node.getKey() ) ) {
+				return false;
+			}
+		}
+
+		return !p2Iterator.hasNext();
+	}
+
 	private static class CustomValidationXmlClassLoader extends ClassLoader {
 		private final String customValidationXmlPath;
 

Modified: validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml
===================================================================
--- validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml	2009-07-13 23:41:18 UTC (rev 17087)
+++ validator/trunk/hibernate-validator/src/test/suite/unit-tests.xml	2009-07-14 11:45:54 UTC (rev 17088)
@@ -5,6 +5,7 @@
         <packages>
             <package name="org.hibernate.validation.bootstrap"/>
             <package name="org.hibernate.validation.constraints.impl"/>
+            <package name="org.hibernate.validation.constraints.composition"/>
             <package name="org.hibernate.validation.engine"/>
             <package name="org.hibernate.validation.engine.groups"/>
             <package name="org.hibernate.validation.engine.traversableresolver"/>




More information about the hibernate-commits mailing list