[hibernate-commits] Hibernate SVN: r16854 - beanvalidation/trunk/validation-api/src/main/java/javax/validation.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Jun 22 09:54:37 EDT 2009


Author: epbernard
Date: 2009-06-22 09:54:37 -0400 (Mon, 22 Jun 2009)
New Revision: 16854

Added:
   beanvalidation/trunk/validation-api/src/main/java/javax/validation/Path.java
Modified:
   beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorContext.java
   beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintViolation.java
   beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java
Log:
BVAL-143 Describe path with an object model

Modified: beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorContext.java
===================================================================
--- beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorContext.java	2009-06-22 13:53:50 UTC (rev 16853)
+++ beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintValidatorContext.java	2009-06-22 13:54:37 UTC (rev 16854)
@@ -27,52 +27,190 @@
 	 * Disable the default error message and default ConstraintViolation object generation.
 	 * Useful to set a different error message or generate a ConstraintViolation based on
 	 * a different property
-	 *
-	 * @see #addError(String)
-	 * @see #addError(String, String)
 	 */
 	void disableDefaultError();
 
 	/**
 	 * @return the current uninterpolated default message
 	 */
-	String getDefaultErrorMessage();
+	String getDefaultErrorMessageTemplate();
 
 	/**
-	 * Add a new error message. This error message will be interpolated.
+	 * Return an error builder building an error allowing to optionally associate
+	 * the error to a sub path.
+	 * The error message will be interpolated.
 	 * <p/>
+	 * To create the error, one must call either one of
+	 * the #addError method available in one of the
+	 * interfaces of the fluent API.
+	 * If another method is called after #addError() on
+	 * ErrorBuilder or any of its associated nested interfaces
+	 * an IllegalStateException is raised.
+	 * <p/>
 	 * If <code>isValid<code> returns <code>false</code>, a <code>ConstraintViolation</code> object will be built
-	 * per error message including the default one unless {@link #disableDefaultError()} has been called.
+	 * per error including the default one unless {@link #disableDefaultError()} has been called.
 	 * <p/>
-	 * Aside from the error message, <code>ConstraintViolation</code> objects generated from such a call
-	 * contain the same contextual information (root bean, path and so on)
+	 * <code>ConstraintViolation</code> objects generated from such a call
+	 * contain the same contextual information (root bean, path and so on) unless
+	 * the path has been overriden.
 	 * <p/>
-	 * This method can be called multiple times. One <code>ConstraintViolation</code> instance per
-	 * call is created.
+	 * To create a different error, a new error builder has to be retrieved from
+	 * ConstraintValidatorContext
 	 *
-	 * @param message new uninterpolated error message.
+	 * Here are a few usage examples:
+	 * <pre>//create new error with the default path the constraint
+	 * //is located on
+	 * context.buildErrorWithMessageTemplate( "way too long" )
+	 *             .addError();
+	 *
+	 * //create new error in the "street" subnode of the default
+	 * //path the constraint is located on
+	 * context.buildErrorWithMessageTemplate( "way too long" )
+	 *              .inSubNode( "street" )
+	 *              .addError();
+	 *
+	 * //create new error in the "addresses["home"].city.name
+	 * //subnode of the default path the constraint is located on
+	 * context.buildErrorWithMessageTemplate( "this detail is wrong" )
+	 *              .inSubNode( "addresses" )
+	 *              .inSubNode( "country" )
+	 *                  .inIterable().atKey( "home" )
+	 *              .inSubNode( "name" )
+	 *              .addError();
+	 * </pre>
+	 *
+	 * @param messageTemplate new uninterpolated error message.
 	 */
-	void addError(String message);
+	ErrorBuilder buildErrorWithMessageTemplate(String messageTemplate);
 
 	/**
-	 * Add a new error message to a given sub property <code>property</code>. The subproperty
-	 * is relative to the path to the bean or property hosting the constraint.
+	 * Error builder allowing to optionally associate
+	 * the error to a sub path.
 	 *
-	 * This error message will be interpolated.
-	 * <p/>
-	 * If <code>isValid</code> returns <code>false</code>, a <code>ConstraintViolation</code> object will be built
-	 * per error message including the default one unless {@link #disableDefaultError()}
-	 * has been called.
-	 * <p/>
-	 * Aside from the error message and the property path, <code>ConstraintViolation</code> objects
-	 * generated from such a call contain the same contextual information
-	 * (root bean, leaf bean etc)
-	 * <p/>
-	 * This method can be called multiple times. One <code>ConstraintViolation</code> instance per
-	 * call is created.
-	 *
-	 * @param message new uninterpolated error message.
-	 * @param property property name the </code>ConstraintViolation</code> is targeting.
+	 * To create the error, one must call either one of
+	 * the #addError method available in one of the
+	 * interfaces of the fluent API.
+	 * If another method is called after #addError() on
+	 * ErrorBuilder or any of its associated objects
+	 * an IllegalStateException is raised.
+	 * 
 	 */
-	void addError(String message, String property);
+	interface ErrorBuilder {
+		/**
+		 * Add a subNode to the path the error will be associated to
+		 *
+		 * @param name property
+		 * @return a builder representing the first level node
+		 */
+		NodeBuilder inSubNode(String name);
+
+		/**
+		 * Add the new error report to be generated if the
+		 * constraint validator mark the value as invalid.
+		 * Methods of this ErrorBuilder instance and its nested
+		 * objects returns IllegalStateException from now on.
+		 *
+		 * @return ConstraintValidatorContext instance the ErrorBuilder comes from 
+		 */
+		ConstraintValidatorContext addError();
+
+		/**
+		 * Represent asubnode whose context is known
+		 * (ie index, key and isInIterable)
+		 */
+		interface NodeBuilder {
+			/**
+			 * Add a subNode to the path the error will be associated to
+			 *
+			 * @param name property
+			 * @return a builder representing this node
+			 */
+			InIterableNodeBuilder inSubNode(String name);
+
+			/**
+			 * Add the new error report to be generated if the
+			 * constraint validator mark the value as invalid.
+			 * Methods of the ErrorBuilder instance this object comes
+			 * from and the error builder nested
+			 * objects returns IllegalStateException from now on.
+			 *
+			 * @return ConstraintValidatorContext instance the ErrorBuilder comes from
+			 */
+			ConstraintValidatorContext addError();
+		}
+
+		/**
+		 * Represent a subnode whose context is
+		 * configurable (ie index, key and isInIterable)
+		 */
+		interface InIterableNodeBuilder {
+			/**
+			 * Mark the node as being in an Iterable or a Map
+			 * @return a builder representing iterable details
+			 */
+			InIterablePropertiesBuilder inIterable();
+
+			/**
+			 * Add a subNode to the path the error will be associated to
+			 *
+			 * @param name property
+			 * @return a builder representing this node
+			 */
+			InIterableNodeBuilder inSubNode(String name);
+
+			/**
+			 * Add the new error report to be generated if the
+			 * constraint validator mark the value as invalid.
+			 * Methods of the ErrorBuilder instance this object comes
+			 * from and the error builder nested
+			 * objects returns IllegalStateException from now on.
+			 *
+			 * @return ConstraintValidatorContext instance the ErrorBuilder comes from
+			 */
+			ConstraintValidatorContext addError();
+		}
+
+		/**
+		 * Represent choices for a node which is
+		 * in an Iterator or Map.
+		 * If the iterator is an indexed collection or a map,
+		 * the index or the key should be set.
+		 */
+		interface InIterablePropertiesBuilder {
+			/**
+			 * Define the key the object is into the Map
+			 *
+			 * @param key map key
+			 * @return a builder representing the current node
+			 */
+			NodeBuilder atKey(Object key);
+
+			/**
+			 * Define the index the object is into the List or array
+			 *
+			 * @param index index
+			 * @return a builder representing the current node
+			 */
+			NodeBuilder atIndex(Integer index);
+
+			/**
+			 * Add a subNode to the path the error will be associated to
+			 *
+			 * @param name property
+			 * @return a builder representing this node
+			 */
+			InIterableNodeBuilder inSubNode(String name);
+
+			/**
+			 * Add the new error report to be generated if the
+			 * constraint validator mark the value as invalid.
+			 * Methods of the ErrorBuilder instance this object comes
+			 * from and the error builder nested
+			 * objects returns IllegalStateException from now on.
+			 *
+			 * @return ConstraintValidatorContext instance the ErrorBuilder comes from
+			 */
+			ConstraintValidatorContext addError();
+		}
+	}
 }

Modified: beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintViolation.java
===================================================================
--- beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintViolation.java	2009-06-22 13:53:50 UTC (rev 16853)
+++ beanvalidation/trunk/validation-api/src/main/java/javax/validation/ConstraintViolation.java	2009-06-22 13:54:37 UTC (rev 16854)
@@ -18,6 +18,7 @@
 package javax.validation;
 
 import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.Path;
 
 /**
  * Describe a constraint violation. This object describe the error context as
@@ -59,10 +60,9 @@
 	Object getLeafBean();
 
 	/**
-	 * @return the property path to the value from <code>rootBean</code>
-	 *         <code>null</code> if the value is the <code>rootBean<code> itself.
+	 * @return the property path to the value from <code>rootBean</code>.
 	 */
-	String getPropertyPath();
+	Path getPropertyPath();
 
 	/**
 	 * @return the value failing to pass the constraint.

Added: beanvalidation/trunk/validation-api/src/main/java/javax/validation/Path.java
===================================================================
--- beanvalidation/trunk/validation-api/src/main/java/javax/validation/Path.java	                        (rev 0)
+++ beanvalidation/trunk/validation-api/src/main/java/javax/validation/Path.java	2009-06-22 13:54:37 UTC (rev 16854)
@@ -0,0 +1,44 @@
+package javax.validation;
+
+/**
+ * Represent a navigation path from an object to another.
+ * Each path element is represented by a Node.
+ *
+ * The path corresponds to the succession of nodes
+ * in the order they are retured by the Iterator
+ *
+ * @author Emmanuel Bernard
+ */
+public interface Path extends Iterable<Path.Node> {
+
+	/**
+	 * Represents an element of a navigation path
+	 */
+	interface Node {
+		/**
+		 * Property name the node represents
+		 * or null if the leaf node and representing an entity
+		 * (in particular the node representing the root object
+		 * has its name null)
+		 */
+		String getName();
+
+		/**
+		 * True if the node represents an object contained in an Iterable
+		 * or in a Map.
+		 */
+		boolean isInIterable();
+
+		/**
+		 * The index the node is placed in if contained
+		 * in an array or List. Null otherwise.
+		 */
+		Integer getIndex();
+
+		/**
+		 * The key the node is placed in if contained
+		 * in a Map. Null otherwise.
+		 */
+		Object getKey();
+	}
+}

Modified: beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java
===================================================================
--- beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java	2009-06-22 13:53:50 UTC (rev 16853)
+++ beanvalidation/trunk/validation-api/src/main/java/javax/validation/TraversableResolver.java	2009-06-22 13:54:37 UTC (rev 16854)
@@ -18,6 +18,7 @@
 package javax.validation;
 
 import java.lang.annotation.ElementType;
+import javax.validation.Path;
 
 /**
  * Contract determining if a property can be accessed by the Bean Validation provider
@@ -32,11 +33,10 @@
 	 * Determine if Bean Validation is allowed to reach the property state
 	 *
 	 * @param traversableObject object hosting <code>traversableProperty</code>, null if validateValue is called
-	 * @param traversableProperty name of the traversable property.
+	 * @param traversableProperty the traversable property.
 	 * @param rootBeanType type of the root object passed to the Validator.
 	 * @param pathToTraversableObject path from the root object to
-	 *        <code>traversableObject</code> ("" if the <code>traversableObject</code> 
-	 *        is the root object)
+	 *        <code>traversableObject</code>
 	 *        (using the path specification defined by Bean Validator).
 	 * @param elementType either <code>FIELD</code> or <code>METHOD</code>.
 	 *
@@ -44,9 +44,9 @@
 	 *         <code>false</code> otherwise.
 	 */
 	boolean isReachable(Object traversableObject,
-						  String traversableProperty,
+						  Path.Node traversableProperty,
 						  Class<?> rootBeanType,
-						  String pathToTraversableObject,
+						  Path pathToTraversableObject,
 						  ElementType elementType);
 
 	/**
@@ -57,11 +57,10 @@
 	 * arguments and if the property is marked as <code>@Valid</code>
 	 *
 	 * @param traversableObject object hosting <code>traversableProperty</code>, null if validateValue is called
-	 * @param traversableProperty name of the traversable property.
+	 * @param traversableProperty the traversable property.
 	 * @param rootBeanType type of the root object passed to the Validator.
 	 * @param pathToTraversableObject path from the root object to
-	 *        <code>traversableObject</code> ("" if the <code>traversableObject</code>
-	 *        is the root object)
+	 *        <code>traversableObject</code>
 	 *        (using the path specification defined by Bean Validator).
 	 * @param elementType either <code>FIELD</code> or <code>METHOD</code>.
 	 *
@@ -69,8 +68,8 @@
 	 *         <code>false</code> otherwise.
 	 */
 	boolean isCascadable(Object traversableObject,
-						  String traversableProperty,
+						  Path.Node traversableProperty,
 						  Class<?> rootBeanType,
-						  String pathToTraversableObject,
+						  Path pathToTraversableObject,
 						  ElementType elementType);
 }




More information about the hibernate-commits mailing list