<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 7 Nov 2016, at 23:42, Hendrik Ebbers &lt;<a href="mailto:hendrik.ebbers@me.com" class="">hendrik.ebbers@me.com</a>&gt; wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class="">And this is not the only example. We already have some classes in JavaSE that will end in such problems:<br class="">The basic Property class in JavaFX can be used like this:<br class=""><br class=""><font face="Courier New" class="">private&nbsp;Property&lt;String&gt;&nbsp;myStringProperty;</font><br class=""><br class="">Based on the current approach we should add a constraint annotation like this:<br class=""><font face="Courier New" class=""><br class="">private&nbsp;Property&lt;@NotNull String&gt;&nbsp;myStringProperty;</font><br class=""><br class="">But next to the property class JavaFX contains the class StringProperty that is a specific implementation of „Property&lt;String&gt;„. If we want to use this class we can not add a annotation to a&nbsp;generic type since we don’t have such a generic type. Here we need to do it this way:<br class=""><br class=""><font face="Courier New" class="">@NotNull&nbsp;<br class="">private StringProperty&nbsp;myStringProperty2;</font><br class=""><br class="">And again we have 2 different approaches:<br class=""><br class=""><font face="Courier New" class="">private&nbsp;Property&lt;@NotNull String&gt;&nbsp;myStringProperty;<br class=""><br class="">@NotNull<br class="">private StringProperty&nbsp;myStringProperty2;</font><br class=""><br class="">Based on this I do not think that it’s a good idea to use the constraint annotation for generic types to validate the content of a wrapper.</div></div></blockquote><div><br class=""></div><div>General comment on you entire email.</div><div><br class=""></div><div>I think you are throwing the baby out with the bath water. Granted, more complicated cases don’t scale as nicely as we would hope but let’s get back tot he basics. 95%+ of this feature usage will be done for collections and maps. Based on this, I’d be a bit unhappy at giving up parameterized type use location for landing that annotations. This is sooooo natural.</div><div><br class=""></div><div>Our job is to make the common case simple and ideally make it scale in a not too ugly way and not close doors to the most complex use cases. And if one thing has to break, we can drop some of the less common cases.</div><div><br class=""></div><div>More specifically to this question, the proposal favored the use of parameterized type use but offers a backup plan for when the parameterized type use location is not present (like specialized subclasses of Java FX). Java FX is a clear cut as the wrapper is purely technical and all of the constraints do apply to the wrapped value.</div><div>But everywhere we have a parameterized type use, we should have the app developer make use of them instead of using the @ConstraintAppliesTo workaround.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""> To be true I do not have the ultimative&nbsp;solution for this problem. Currently I trying to add some metadata to the annotations to define it’s goal. Here is an example:<br class=""><br class=""><font face="Courier New" class="">@NotEmpty<br class="">private&nbsp;List&lt;String&gt;&nbsp;names1;<br class=""><br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS)<br class="">private&nbsp;List&lt;String&gt;&nbsp;names2;<br class=""><br class="">@NotEmpty<br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS)<br class="">private&nbsp;List&lt;String&gt;&nbsp;names3;</font><br class=""><br class="">Here the „applyTo“ value was added to the @NotEmpty annotation (like bean validation already does with the groups). By using this value a developer can specify if he wants to validate the&nbsp;value of the field or its internals. By doing so „names1“ is valid if the list contains at leas 1 element, „names2“ is valid if all elements in the list have at least a length of 1 (an empty list is&nbsp;allowed) and in „names3“ the list must contain at least one element and all elements must have a length &gt; 0.<br class=""><br class="">A similar approach is already defined in the proposal and I understand why this is not the perfect solution since you need to define it whenever you do not want to valide a plain value:<br class=""><br class=""><font face="Courier New" class="">@NotNull(applyTo = ConstraintsApplyTo.INTERNALS)<br class="">private StringProperty&nbsp;myStringProperty2;</font><div class=""><br class=""></div><div class="">Extracting this information to an additional (optional) annotation will be a problem since this can end in such an expression:</div><div class=""><br class=""></div><div class=""><span style="font-family: 'Courier New';" class="">@NotEmpty</span></div><div class=""><font face="Courier New" class="">@ConstraintsApplyTo(CONTAINED_VALUES)</font><br style="font-family: 'Courier New';" class=""><span style="font-family: 'Courier New';" class="">@NotEmpty</span><br style="font-family: 'Courier New';" class=""><span style="font-family: 'Courier New';" class="">private&nbsp;</span><span style="font-family: 'Courier New';" class="">List&lt;String&gt;&nbsp;</span><span style="font-family: 'Courier New';" class="">names3</span><span style="font-family: 'Courier New';" class="">;</span></div><div class=""><br class=""></div><div class="">By doing so you can not define the same constraints type for the container and for the containing value. In the example above the same is working.&nbsp;</div><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div><div>We did explore per annotation location overriding. This is a question in the initial proposal. The reason it did not make the first cut is as you have seen:</div><div><br class=""></div><div>- you need a lot of information on side that it not trivial to digest</div><div>- each existing constraint annotation will have to be changed to add these new attributes</div><div>&nbsp; &nbsp; - on that front, the spec has declared that attribute names starting with “valid” are reserved for the spec, so your proposal would have to have attributes prefixed with “valid” not to break existing code</div><div>- at the end of the day, the feature is really for code using type use, so we are twisting it for edge cases</div><div><br class=""></div><div>But I am very open to the idea of doing per annotation location overriding if people think that they are an important feature.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Next to the „applyTo“ value all the constraint annotations needs additional information to really validate all the given examples. In addition a plugin must be present that defines how we can&nbsp;get the internal value(s) of a class (in this case „StringProperty“).<br class="">Here are some code snippets that use additional information in the annotations to define the validation:<br class=""><br class=""><br class=""><font face="Courier New" class="">@NotEmpty<br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS)<br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2)<br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3)<br class="">private&nbsp;List&lt;List&lt;List&lt;StringProperty&gt;&gt;&gt;&nbsp;spooky;<br class=""><br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class)<br class="">private&nbsp;RealValue&lt;String&gt;&nbsp;myValue;</font><br class=""><br class="">The „applyToInternalDepth“ value is used to define how often the validator should get the internal value (depth). In the given example „@NotEmpty(applyTo =&nbsp;ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3)“ would validate the content of the „StringProperty“. In addition we need some information for the container if the container&nbsp;implements several interfaces. This could be defined in the annotation, too. In the example this is defined by the „valueContainerClass“ value.<br class=""></div></div></div></blockquote><div><br class=""></div><div>Hopefully we can converge on my idea not to have to add&nbsp;valueContainerClass (see the other emails). But you do need a way to identify the correct type parameter targeted. This is equivalent to the @ExtractedValue which today has&nbsp;typeParameterHost and either&nbsp;typeParameterIndex or typeParameterName to uniquely identify them.</div><div><br class=""></div><div>On the depth approach, your example would be more easily rewritten as&nbsp;</div><div><br class=""></div><div>&nbsp; &nbsp; @NotEmpty List&lt;@NotEmpty List&lt;@NotEmpty List&lt;@NotEmpty StringProperty&gt;&gt;&gt; spooky;</div><div><br class=""></div><div>which clarifies everything. But let’s assume we have a type ListOfListOfListOfStringProperty type. do we really want to support</div><div><br class=""></div><div>@NotEmpty<br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS)<br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2)<br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3)<br class="">private&nbsp;ListOfListOfListOfStringProperty&nbsp;spooky;</div><div><br class=""></div><div>or even</div><div><br class=""></div><div>@NotEmpty</div><div>// support nested levels by positioning&nbsp;ConstraintsApplyTo at the right level<br class="">private&nbsp;List&lt;@NotEmpty List&lt;@NotEmpty @NotEmpty(applyTo = ConstraintsApplyTo.CONTAINED_VALUES) ListOfStringProperty&gt;&gt; spooky;</div><div><br class=""></div><div>Or do we throw the towel and say that nested levels are not supported for non parameterized type use locations? What I am realizing now is that this option is available essentially to support containers that do not offer parameterized type. And in a previous email, I am questioning that use case.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class="">Based on this a constraint annotation needs this additional fields:<br class=""><br class=""><font face="Courier New" class="">ConstraintsApplyTo applyTo()&nbsp;default&nbsp;ConstraintsApplyTo.VALUE;&nbsp;&nbsp;//&nbsp;VALUE or INTERNALS<br class=""><br class="">int&nbsp;applyToInternalDepth()&nbsp;default&nbsp;&nbsp;1;<br class=""><br class="">Class&lt;?&gt; valueContainerClass()&nbsp;default&nbsp;Object.class;</font><br class=""><br class="">As I said I don’t have a good solution :( But I think that based on the given issues simply adding annotations to the generic types isn’t the best idea.<br class=""><br class="">I think it’s quite important to have support for all the wrapper classes. Validation collections and (JavaFX) properties will be a big benefit.&nbsp;<br class=""></div></div></div></blockquote></div><br class=""></body></html>