<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 23 Nov 2016, at 09:06, Gunnar Morling &lt;<a href="mailto:gunnar@hibernate.org" class="">gunnar@hibernate.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><br class="Apple-interchange-newline"><br class=""><div class="gmail_quote">2016-11-21 17:08 GMT+01:00 Emmanuel Bernard<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:emmanuel@hibernate.org" target="_blank" class="">emmanuel@hibernate.org</a>&gt;</span>:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 7 Nov 2016, at 23:42, Hendrik Ebbers &lt;<a href="mailto:hendrik.ebbers@me.com" target="_blank" class="">hendrik.ebbers@me.com</a>&gt; wrote:</div></blockquote></div></div></blockquote><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word;" 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;<wbr class="">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;<wbr class="">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.<wbr class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">On the depth approach, your example would be more easily rewritten as&nbsp;</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span>@NotEmpty List&lt;@NotEmpty List&lt;@NotEmpty List&lt;@NotEmpty StringProperty&gt;&gt;&gt; spooky;</div><div class=""><br class=""></div><div class="">which clarifies everything. But let’s assume we have a type ListOfListOfListOfStringProper<wbr class="">ty type. do we really want to support</div><div class=""><br class=""></div><div 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;<wbr class="">ListOfListOfListOfStringProper<wbr class="">ty&nbsp;spooky;</div><div class=""><br class=""></div><div class="">or even</div><div class=""><br class=""></div><div class="">@NotEmpty</div><div class="">// 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_<wbr class="">VALUES) ListOfStringProperty&gt;&gt; spooky;</div><div class=""><br class=""></div><div class="">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></div></div></blockquote><div class=""><br class=""></div><div class="">I'm also not convinced of this. In a way it seems to me like breaking encapsulation.</div><div class=""><br class=""></div><div class="">When dealing with a type such as ListOfStringListsProperty, you don't know it's inner works from a variable declaration. Hence I'm doubting that you should be allowed to apply constraints to them from the outside. It's getting more apparent when thinking of more real-world domain-specific types:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public class CustomerContacts {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; List&lt;List&lt;String&gt;&gt; contacts; // one single inner list contains the contacts valid at a given time</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">I don't think it makes sense to allow application of constraints "from the outside" when dealing with a property of CustomerContacts. It makes assumptions on the implementation of that type which is a dangerous thing to do. What if the implementation of CustomerContacts changes to be map-based? Existing constraint configurations given at the usage side would have to be adapted then.</div><div class=""><br class=""></div><div class="">Instead the constraints should be declared within CustomerContacts itself.</div><div class=""><br class=""></div><div class="">It's different for generic types. When dealing with a type like List&lt;List&lt;String&gt;&gt;, its "inner workings" are apparent to the user, i.e. it's reasonable to allow them to apply constraints to the elements of the inner list for instance.</div></div></div></div></div></blockquote><br class=""></div><div>Ah interesting point of view. I’ve never thought of it that way.</div><div><br class=""></div><div>I think what I had in mind when I said containers with no parameterized type is the Java 4 style collections that only have raw type support.</div><div><br class=""></div><div>@Email(validApplyTo=ConsgraintsApplyTo.CONTAINED_VALUE)</div><div>Collection emails;</div><div><br class=""></div><div>But back to the question, is that even a valid use case in 2016?</div><div><br class=""></div><div><br class=""></div></body></html>