<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Here is the proposal I integrated in the spec. Main changes are in the email, I cannot attach the whole spec (too big for the mailing list) but if you ask me I will send it to you by email.</div><div><br></div><div>Review very much welcome.</div><div><br></div><div><br></div><div><span class="Apple-style-span" style="font-family: -webkit-sans-serif; font-size: 14px; "><div class="titlepage" style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "><h2 class="title" style="clear: both; font-family: sans-serif; color: rgb(0, 51, 153); font-size: 140%; margin-top: 10px; padding-top: 5px; font-weight: bold; ">2.1.&nbsp;Constraint annotation</h2></div></div><div style="font-family: sans-serif; font-size: 14px; "></div></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">A constraint on a JavaBean is expressed through one or more annotations. An annotation is considered a constraint definition if its retention policy contains&nbsp;<tt class="literal" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">RUNTIME</tt>&nbsp;and if the annotation itself is annotated with&nbsp;<tt class="literal" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">javax.validation.Constraint</tt>.</p><pre class="programlisting" style="font-size: 100%; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-color: rgb(244, 244, 244); font-family: monospace; width: auto; ">/**
 * Link between a constraint annotation and its constraint validation implementations.
 * &lt;p/>
 * A given constraint annotation should be annotated by a @Constraint
 * annotation which refers to its list of constraint validation implementation.
 *
 * @author Emmanuel Bernard (emmanuel at hibernate.org)
 * @author Gavin King
 * @author Hardy Ferentschik
 */
@Documented
@Target({ ANNOTATION_TYPE })
@Retention(RUNTIME)
public @interface Constraint {
        /**
         * ConstraintValidator classes must reference distinct target types.
         * If two validators refer to the same type, an exception will occur
         * 
         * @return aray of ConstraintValidator classes implementing the constraint
         */
        public Class&lt;? extends ConstraintValidator&lt;?,?>>[] validatedBy();
}</pre><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Constraint annotations can target any of the following&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ElementType</tt>s:</p><div class="itemizedlist" style="font-family: sans-serif; font-size: 14px; "><ul type="disc" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><tt class="literal" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">FIELD</tt>&nbsp;for constrained attributes</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><tt class="literal" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">METHOD</tt>&nbsp;for constrained getters</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><tt class="literal" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">TYPE</tt>&nbsp;for constrained beans</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><tt class="literal" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ANNOTATION_TYPE</tt>&nbsp;for constraints composing other constraints</p></li></ul></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">While other&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ElementType</tt>s are not forbidden, the provider does not have to recognize and process constraints placed on such types.</p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Since a given constraint definition applies to one or more specific Java types, the JavaDoc for the constraint annotation should clearly state which types are supported. Applying a constraint annotation to an incompatible type will raise a&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">UnexpectedTypeForConstraintException</tt>. Care should be taken on defining the list of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>. The type resolution algorithm (see&nbsp;<a href="file:///Users/manu/projects/specs/303/specbook/build/en/html_single/index.html#typevalidatorresolution" title="3.5.3.&nbsp;ConstraintValidator resolution algorithm" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); ">Section&nbsp;3.5.3, “ConstraintValidator resolution algorithm”</a>) could lead to exceptions due to ambiguity.</p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><br></p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">[...]</p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><br></p><div style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><br class="webkit-block-placeholder"></div><div class="titlepage" style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "><h2 class="title" style="clear: both; font-family: sans-serif; color: rgb(0, 51, 153); font-size: 140%; margin-top: 10px; padding-top: 5px; font-weight: bold; ">2.4.&nbsp;Constraint validation implementation</h2></div></div><div style="font-family: sans-serif; font-size: 14px; "></div></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">A constraint validation implementation performs the validation of a given constraint annotation for a given type. The implementation classes are specified by the&nbsp;<tt class="literal" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">validatedBy</tt>&nbsp;element of the<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Contraint</tt>&nbsp;annotation that decorates the constraint definition. The constraint validation implementation implements the&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;interface.</p><div class="example" style="font-family: sans-serif; font-size: 14px; "><a name="d0e560" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); "></a><p class="title" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); margin-top: 10px; padding-top: 5px; font-weight: bold; "><b style="font-family: sans-serif; font-size: 14px; ">Example&nbsp;2.10.&nbsp;ConstraintValidator interface</b></p><pre class="programlisting" style="font-size: 100%; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-color: rgb(244, 244, 244); font-family: monospace; width: auto; ">/**
 * Defines the logic to validate a given constraint A
 * for a given object type T.
 * Implementations must comply to the following restriction:
 * T must resolve to a non parameterized type
 *
 * @author Emmanuel Bernard
 * @author Hardy Ferentschik
 */
public interface ConstraintValidator&lt;A extends Annotation, T> {
        /**
         * Validator parameters for a given constraint definition
         * Annotations parameters are passed as key/value into parameters
         * &lt;p/>
         * This method is guaranteed to be called before any of the other Constraint
         * implementation methods
         *
         * @param constraintAnnotation parameters for a given constraint definition
         */
        void initialize(A constraintAnnotation);

        /**
         * Implement the validation constraint.
         * &lt;code>object&lt;/code> state must not be changed by a Constraint implementation
         *
         * @param object object to validate
         * @param constraintValidatorContext context in which the constraint is evaluated
         *
         * @return false if &lt;code>object&lt;/code> does not pass the constraint
         */
        boolean isValid(T object, ConstraintValidatorContext constraintValidatorContext);
}</pre></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Some restrictions apply on the generic type&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;(used in the&nbsp;<tt class="methodname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">isValid</tt>&nbsp;method). T must resolve in a non parameterized type:</p><div class="itemizedlist" style="font-family: sans-serif; font-size: 14px; "><ul type="disc" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">the type is not using generics</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">because the raw type is used instead of the generic version</p></li></ul></div><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in; font-family: sans-serif; font-size: 14px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; background-color: rgb(251, 218, 218); "><h3 class="title" style="font-family: sans-serif; color: rgb(0, 51, 153); font-size: 120%; margin-top: 10px; padding-top: 5px; font-weight: bold; ">Warning</h3><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Should we support unbounded wildcards?</p></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Here are some examples of valid definitions in&nbsp;<a href="file:///Users/manu/projects/specs/303/specbook/build/en/html_single/index.html#example-constraintsdefinitionimplementation-validationimplementation-validdef" title="Example&nbsp;2.11.&nbsp;Valid ConstraintValidator definitions" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); ">Example&nbsp;2.11, “Valid ConstraintValidator definitions”</a>.</p><div class="example" style="font-family: sans-serif; font-size: 14px; "><a name="example-constraintsdefinitionimplementation-validationimplementation-validdef" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); "></a><p class="title" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); margin-top: 10px; padding-top: 5px; font-weight: bold; "><b style="font-family: sans-serif; font-size: 14px; ">Example&nbsp;2.11.&nbsp;Valid ConstraintValidator definitions</b></p><pre class="programlisting" style="font-size: 100%; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-color: rgb(244, 244, 244); font-family: monospace; width: auto; ">//String is not making use of generics
public class SizeValidatorForString implements&lt;Size, String> {...}

//Collection uses generics but the raw type is used
public class SizeValidatorForCollection implements&lt;Size, Collection> {...}</pre></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">And some invalid definitions in&nbsp;<a href="file:///Users/manu/projects/specs/303/specbook/build/en/html_single/index.html#example-constraintsdefinitionimplementation-validationimplementation-invaliddef" title="Example&nbsp;2.12.&nbsp;Invalid ConstraintValidator definitions" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); ">Example&nbsp;2.12, “Invalid ConstraintValidator definitions”</a>.</p><div class="example" style="font-family: sans-serif; font-size: 14px; "><a name="example-constraintsdefinitionimplementation-validationimplementation-invaliddef" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); "></a><p class="title" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); margin-top: 10px; padding-top: 5px; font-weight: bold; "><b style="font-family: sans-serif; font-size: 14px; ">Example&nbsp;2.12.&nbsp;Invalid ConstraintValidator definitions</b></p><pre class="programlisting" style="font-size: 100%; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-color: rgb(244, 244, 244); font-family: monospace; width: auto; ">//parameterized type
public class SizeValidatorForString implements&lt;Size, Collection&lt;String> {...}

//parameterized type using unbounded wildcard
public class SizeValidatorForCollection implements&lt;Size, Collection&lt;?>> {...}

//parameterized type using bounded wildcard
public class SizeValidatorForCollection implements&lt;Size, Collection&lt;? extends Address>> {...}</pre></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in; font-family: sans-serif; font-size: 14px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; background-color: rgb(255, 255, 204); "><h3 class="title" style="font-family: sans-serif; color: rgb(0, 51, 153); font-size: 120%; margin-top: 10px; padding-top: 5px; font-weight: bold; ">Note</h3><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">This restriction is not a theoretical limitation and a future version of the specification will likely allow that in the future.</p><div><br></div><div><br></div><div><br></div></div><div><br class="webkit-block-placeholder"></div></span></div><div><br></div><div>[...]</div><div><br></div><div><br></div><div><span class="Apple-style-span" style="font-family: -webkit-sans-serif; font-size: 14px; "><div class="section" lang="en" style="font-family: sans-serif; font-size: 14px; "><div class="section" lang="en" style="font-family: sans-serif; font-size: 14px; "><div class="titlepage" style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "><h3 class="title" style="font-family: sans-serif; color: rgb(0, 51, 153); font-size: 120%; margin-top: 10px; padding-top: 5px; font-weight: bold; ">3.5.3.&nbsp;ConstraintValidator resolution algorithm</h3></div></div><div style="font-family: sans-serif; font-size: 14px; "></div></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">A constraint is associated to one or more&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;implementations. Each&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator&lt;A, T></tt>&nbsp;accepts the type&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>. The&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;executed depends on the type declared by the target hosting the constraint. For a given constraint evaluation, a single&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;is considered.</p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">If the constraint is hosted on a class or an interface, the targeted type is the class or the interface. If the constraint is hosted on a class attribute, the type of the attribute is the targeted type. If the constraint is hosted on a getter, the return type of the getter is the targeted type.</p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">The rules written below describe formally the following statement: the&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;chosen to validate a declared type&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;is the one where the type supported by the<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;is a supertype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;and where there is no other&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;whose supported type is a supertype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;and not a supertype of the chosen<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;supported type.</p><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">When validating a constraint A placed on a target declaring the type&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>, the following resolution rules apply.</p><div class="itemizedlist" style="font-family: sans-serif; font-size: 14px; "><ul type="disc" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Primitive types are considered equivalent to their respective primitive wrapper class.</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">A&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator&lt;A, U></tt>&nbsp;is said to be&nbsp;<span class="emphasis" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><em style="font-family: sans-serif; font-size: 14px; ">compliant</em></span>&nbsp;with&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;if&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;is a subtype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">U</tt>&nbsp;(according to the<a href="http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10" target="_top" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); ">&nbsp;Java Language Specification 3rd edition chapter 4.10 Subtyping</a>). Note that&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;is a subtype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">U</tt>&nbsp;if&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;=&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">U</tt>.</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">If no&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;compliant with&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;is found amongst the&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>s listed by the constraint&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">A</tt>, a&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">UnexpectedTypeForConstraintException</tt>&nbsp;is raised.</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">A&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator&lt;A, U></tt>&nbsp;compliant with&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;is considered&nbsp;<span class="emphasis" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><em style="font-family: sans-serif; font-size: 14px; ">strictly more specific</em></span>&nbsp;than a&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator&lt;A, V></tt>&nbsp;compliant with&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;if&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">U</tt>&nbsp;is a strict subtype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">V</tt>.&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">U</tt>&nbsp;is a strict subtype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">V</tt>&nbsp;if&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">U</tt>&nbsp;is a subtype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">V</tt>&nbsp;and&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">U</tt>&nbsp;!=&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">V</tt>&nbsp;(according to the<a href="http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10" target="_top" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); ">Java Language Specification 3rd edition chapter 4.10 Subtyping</a>).</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">A&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator&lt;A, U></tt>&nbsp;compliant with&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;is considered maximally specific if no other&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator&lt;A, V></tt>&nbsp;compliant with&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">T</tt>&nbsp;is strictly more specific than<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator&lt;A, U></tt>.</p></li><li style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); "><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">If more than one maximally specific&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;is found, a&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">AmbiguousConstraintUsageException</tt>&nbsp;is raised.</p></li></ul></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in; font-family: sans-serif; font-size: 14px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; background-color: rgb(255, 255, 204); "><h3 class="title" style="font-family: sans-serif; color: rgb(0, 51, 153); font-size: 120%; margin-top: 10px; padding-top: 5px; font-weight: bold; ">Note</h3><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">While the Java compiler itself cannot determine if a constraint declaration will lead to a&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">UnexpectedTypeForConstraintException</tt>&nbsp;or a<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">AmbiguousConstraintUsageException</tt>, rules can be statically checked. A tool such as an IDE or a Java 6 annotation processor can apply these rules and prevent a compilation in case of ambiguity. The specification encourages Bean Validation provider to provide such a tool to their users.</p></div><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Let's see a couple of declaration their respective&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;resolution. Assuming the following definitions:</p><pre class="programlisting" style="font-size: 100%; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-color: rgb(244, 244, 244); font-family: monospace; width: auto; ">[...]
@Constraint(validatedBy={
    SizeValidatorForCollection.class,
    SizeValidatorForSet.class,
    SizeValidatorForSerializable.class })
public @interface Size { ...}

public class SizeValidatorForCollection implements ConstraintValidator&lt;Size, Collection> { ... }
public class SizeValidatorForSet implements ConstraintValidator&lt;Size, Set> { ... }
public class SizeValidatorForSerializable implements ConstraintValidator&lt;Size, Serializable> { ... }

public interface SerializableCollection extends Serializable,  Collection {}</pre><p style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">The following resolutions occur.</p><div class="table" style="font-family: sans-serif; font-size: 14px; "><a name="d0e1999" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 204); "></a><p class="title" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); margin-top: 10px; padding-top: 5px; font-weight: bold; "><b style="font-family: sans-serif; font-size: 14px; ">Table&nbsp;3.1.&nbsp;Resolution of ConstraintValidator for various constraints declarations</b></p><table summary="Resolution of ConstraintValidator for various constraints
          declarations" border="1" style="font-family: sans-serif; font-size: 14px; border-collapse: collapse; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; empty-cells: hide; width: 100%; "><colgroup style="font-family: sans-serif; font-size: 14px; "><col align="center" style="font-family: sans-serif; font-size: 14px; "><col style="font-family: sans-serif; font-size: 14px; "></colgroup><thead style="font-family: sans-serif; font-size: 14px; "><tr style="font-family: sans-serif; font-size: 14px; "><th align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Declaration</th><th style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); ">Resolution</th></tr></thead><tbody style="font-family: sans-serif; font-size: 14px; "><tr style="font-family: sans-serif; font-size: 14px; "><td align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="code" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Size Collection getAddresses() { ... }</tt></td><td style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">SizeValidatorForCollection</tt>: direct match</td></tr><tr style="font-family: sans-serif; font-size: 14px; "><td align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="code" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Size Collection&lt;?> getAddresses() { ... }</tt></td><td style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">SizeValidatorForCollection</tt>:&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Collection</tt>&nbsp;is a direct supertype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Collection&lt;?></tt></td></tr><tr style="font-family: sans-serif; font-size: 14px; "><td align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="code" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Size Collection&lt;Address> getAddresses() { ... }</tt></td><td style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">SizeValidatorForCollection</tt>:&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Collection</tt>&nbsp;is a direct supertype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Collection&lt;Address></tt></td></tr><tr style="font-family: sans-serif; font-size: 14px; "><td align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="code" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Size Set&lt;Address> getAddresses() { ... }</tt></td><td style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">SizeValidatorForSet</tt>: direct supertype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Set&lt;Address></tt></td></tr><tr style="font-family: sans-serif; font-size: 14px; "><td align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="code" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Size SortedSet&lt;Address> getAddresses() { ... }</tt></td><td style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">SizeValidatorForSet</tt>:&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Set</tt>&nbsp;is the closest supertype of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">SortedSet&lt;Address></tt></td></tr><tr style="font-family: sans-serif; font-size: 14px; "><td align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="code" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Size SerializableCollection getAddresses() { ... }</tt></td><td style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">AmbiguousConstraintUsageException</tt><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">SerializableCollection</tt>&nbsp;is a subtype of both&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Collection</tt>&nbsp;and&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Serializable</tt>&nbsp;and neither<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Collection</tt>&nbsp;nor&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">Serializable</tt>&nbsp;are subtypes of each other.</td></tr><tr style="font-family: sans-serif; font-size: 14px; "><td align="center" style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="code" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">@Size String getName() { ... }</tt></td><td style="font-family: sans-serif; font-size: 14px; color: rgb(0, 0, 0); padding-top: 4pt; padding-right: 4pt; padding-bottom: 4pt; padding-left: 4pt; "><tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">UnexpectedTypeForConstraintException</tt>&nbsp;none of the&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">ConstraintValidator</tt>&nbsp;types are supertypes of&nbsp;<tt class="classname" style="font-size: 100%; color: rgb(17, 17, 17); font-family: monospace; ">String</tt>.</td></tr></tbody></table></div></div></div><div class="section" lang="en" style="font-family: sans-serif; font-size: 14px; "><div class="titlepage" style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "><div style="font-family: sans-serif; font-size: 14px; "></div></div></div></div></span></div><div><br></div><div><br></div><div><br></div><div>[...]</div><div><br></div><div><span class="Apple-style-span" style="font-family: -webkit-sans-serif; font-size: 14px; "><pre class="programlisting" style="font-size: 100%; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-color: rgb(244, 244, 244); font-family: monospace; width: auto; position: static; z-index: auto; ">public interface ConstraintDescriptor {
        /**
         * Returns the annotation describing the constraint declaration.
         * If a composing constraint, parameter values are reflecting
         * the overridden parameters from the main constraint
         *
         * @return The annotation for this constraint.
         */
        Annotation getAnnotation();

        /**
         * @return The groups the constraint is applied on.
         */
        Set&lt;Class&lt;?>> getGroups();

        /**
         * @return the constraint validation implementation class
         */
        Class&lt;? extends ConstraintValidator&lt;?,?>>[]
            getConstraintValidatorClasses();</pre></span></div><div><div>On &nbsp;Jan 23, 2009, at 15:13, Emmanuel Bernard wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Today, ConstraintValidator accepts Object and the implementation is responsible for handling the casting and raise an exception if the type is not supported.</div><div><br></div><div>The idea is to get type-safe validator and a discovery mechanism to associate a validator to a given runtime type being validated. The resolution is not 100% complete, you might end up with:</div><div>&nbsp;- no valid validator</div><div>&nbsp;- no way to decide between two or more validators</div><div>and get exceptions at runtime.</div><div><br></div><div>I would really like feedback on it as we could arrange some of these rules to not fail (at least in the latter case):</div><div>&nbsp;- do we want this type-safe + auto resolution algorithm strategy or should we stick with the untyped solution</div><div>&nbsp;- do we want to fail in case of ambiguity or rather choose the first compatible provider?</div><div><br></div><div>Personally I find the feature quite elegant and the metadata can be used by tools to warn a user if a constraint does not match the static type it is applied on.</div><div><br></div><div><b>API and declaration<br></b><div><br></div><div>A more typesafe proposal would be:</div><div><br></div><div>public interface ConstraintValidator&lt;A extends Annotation, T> {</div><div>&nbsp;&nbsp; &nbsp;void initialize(A annotation);</div><div>&nbsp;&nbsp; &nbsp;boolean isValid(T object,&nbsp;ConstraintValidationContext context);</div><div>}</div><div><br></div><div>public class StringSizeValidator implements ConstraintValidator&lt;Size, String> {</div><div>&nbsp;&nbsp; ...</div><div>}</div><div><br></div><div><div>public class CollectionSizeValidator implements ConstraintValidator&lt;Size, Collection> {</div><div>&nbsp;&nbsp; ...</div><div>}</div><div><br></div><div><div>public class MapSizeValidator implements ConstraintValidator&lt;Size, Map> {</div><div>&nbsp;&nbsp; ...</div><div>}</div></div><div><br></div><div><div>public class ArraySizeValidator implements ConstraintValidator&lt;Size, Object[]> {</div><div>&nbsp;&nbsp; ...</div><div>}</div><br></div></div><div><br></div><div>@Constraint(validatedBy={</div><div>&nbsp;&nbsp; &nbsp;StringSizeValidator.class, CollectionSizeValidator.class,&nbsp;</div><div>&nbsp;&nbsp; &nbsp;MapSizeValidator.class, ArraySizeValidator.class} )</div><div>public @interface Size { ... }</div><div><br></div><div>We then need to decide at runtime, which validator needs to be executed.</div><div>Here is a proposed algorithm heavily based on the Java Language Specification (boy it's hard to read it).</div><div><br></div><div><b>Resolution algorithm</b></div><div>The type T of a ConstraintValidator must not make direct use of generics itself.</div><div><br></div><div><i>This is because the algorithm compare the actual type at runtime and such notion would be lost. So you can do ConstraintValidator&lt;Size, Collection> but not ConstraintValidator&lt;Size, Collection&lt;String>>.</i></div><div><br></div><div>For a given runtime object t of type T about to be validated for a given constraint:</div><div>if t is null the first validator in the array of available validators is used.</div><div>otherwise</div><div><br></div><div>A validator accepting U is said to be compliant with the type T if T is a subtype of U according to the JLS chapter 4.10.</div><div><br></div><div>If no&nbsp;compliant&nbsp;validator is found for T, a UnexpectedTypeForConstraint exception is raised.</div><div><i>If a validator is taking the responsibility to dispatch types (ie ConstraintValidator&lt;Size,Object>), it must use the same exception in the same circumstances.</i></div><div><br></div><div>If one&nbsp;compliant&nbsp;validator is found, it is used.</div><div><br></div><div>If more than one&nbsp;compliant&nbsp;validator is found, the one with the most specific parameter is used.&nbsp;The informal intuition is that one parameter is more specific than another if any assignment handled by the first parameter could be passed on to the other one without a compile-time type error.</div><div><br></div><div>Of a given type T, a&nbsp;compliant&nbsp;validator accepting U is considered maximally specific if no other T compliant validator accepting V is such as V is a strict subtype of U. String subtype is defined by JSL chapter 4.10.</div><div><br></div><div>If more than one maximally specific validator is found, a AmbiguousValidatorException is raised.</div><div><br></div><div>WDYT?</div></div></div>_______________________________________________<br>hibernate-dev mailing list<br><a href="mailto:hibernate-dev@lists.jboss.org">hibernate-dev@lists.jboss.org</a><br>https://lists.jboss.org/mailman/listinfo/hibernate-dev<br></blockquote></div><br></body></html>