[hibernate-commits] Hibernate SVN: r15995 - in validator/trunk/hibernate-validator/src: main/java/org/hibernate/validation/engine/group and 2 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Feb 18 09:47:10 EST 2009


Author: hardy.ferentschik
Date: 2009-02-18 09:47:10 -0500 (Wed, 18 Feb 2009)
New Revision: 15995

Added:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/Group.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChain.java
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChainGenerator.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/Address.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence1.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence2.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupChainGeneratorTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupTest.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCode.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCodeCoherenceChecker.java
Removed:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupExecutionOrder.java
   validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/GroupTest.java
Modified:
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
Log:
HV-92 Work on group and group sequence processing

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-02-18 08:07:43 UTC (rev 15994)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -38,39 +38,55 @@
 
 import org.hibernate.validation.util.PropertyIterator;
 import org.hibernate.validation.util.ReflectionHelper;
+import org.hibernate.validation.engine.group.GroupChainGenerator;
 
 /**
- * The main Bean Validation class.
+ * The main Bean Validation class. This is the core processing class of Hibernate Validator.
  *
  * @author Emmanuel Bernard
  * @author Hardy Ferentschik
  * @todo Make all properties transient for serializability.
  */
 public class ValidatorImpl implements Validator {
-	private static final Set<Class<?>> INDEXABLE_CLASS = new HashSet<Class<?>>();
-	private static final Class<?>[] DEFAULT_GROUP = new Class<?>[] { Default.class };
+	/**
+	 * Set of classes which can be used as index in a map.
+	 */
+	private static final Set<Class<?>> VALID_MAP_INDEX_CLASSES = new HashSet<Class<?>>();
+	static {
+		VALID_MAP_INDEX_CLASSES.add( Integer.class );
+		VALID_MAP_INDEX_CLASSES.add( Long.class );
+		VALID_MAP_INDEX_CLASSES.add( String.class );
+	}
 
 	/**
+	 * The default group array used in case any of the validate methods is called without a group.
+	 */
+	private static final Class<?>[] DEFAULT_GROUP_ARRAY = new Class<?>[] { Default.class };
+
+	/**
 	 * A map for the meta data for each entity. The key is the class and the value the bean meta data for this
 	 * entity.
 	 */
 	private static Map<Class<?>, BeanMetaDataImpl<?>> metadataProviders
 			= new ConcurrentHashMap<Class<?>, BeanMetaDataImpl<?>>( 10 );
 
-	static {
-		INDEXABLE_CLASS.add( Integer.class );
-		INDEXABLE_CLASS.add( Long.class );
-		INDEXABLE_CLASS.add( String.class );
-	}
+	/**
+	 * Used to resolve the group execution order for a validate call.
+	 */
+	private GroupChainGenerator groupChainGenerator;
 
 	private final ConstraintValidatorFactory constraintValidatorFactory;
+
 	private final MessageInterpolator messageInterpolator;
+
 	private final BuiltinConstraints builtinConstraints;
 
 	public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory, MessageInterpolator messageInterpolator, BuiltinConstraints builtinConstraints) {
 		this.constraintValidatorFactory = constraintValidatorFactory;
 		this.messageInterpolator = messageInterpolator;
 		this.builtinConstraints = builtinConstraints;
+
+		groupChainGenerator = new GroupChainGenerator();
 	}
 
 	/**
@@ -84,6 +100,12 @@
 		ExecutionContext<T> context = new ExecutionContext<T>(
 				object, messageInterpolator, constraintValidatorFactory
 		);
+
+		// if no group is specified use the default
+		if ( groups.length == 0 ) {
+			groups = DEFAULT_GROUP_ARRAY;
+		}
+
 		List<ConstraintViolationImpl<T>> list = validateInContext( context, Arrays.asList( groups ) );
 		return new HashSet<ConstraintViolation<T>>( list );
 	}
@@ -96,19 +118,12 @@
 	 * @param groups A list of groups to validate.
 	 *
 	 * @return List of invalid constraints.
-	 *
-	 * @todo Currently we iterate the cascaded fields multiple times. Maybe we should change to an approach where we iterate the object graph only once.
 	 */
 	private <T> List<ConstraintViolationImpl<T>> validateInContext(ExecutionContext<T> context, List<Class<?>> groups) {
 		if ( context.peekValidatedObject() == null ) {
 			return Collections.emptyList();
 		}
 
-		// if no group is specified use the default
-		if ( groups.size() == 0 ) {
-			groups = Arrays.asList( DEFAULT_GROUP );
-		}
-
 		List<Class<?>> expandedGroups;
 		boolean isGroupSequence;
 		for ( Class<?> group : groups ) {
@@ -214,7 +229,7 @@
 			propertyIndex = String.valueOf( i );
 			if ( actualValue instanceof Map.Entry ) {
 				Object key = ( ( Map.Entry ) actualValue ).getKey();
-				if ( INDEXABLE_CLASS.contains( key.getClass() ) ) {
+				if ( VALID_MAP_INDEX_CLASSES.contains( key.getClass() ) ) {
 					propertyIndex = key.toString();
 				}
 				actualValue = ( ( Map.Entry ) actualValue ).getValue();
@@ -259,7 +274,7 @@
 
 		// if no group is specified use the default
 		if ( groups.length == 0 ) {
-			groups = DEFAULT_GROUP;
+			groups = DEFAULT_GROUP_ARRAY;
 		}
 
 		List<Class<?>> expandedGroups;
@@ -312,7 +327,7 @@
 
 		// if no group is specified use the default
 		if ( groups.length == 0 ) {
-			groups = DEFAULT_GROUP;
+			groups = DEFAULT_GROUP_ARRAY;
 		}
 
 		List<Class<?>> expandedGroups;

Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/Group.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/Group.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/Group.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,85 @@
+// $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.group;
+
+/**
+ * Encapsulates a single group.
+ *
+ * @author Hardy Ferentschik
+ */
+public class Group {
+	private Class<?> group;
+	private Class<?> sequence;
+
+	public Group(Class<?> group) {
+		this( group, null );
+	}
+
+	public Group(Class<?> group, Class<?> sequence) {
+		this.group = group;
+		this.sequence = sequence;
+	}
+
+	public Class<?> getGroup() {
+		return group;
+	}
+
+	public boolean partOfSequence() {
+		return sequence != null;
+	}
+
+	public Class<?> getSequence() {
+		return sequence;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if ( this == o ) {
+			return true;
+		}
+		if ( o == null || getClass() != o.getClass() ) {
+			return false;
+		}
+
+		Group group1 = ( Group ) o;
+
+		if ( group != null ? !group.equals( group1.group ) : group1.group != null ) {
+			return false;
+		}
+		if ( sequence != null ? !sequence.equals( group1.sequence ) : group1.sequence != null ) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		int result = group != null ? group.hashCode() : 0;
+		result = 31 * result + ( sequence != null ? sequence.hashCode() : 0 );
+		return result;
+	}
+
+	@Override
+	public String toString() {
+		return "Group{" +
+				"group=" + group +
+				", sequence=" + sequence +
+				'}';
+	}
+}


Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/Group.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChain.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChain.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChain.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,99 @@
+// $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.group;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An instance of <code>GroupExecutionChain</code> defines the order in to validate groups during the validation process.
+ *
+ * @author Hardy Ferentschik
+ */
+public class GroupChain {
+
+	private List<Group> groupList = new ArrayList<Group>();
+
+	private int nextGroupPointer = 0;
+
+
+	/**
+	 * @return Returns <code>true</code> if there is another group in the chain <code>false</code> otherwise.
+	 */
+	public boolean hasNext() {
+		return nextGroupPointer <= groupList.size();
+	}
+
+	/**
+	 * @return Returns the next group in the chain or <code>null</code> if there is none.
+	 */
+	public Group next() {
+		if ( hasNext() ) {
+			return groupList.get( nextGroupPointer++ );
+		}
+		else {
+			return null;
+		}
+	}
+
+	/**
+	 * @return The number of groups in this chain.
+	 */
+	public int size() {
+		return groupList.size();
+	}
+
+	public boolean containsSequence(Class<?> groupSequence) {
+		boolean result = false;
+		for ( Group group : groupList ) {
+			if ( groupSequence.getName().equals( group.getSequence() ) ) {
+				result = true;
+				break;
+			}
+		}
+		return result;
+	}
+
+	void insertGroup(Group group) {
+		if ( nextGroupPointer != 0 ) {
+			throw new RuntimeException( "Trying to modify the GroupChain while iterating." );
+		}
+
+		if ( !groupList.contains( group ) ) {
+			groupList.add( group );
+		}
+	}
+
+	void insertSequence(List<Group> groups) {
+		if ( groups == null || groups.size() == 0 ) {
+			return;
+		}
+
+		if ( !containsSequence( groups.get( 0 ).getSequence() ) ) {
+			groupList.addAll( groups );
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "GroupChain{" +
+				"groupList=" + groupList +
+				", nextGroupPointer=" + nextGroupPointer +
+				'}';
+	}
+}
\ No newline at end of file


Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChain.java
___________________________________________________________________
Name: svn:keywords
   + Id

Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChainGenerator.java (from rev 15990, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupExecutionOrder.java)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChainGenerator.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupChainGenerator.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,95 @@
+// $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.group;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.GroupSequence;
+import javax.validation.ValidationException;
+
+/**
+ * Used to determine the execution order.
+ *
+ * @author Hardy Ferentschik
+ */
+public class GroupChainGenerator {
+
+	private final Map<Class<?>, List<Group>> resolvedSequences = new HashMap<Class<?>, List<Group>>();
+
+	public GroupChain getGroupChainFor(Set<Class<?>> groups) {
+		if ( groups == null || groups.size() == 0 ) {
+			throw new IllegalArgumentException( "At least one group has to be specified." );
+		}
+
+		for ( Class<?> clazz : groups ) {
+			if ( !clazz.isInterface() ) {
+				throw new ValidationException( "A group has to be an interface. " + clazz.getName() + " is not." );
+			}
+		}
+
+		GroupChain chain = new GroupChain();
+		for ( Class<?> clazz : groups ) {
+			if ( clazz.getAnnotation( GroupSequence.class ) == null ) { // normal clazz
+				Group group = new Group( clazz );
+				chain.insertGroup( group );
+			}
+			else {
+				insertSequence( clazz, chain );
+			}
+		}
+
+		return chain;
+	}
+
+	private void insertSequence(Class<?> clazz, GroupChain chain) {
+		List<Group> sequence;
+		if ( resolvedSequences.containsKey( clazz ) ) {
+			sequence = resolvedSequences.get( clazz );
+		}
+		else {
+			sequence = resolveSequence( clazz, new ArrayList<Class<?>>() );
+		}
+		chain.insertSequence( sequence );
+	}
+
+	private List<Group> resolveSequence(Class<?> group, List<Class<?>> processedSequences) {
+		if ( processedSequences.contains( group ) ) {
+			throw new ValidationException( "Cyclic dependecy in group definition" );
+		}
+		else {
+			processedSequences.add( group );
+		}
+		List<Group> resolvedGroupSequence = new ArrayList<Group>();
+		GroupSequence sequenceAnnotation = group.getAnnotation( GroupSequence.class );
+		Class<?>[] sequenceArray = sequenceAnnotation.sequence();
+		for ( Class clazz : sequenceArray ) {
+			if ( clazz.getAnnotation( GroupSequence.class ) == null ) {
+				resolvedGroupSequence.add( new Group( clazz, group ) );
+			}
+			else {
+				List<Group> tmpSequence = resolveSequence( clazz, processedSequences );
+				resolvedGroupSequence.addAll( tmpSequence );
+			}
+		}
+		resolvedSequences.put( group, resolvedGroupSequence );
+		return resolvedGroupSequence;
+	}
+}

Deleted: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupExecutionOrder.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupExecutionOrder.java	2009-02-18 08:07:43 UTC (rev 15994)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/group/GroupExecutionOrder.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -1,26 +0,0 @@
-// $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.group;
-
-/**
- * Used to determine the execution order if there is one or more group or group sequences are specified.
- *
- * @author Hardy Ferentschik
- */
-public class GroupExecutionOrder {
-}

Deleted: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/GroupTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/GroupTest.java	2009-02-18 08:07:43 UTC (rev 15994)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/GroupTest.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -1,181 +0,0 @@
-// $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.HashSet;
-import java.util.Set;
-import javax.validation.ConstraintViolation;
-import javax.validation.Validator;
-import javax.validation.groups.Default;
-
-import static org.junit.Assert.assertEquals;
-import org.junit.Test;
-
-import org.hibernate.validation.eg.Animal;
-import org.hibernate.validation.eg.Author;
-import org.hibernate.validation.eg.Book;
-import org.hibernate.validation.eg.DefaultAlias;
-import org.hibernate.validation.eg.Dictonary;
-import org.hibernate.validation.eg.groups.First;
-import org.hibernate.validation.eg.groups.Last;
-import org.hibernate.validation.eg.groups.Second;
-import org.hibernate.validation.util.TestUtil;
-
-/**
- * Tests for the implementation of <code>Validator</code>.
- *
- * @author Hardy Ferentschik
- */
-public class GroupTest {
-
-	@Test
-	public void testGroups() {
-		Validator validator = TestUtil.getValidator();
-
-		Author author = new Author();
-		author.setLastName( "" );
-		author.setFirstName( "" );
-		Book book = new Book();
-		book.setTitle( "" );
-		book.setAuthor( author );
-
-		Set<ConstraintViolation<Book>> constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
-		assertEquals( "Wrong number of constraints", 3, constraintViolations.size() );
-
-		author.setFirstName( "Gavin" );
-		author.setLastName( "King" );
-
-		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
-		ConstraintViolation constraintViolation = constraintViolations.iterator().next();
-		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
-		assertEquals( "Wrong message", "may not be empty", constraintViolation.getMessage() );
-		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
-		assertEquals( "Wrong value", book.getTitle(), constraintViolation.getInvalidValue() );
-		assertEquals( "Wrong propertyName", "title", constraintViolation.getPropertyPath() );
-
-		book.setTitle( "Hibernate Persistence with JPA" );
-		book.setSubtitle( "Revised Edition of Hibernate in Action" );
-
-		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
-		constraintViolation = constraintViolations.iterator().next();
-		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
-		assertEquals( "Wrong message", "length must be between 0 and 30", constraintViolation.getMessage() );
-		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
-		assertEquals( "Wrong value", book.getSubtitle(), constraintViolation.getInvalidValue() );
-		assertEquals( "Wrong propertyName", "subtitle", constraintViolation.getPropertyPath() );
-
-		book.setSubtitle( "Revised Edition" );
-		author.setCompany( "JBoss a divison of RedHat" );
-
-		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
-		constraintViolation = constraintViolations.iterator().next();
-		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
-		assertEquals( "Wrong message", "length must be between 0 and 20", constraintViolation.getMessage() );
-		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
-		assertEquals( "Wrong value", author.getCompany(), constraintViolation.getInvalidValue() );
-		assertEquals( "Wrong propertyName", "author.company", constraintViolation.getPropertyPath() );
-
-		author.setCompany( "JBoss" );
-
-		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
-		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
-	}
-
-	@Test
-	public void testDefaultGroupSequence() {
-		Validator validator = TestUtil.getValidator();
-
-		Author author = new Author();
-		author.setLastName( "" );
-		author.setFirstName( "" );
-		Book book = new Book();
-		book.setAuthor( author );
-
-		Set<ConstraintViolation<Book>> constraintViolations = validator.validate( book, Default.class );
-		assertEquals( "Wrong number of constraints", 2, constraintViolations.size() );
-
-		author.setFirstName( "Gavin" );
-		author.setLastName( "King" );
-
-		constraintViolations = validator.validate( book, Default.class );
-		ConstraintViolation constraintViolation = constraintViolations.iterator().next();
-		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
-		assertEquals( "Wrong message", "may not be null", constraintViolation.getMessage() );
-		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
-		assertEquals( "Wrong value", book.getTitle(), constraintViolation.getInvalidValue() );
-		assertEquals( "Wrong propertyName", "title", constraintViolation.getPropertyPath() );
-
-		book.setTitle( "Hibernate Persistence with JPA" );
-		book.setSubtitle( "Revised Edition of Hibernate in Action" );
-
-		constraintViolations = validator.validate( book, Default.class );
-		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
-
-		book.setSubtitle( "Revised Edition" );
-		author.setCompany( "JBoss a divison of RedHat" );
-
-		constraintViolations = validator.validate( book, Default.class );
-		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
-
-		author.setCompany( "JBoss" );
-
-		constraintViolations = validator.validate( book, Default.class );
-		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
-	}
-
-	@Test
-	public void testGroupSequences() {
-		Validator validator = TestUtil.getValidator();
-
-		Dictonary dictonary = new Dictonary();
-		dictonary.setTitle( "English - German" );
-		Author author = new Author();
-		author.setLastName( "-" );
-		author.setFirstName( "-" );
-		author.setCompany( "Langenscheidt Publ." );
-		dictonary.setAuthor( author );
-
-		Set<ConstraintViolation<Dictonary>> constraintViolations = validator.validate( dictonary, DefaultAlias.class );
-		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
-	}
-
-	@Test
-	public void testValidationFailureInMultipleGroups() {
-		Validator validator = TestUtil.getValidator();
-		Animal elepfant = new Animal();
-		elepfant.setName( "" );
-		elepfant.setDomain( Animal.Domain.EUKARYOTA );
-
-		Set<ConstraintViolation<Animal>> constraintViolations = validator.validate( elepfant, First.class, Second.class );
-		assertEquals(
-				"The should be two invalid constraints since the same propertyName gets validated in both groups",
-				1,
-				constraintViolations.size()
-		);
-
-		ConstraintViolation constraintViolation = constraintViolations.iterator().next();
-		Set<Class<?>> expected = new HashSet<Class<?>>();
-		expected.add( First.class );
-		expected.add( Second.class );
-		assertEquals(
-				"The constraint should be invalid for both groups",
-				expected,
-				constraintViolation.getGroups()
-		);
-	}
-}
\ No newline at end of file

Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/Address.java (from rev 15989, beanvalidation/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s3/s4/Address.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/Address.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/Address.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,35 @@
+package org.hibernate.validation.engine.group;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import javax.validation.GroupSequence;
+import javax.validation.groups.Default;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at ZipCodeCoherenceChecker(groups = Address.HighLevelCoherence.class)
+public class Address {
+	@NotNull @Size(max = 50)
+	private String street1;
+
+	@ZipCode
+	private String zipcode;
+
+	@NotNull
+	@Size(max = 30)
+	private String city;
+
+	/**
+	 * Check conherence on the overall object
+	 * Needs basic checking to be green first
+	 */
+	public interface HighLevelCoherence {}
+
+	/**
+	 * Check both basic constraints and high level ones.
+	 * High level constraints are not checked if basic constraints fail.
+	 */
+	@GroupSequence(sequence = {Default.class, HighLevelCoherence.class})
+	public interface Complete {}
+}
\ No newline at end of file

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,27 @@
+// $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.group;
+
+import javax.validation.GroupSequence;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at GroupSequence(sequence = CyclicGroupSequence.class)
+public interface CyclicGroupSequence {
+}
\ No newline at end of file


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence1.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence1.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence1.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,27 @@
+// $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.group;
+
+import javax.validation.GroupSequence;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at GroupSequence(sequence = CyclicGroupSequence2.class)
+public interface CyclicGroupSequence1 {
+}


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence1.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence2.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence2.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence2.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,27 @@
+// $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.group;
+
+import javax.validation.GroupSequence;
+
+/**
+ * @author Hardy Ferentschik
+ */
+ at GroupSequence( sequence = CyclicGroupSequence1.class)
+public interface CyclicGroupSequence2 {
+}
\ No newline at end of file


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/CyclicGroupSequence2.java
___________________________________________________________________
Name: svn:keywords
   + Id

Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupChainGeneratorTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupChainGeneratorTest.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupChainGeneratorTest.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,115 @@
+// $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.group;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.validation.ValidationException;
+import javax.validation.groups.Default;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.hibernate.validation.eg.groups.First;
+import org.hibernate.validation.eg.groups.Last;
+import org.hibernate.validation.eg.groups.Second;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class GroupChainGeneratorTest {
+
+	GroupChainGenerator generator;
+
+	@Before
+	public void init() {
+		generator = new GroupChainGenerator();
+	}
+
+	@Test(expected = ValidationException.class)
+	public void testGroupChainForNonInterface() {
+		Set<Class<?>> groups = new HashSet<Class<?>>();
+		groups.add( String.class );
+		generator.getGroupChainFor( groups );
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testGroupChainForNull() {
+		generator.getGroupChainFor( null );
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testGroupChainForEmptySet() {
+		generator.getGroupChainFor( new HashSet<Class<?>>() );
+	}
+
+	@Test(expected = ValidationException.class)
+	public void testCyclicGroupSequences() {
+		Set<Class<?>> groups = new HashSet<Class<?>>();
+		groups.add( CyclicGroupSequence1.class );
+		generator.getGroupChainFor( groups );
+	}
+
+	@Test(expected = ValidationException.class)
+	public void testCyclicGroupSequence() {
+		Set<Class<?>> groups = new HashSet<Class<?>>();
+		groups.add( CyclicGroupSequence.class );
+		generator.getGroupChainFor( groups );
+	}
+
+	@Test
+	public void testGroupDuplicates() {
+		Set<Class<?>> groups = new HashSet<Class<?>>();
+		groups.add( First.class );
+		groups.add( Second.class );
+		groups.add( Last.class );
+		GroupChain chain = generator.getGroupChainFor( groups );
+		assertEquals( "Wrong number of groups", 3, chain.size() );
+
+		groups.clear();
+		groups.add( First.class );
+		groups.add( First.class );
+		chain = generator.getGroupChainFor( groups );
+		assertEquals( "Wrong number of groups", 1, chain.size() );
+
+		groups.clear();
+		groups.add( First.class );
+		groups.add( Last.class );
+		groups.add( First.class );
+		chain = generator.getGroupChainFor( groups );
+		assertEquals( "Wrong number of groups", 2, chain.size() );
+	}
+
+	@Test
+	public void testSequenceResolution() {
+		Set<Class<?>> groups = new HashSet<Class<?>>();
+		groups.add( Address.Complete.class );
+		GroupChain chain = generator.getGroupChainFor( groups );
+		assertEquals( "Wrong number of groups", 2, chain.size() );
+
+		assertTrue( "Should have more groups", chain.hasNext() );
+		assertEquals( "Wrong group", Default.class, chain.next().getGroup() );
+
+		assertTrue( "Should have more groups", chain.hasNext() );
+		assertEquals( "Wrong group", Address.HighLevelCoherence.class, chain.next().getGroup() );
+
+		assertTrue( "There should be no more groups", chain.hasNext() );
+	}
+}


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupChainGeneratorTest.java
___________________________________________________________________
Name: svn:keywords
   + Id

Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupTest.java (from rev 15990, validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/GroupTest.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupTest.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupTest.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,181 @@
+// $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.group;
+
+import java.util.HashSet;
+import java.util.Set;
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import javax.validation.groups.Default;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+import org.hibernate.validation.eg.Animal;
+import org.hibernate.validation.eg.Author;
+import org.hibernate.validation.eg.Book;
+import org.hibernate.validation.eg.DefaultAlias;
+import org.hibernate.validation.eg.Dictonary;
+import org.hibernate.validation.eg.groups.First;
+import org.hibernate.validation.eg.groups.Last;
+import org.hibernate.validation.eg.groups.Second;
+import org.hibernate.validation.util.TestUtil;
+
+/**
+ * Tests for the implementation of <code>Validator</code>.
+ *
+ * @author Hardy Ferentschik
+ */
+public class GroupTest {
+
+	@Test
+	public void testGroups() {
+		Validator validator = TestUtil.getValidator();
+
+		Author author = new Author();
+		author.setLastName( "" );
+		author.setFirstName( "" );
+		Book book = new Book();
+		book.setTitle( "" );
+		book.setAuthor( author );
+
+		Set<ConstraintViolation<Book>> constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
+		assertEquals( "Wrong number of constraints", 3, constraintViolations.size() );
+
+		author.setFirstName( "Gavin" );
+		author.setLastName( "King" );
+
+		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
+		ConstraintViolation constraintViolation = constraintViolations.iterator().next();
+		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+		assertEquals( "Wrong message", "may not be empty", constraintViolation.getMessage() );
+		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
+		assertEquals( "Wrong value", book.getTitle(), constraintViolation.getInvalidValue() );
+		assertEquals( "Wrong propertyName", "title", constraintViolation.getPropertyPath() );
+
+		book.setTitle( "Hibernate Persistence with JPA" );
+		book.setSubtitle( "Revised Edition of Hibernate in Action" );
+
+		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
+		constraintViolation = constraintViolations.iterator().next();
+		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+		assertEquals( "Wrong message", "length must be between 0 and 30", constraintViolation.getMessage() );
+		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
+		assertEquals( "Wrong value", book.getSubtitle(), constraintViolation.getInvalidValue() );
+		assertEquals( "Wrong propertyName", "subtitle", constraintViolation.getPropertyPath() );
+
+		book.setSubtitle( "Revised Edition" );
+		author.setCompany( "JBoss a divison of RedHat" );
+
+		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
+		constraintViolation = constraintViolations.iterator().next();
+		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+		assertEquals( "Wrong message", "length must be between 0 and 20", constraintViolation.getMessage() );
+		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
+		assertEquals( "Wrong value", author.getCompany(), constraintViolation.getInvalidValue() );
+		assertEquals( "Wrong propertyName", "author.company", constraintViolation.getPropertyPath() );
+
+		author.setCompany( "JBoss" );
+
+		constraintViolations = validator.validate( book, First.class, Second.class, Last.class );
+		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
+	}
+
+	@Test
+	public void testDefaultGroupSequence() {
+		Validator validator = TestUtil.getValidator();
+
+		Author author = new Author();
+		author.setLastName( "" );
+		author.setFirstName( "" );
+		Book book = new Book();
+		book.setAuthor( author );
+
+		Set<ConstraintViolation<Book>> constraintViolations = validator.validate( book, Default.class );
+		assertEquals( "Wrong number of constraints", 2, constraintViolations.size() );
+
+		author.setFirstName( "Gavin" );
+		author.setLastName( "King" );
+
+		constraintViolations = validator.validate( book, Default.class );
+		ConstraintViolation constraintViolation = constraintViolations.iterator().next();
+		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+		assertEquals( "Wrong message", "may not be null", constraintViolation.getMessage() );
+		assertEquals( "Wrong root entity", book, constraintViolation.getRootBean() );
+		assertEquals( "Wrong value", book.getTitle(), constraintViolation.getInvalidValue() );
+		assertEquals( "Wrong propertyName", "title", constraintViolation.getPropertyPath() );
+
+		book.setTitle( "Hibernate Persistence with JPA" );
+		book.setSubtitle( "Revised Edition of Hibernate in Action" );
+
+		constraintViolations = validator.validate( book, Default.class );
+		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+
+		book.setSubtitle( "Revised Edition" );
+		author.setCompany( "JBoss a divison of RedHat" );
+
+		constraintViolations = validator.validate( book, Default.class );
+		assertEquals( "Wrong number of constraints", 1, constraintViolations.size() );
+
+		author.setCompany( "JBoss" );
+
+		constraintViolations = validator.validate( book, Default.class );
+		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
+	}
+
+	@Test
+	public void testGroupSequences() {
+		Validator validator = TestUtil.getValidator();
+
+		Dictonary dictonary = new Dictonary();
+		dictonary.setTitle( "English - German" );
+		Author author = new Author();
+		author.setLastName( "-" );
+		author.setFirstName( "-" );
+		author.setCompany( "Langenscheidt Publ." );
+		dictonary.setAuthor( author );
+
+		Set<ConstraintViolation<Dictonary>> constraintViolations = validator.validate( dictonary, DefaultAlias.class );
+		assertEquals( "Wrong number of constraints", 0, constraintViolations.size() );
+	}
+
+	@Test
+	public void testValidationFailureInMultipleGroups() {
+		Validator validator = TestUtil.getValidator();
+		Animal elepfant = new Animal();
+		elepfant.setName( "" );
+		elepfant.setDomain( Animal.Domain.EUKARYOTA );
+
+		Set<ConstraintViolation<Animal>> constraintViolations = validator.validate( elepfant, First.class, Second.class );
+		assertEquals(
+				"The should be two invalid constraints since the same propertyName gets validated in both groups",
+				1,
+				constraintViolations.size()
+		);
+
+		ConstraintViolation constraintViolation = constraintViolations.iterator().next();
+		Set<Class<?>> expected = new HashSet<Class<?>>();
+		expected.add( First.class );
+		expected.add( Second.class );
+		assertEquals(
+				"The constraint should be invalid for both groups",
+				expected,
+				constraintViolation.getGroups()
+		);
+	}
+}
\ No newline at end of file


Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/GroupTest.java
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:mergeinfo
   + 

Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCode.java (from rev 15989, beanvalidation/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s3/s4/ZipCode.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCode.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCode.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,7 @@
+package org.hibernate.validation.engine.group;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public @interface ZipCode {
+}
\ No newline at end of file

Copied: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCodeCoherenceChecker.java (from rev 15989, beanvalidation/trunk/validation-api/src/test/java/org/hibernate/validator/spec/s3/s4/ZipCodeCoherenceChecker.java)
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCodeCoherenceChecker.java	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/group/ZipCodeCoherenceChecker.java	2009-02-18 14:47:10 UTC (rev 15995)
@@ -0,0 +1,19 @@
+package org.hibernate.validation.engine.group;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Target({ TYPE, ANNOTATION_TYPE })
+ at Retention(RUNTIME)
+ at Documented
+public @interface ZipCodeCoherenceChecker {
+	public abstract String message() default "{validator.zipCodeCoherenceChecker}";
+	public abstract Class<?>[] groups() default {};
+}
\ No newline at end of file




More information about the hibernate-commits mailing list