<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 <<a href="mailto:gunnar@hibernate.org" class="">gunnar@hibernate.org</a>> 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"> </span><span dir="ltr" class=""><<a href="mailto:emmanuel@hibernate.org" target="_blank" class="">emmanuel@hibernate.org</a>></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 <<a href="mailto:hendrik.ebbers@me.com" target="_blank" class="">hendrik.ebbers@me.com</a>> 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 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 List<List<List<<wbr class="">StringProperty>>> spooky;<br class=""><br class="">@NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class)<br class="">private RealValue<String> <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 = 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 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 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 typeParameterHost and either 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 </div><div class=""><br class=""></div><div class=""> <span class="Apple-converted-space"> </span>@NotEmpty List<@NotEmpty List<@NotEmpty List<@NotEmpty StringProperty>>> 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 <wbr class="">ListOfListOfListOfStringProper<wbr class="">ty 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 ConstraintsApplyTo at the right level<br class="">private List<@NotEmpty List<@NotEmpty @NotEmpty(applyTo = ConstraintsApplyTo.CONTAINED_<wbr class="">VALUES) ListOfStringProperty>> 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=""> public class CustomerContacts {</div><div class=""> List<List<String>> contacts; // one single inner list contains the contacts valid at a given time</div><div class=""> }</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<List<String>>, 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>