From hendrik.ebbers at me.com Mon Nov 7 16:01:24 2016 From: hendrik.ebbers at me.com (Hendrik Ebbers) Date: Mon, 07 Nov 2016 22:01:24 +0100 Subject: [bv-dev] BVAL-214 Sample In-Reply-To: References: <213B6C20-64A3-4767-8F9A-8454AE165D9D@me.com> Message-ID: <7DB65788-63A1-4DBA-9035-47A373C047A8@me.com> Hi, I think it?s a mix. The code is based on proposition 2 (see http://beanvalidation.org/proposals/BVAL-214/#proposition-2). But at the end the difference to the API of proposition 1 is quite small. See this Gist for a small refactoring that looks more like the API f proposition 1: https://gist.github.com/hendrikebbers/3a4fb58c5384638b6b34affe3b6b0228 At the end I think that the name ?ValidatedValues? is wrong if we do it this way since an instance describe values that should be validated in future ;) Cheers, Hendrik > Am 19.10.2016 um 14:25 schrieb Gunnar Morling : > > Hi Hendrik, > > Thanks, having such test bed will be very useful! > > Adding some association to the model (a plain reference or a collection annotated with @Valid) would be a great addition so we can use it to explore cascaded validation, too. > > One question: this does not address the actual issue of BVAL-214 - which is the validation of class-level constraints in the course of validateValues() - yet, right? I.e. in its current form, this is essentially taking the existing validateValue() and exposes it in a form more easily digestable for the purposes of UI validation, right? > > --Gunnar > > > > > 2016-10-12 8:45 GMT+02:00 Hendrik Ebbers >: > Hi all, > > I created a small JavaFX as a playground for proposal BVAL-214. I already added a dummy implementation for my idea (see http://beanvalidation.org/proposals/BVAL-214/#proposition-2 ). > You can find the sources here: https://github.com/guigarage/BeanValidationForUI > > I added a dummy implementation for the validation API and the sample can simply be started by the com.guigarage.validation.Demo class > I will add some doc later to describe my ideas. > > Cheers, > > Hendrik > > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161107/5ad03d20/attachment-0001.html From hendrik.ebbers at me.com Mon Nov 7 17:42:34 2016 From: hendrik.ebbers at me.com (Hendrik Ebbers) Date: Mon, 07 Nov 2016 23:42:34 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: Hi all, I want to give some feedback to this proposal. Let?s start with a small example like this: @NotEmpty private List values; Here I assume that we have a @NotEmpty constraint that can be used of several types (like collections or Strings). In the example above the annotation defines some metadata for the field. By doing so you will read it as ?The list should not be empty - The List should contain at least one element?. I think this is the same syntax as it was done before and everyone will understand it. Here is the next example: private List<@NotEmpty String> desc; By defining it this way we have a list that can contain 0?n elements but each element must be a string with a length > 0. Since the @NotEmpty annotation now marks the generic type of the list it is related to the content of the list. The next example contains a mix: @NotEmpty private List<@NotEmpty String> desc; Here 2 @NotEmpty annotations are used. In the end the field will be valid if the list contains at least one String and all Strings of the list have a length > 0. Based on this we could create a field that looks like this: private List>> spooky; Even here we can say that the field must contain a list with 0?n elements where each element contains a list that must not be empty. Until now I only worked with lists and here the approach is quite nice. Sadly it won?t work always. By adding an constraints annotation to the generic type of the list we know that the annotation mentions the content of the list. But this is only working because of one point: The generic type of a collection defines the type of the collection content. This works fine for collections (and for example JavaFX properties) but in other cases this will end in problems. Let?s say we have the following 2 interfaces: public interface CachedValue { V getCachedValue(); } public interface RealValue { V getRealValue(); } Based on this interfaces we can easily create a new class that implements both interfaces: public class CachableValue implements CachedValue, RealValue { private V cachedValue; @Override public V getCachedValue() { return cachedValue; } @Override public V getRealValue() { V realValue = receiveValueFromServer(); cachedValue = realValue; return realValue; } private V receiveValueFromServer() { return ServerConnector.getCurrentValue(); //Some fake code } } Let?s try to add a constraint annotation to validate the content of such a CachableValue: private CachableValue<@NotEmpty String> myValue; Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem. Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea what will happen. The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on this I think that it will be a must to support all wrapper types. In addition I think that simply adding a constraints annotation to the generic type is wrong. All examples that we have mentioned are just perfect examples in that the generic type defines the content. Let?s say we have a class like this: public abstract class ConvertableInteger { private int value; public void setValue(int value) { this.value = value; } public int getValue() { return value; } public abstract V getConvertedValue(); } If you want to validate an instance of this class you normally want to validate the integer and not the converted value: private ConvertableInteger<@Min(2_000_000) Date> myValue; Such an expression looks like if you want to validate a Date object. In this case the better solution would be something like this: @Min(2_000_000) private ConvertableInteger myValue; And now we end in 2 different ways how we annotation value wrappers: private CachableValue<@NotEmpty String> myCachedValue; @Min(2_000_000) private ConvertableInteger myIntegerValue; And this is not the only example. We already have some classes in JavaSE that will end in such problems: The basic Property class in JavaFX can be used like this: private Property myStringProperty; Based on the current approach we should add a constraint annotation like this: private Property<@NotNull String> myStringProperty; But next to the property class JavaFX contains the class StringProperty that is a specific implementation of ?Property?. If we want to use this class we can not add a annotation to a generic type since we don?t have such a generic type. Here we need to do it this way: @NotNull private StringProperty myStringProperty2; And again we have 2 different approaches: private Property<@NotNull String> myStringProperty; @NotNull private StringProperty myStringProperty2; 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. To be true I do not have the ultimative solution for this problem. Currently I trying to add some metadata to the annotations to define it?s goal. Here is an example: @NotEmpty private List names1; @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) private List names2; @NotEmpty @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) private List names3; 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 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 allowed) and in ?names3? the list must contain at least one element and all elements must have a length > 0. 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: @NotNull(applyTo = ConstraintsApplyTo.INTERNALS) private StringProperty myStringProperty2; Extracting this information to an additional (optional) annotation will be a problem since this can end in such an expression: @NotEmpty @ConstraintsApplyTo(CONTAINED_VALUES) @NotEmpty private List names3; 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. 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?). Here are some code snippets that use additional information in the annotations to define the validation: @NotEmpty @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) private List>> spooky; @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class) private RealValue myValue; The ?applyToInternalDepth? value is used to define how often the validator should get the internal value (depth). In the given example ?@NotEmpty(applyTo = ConstraintsApplyTo.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. Based on this a constraint annotation needs this additional fields: ConstraintsApplyTo applyTo() default ConstraintsApplyTo.VALUE; // VALUE or INTERNALS int applyToInternalDepth() default 1; Class valueContainerClass() default Object.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. I think it?s quite important to have support for all the wrapper classes. Validation collections and (JavaFX) properties will be a big benefit. I don?t think that support for Optional is that important since having a field of type Optional looks like an anti-pattern to me. Normally Optional should be used as a method return type and not as a type for a field. Supporting it in the bean validation might end in strange model classes. Example: The following model looks good to me: public class Model { @NotNull private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Optional name() { return Optional.ofNullable(name);} } On the other hand this looks like an anti-pattern to me: public class Model { @NotNull private Optional name; public Optional getName() { return name; } public void setName(String name) { this.name = Optional.ofNullable(name); } } I now that some of the code samples will not compile (for example several annotations of same type for element) but I think the code is more easy to read by doing it that way ;) Cheers, Hendrik > Am 30.09.2016 um 14:35 schrieb Christian Kaltepoth : > > Hey Gunnar, > > I was wondering whether the distinction between SingleContainerValueExtractor and ManyContainerValuesExtractor is really necessary. I'm not sure if the unnecessary instantiation of an iterator in the single value case is really a problem in practice. I think extractor implementations will provide some special implementation of the Iterator/Iterable contract in any case. Not sure how others feel about that. > Good question. I reckon we'll know more after experimenting with this in the RI. > > I agree. The proposal mentions the possibility of having different functional rules and better performance for the single value case as reasons for the distinction. I just think that the latter one won't actually be a real problem. > > Section 2.1 states that BV will support Iterable and Map by default. What about Optional? We will support the JDK8 date/time API, so why don't we plan to support Optional? > Optional will be part of it by default. It should be stated somewhere, I hope :) > > The document explicitly states: > > Bean Validation will have out of the box support for containers Iterable and Map. > > I was expecting Optional to be listed here too. That's why I mentioned it. :-) > > > Christian > > > > -- > Christian Kaltepoth > Blog: http://blog.kaltepoth.de/ > Twitter: http://twitter.com/chkal > GitHub: https://github.com/chkal > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161107/d9b96be5/attachment-0001.html From guillaume.smet at gmail.com Wed Nov 9 18:29:59 2016 From: guillaume.smet at gmail.com (Guillaume Smet) Date: Thu, 10 Nov 2016 00:29:59 +0100 Subject: [bv-dev] Proposal for supporting new Java 8 date/time types In-Reply-To: References: <451B8D8D-BBE9-4F15-BE27-E5F0B20F2211@me.com> <40e87e93-ac34-a45f-2610-385a7e91b9c3@xs4all.nl> Message-ID: Hi, So I started to work on a first implementation in the API, the TCK and in HV. It's a bit different from the latest draft of Michael but I think it should be a good base for our discussions. * Bean Validation API: https://github.com/beanvalidation/beanvalidation-api/pull/70 * Bean Validation TCK: https://github.com/beanvalidation/beanvalidation-tck/pull/77 * HV: https://github.com/hibernate/hibernate-validator/pull/576 Main differences are: * I didn't use introspection to build the now object from the Clock and get the compareTo method. It would save some code but I don't think it's a good idea. I agree that it limits the support to officially supported types but I like it better this way. AbstractJavaTimeValidator makes it easy to add support for other types if required; * I implemented all the default java.time types in this first round but I'll add optional support for threeten-extras as a proprietary extension in a followup-up patch if we decide to keep this approach; * I named the nowIsValid option orPresent leading to having something like @Past(orPresent = true) which does not look too bad. Comments welcome! -- Guillaume On Wed, Oct 19, 2016 at 11:24 AM, Gunnar Morling wrote: > Hi Michael, > > +1 for splitting it up into two parts and have the discussion around > Duration et al. separately. Based on that, do you think you could send a PR > with the first pieces some time soon? > > I think it'd be great to put out an Alpha1 of the spec and the RI > containing this change and the other things we have so far. It's just the > first steps, but pushing it out demonstrates progress and allows to get > feedback early on. > > My idea would be to do an Alpha1 with these changes around the end of this > month. WDYT? > > Thanks, > > --Gunnar > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161110/b5217226/attachment.html From christian at kaltepoth.de Sat Nov 12 05:20:54 2016 From: christian at kaltepoth.de (Christian Kaltepoth) Date: Sat, 12 Nov 2016 11:20:54 +0100 Subject: [bv-dev] Proposal for supporting new Java 8 date/time types In-Reply-To: References: <451B8D8D-BBE9-4F15-BE27-E5F0B20F2211@me.com> <40e87e93-ac34-a45f-2610-385a7e91b9c3@xs4all.nl> Message-ID: Hey Guillaume, this looks VERY good! I like like the idea of using "orPresent" instead of " nowIsValid". Great work! Christian 2016-11-10 0:29 GMT+01:00 Guillaume Smet : > Hi, > > So I started to work on a first implementation in the API, the TCK and in > HV. > > It's a bit different from the latest draft of Michael but I think it > should be a good base for our discussions. > > * Bean Validation API: https://github.com/beanvalidation/beanvalidation- > api/pull/70 > * Bean Validation TCK: https://github.com/beanvalidation/beanvalidation- > tck/pull/77 > * HV: https://github.com/hibernate/hibernate-validator/pull/576 > > Main differences are: > * I didn't use introspection to build the now object from the Clock and > get the compareTo method. It would save some code but I don't think it's a > good idea. I agree that it limits the support to officially supported types > but I like it better this way. AbstractJavaTimeValidator makes it easy to > add support for other types if required; > * I implemented all the default java.time types in this first round but > I'll add optional support for threeten-extras as a proprietary extension in > a followup-up patch if we decide to keep this approach; > * I named the nowIsValid option orPresent leading to having something like > @Past(orPresent = true) which does not look too bad. > > Comments welcome! > > -- > Guillaume > > On Wed, Oct 19, 2016 at 11:24 AM, Gunnar Morling > wrote: > >> Hi Michael, >> >> +1 for splitting it up into two parts and have the discussion around >> Duration et al. separately. Based on that, do you think you could send a PR >> with the first pieces some time soon? >> >> I think it'd be great to put out an Alpha1 of the spec and the RI >> containing this change and the other things we have so far. It's just the >> first steps, but pushing it out demonstrates progress and allows to get >> feedback early on. >> >> My idea would be to do an Alpha1 with these changes around the end of >> this month. WDYT? >> >> Thanks, >> >> --Gunnar >> > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -- Christian Kaltepoth Blog: http://blog.kaltepoth.de/ Twitter: http://twitter.com/chkal GitHub: https://github.com/chkal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161112/81f3cc13/attachment.html From hendrik.ebbers at me.com Thu Nov 17 03:19:08 2016 From: hendrik.ebbers at me.com (Hendrik Ebbers) Date: Thu, 17 Nov 2016 09:19:08 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: <2C2AEAB7-D984-4B82-ABA5-1C4F6731CFB6@me.com> No feedback? :( Wonder if I missed something or if you think that my thoughts go in the right direction / show real problems with the discussed approach. Cheers, Hendrik > Am 07.11.2016 um 23:42 schrieb Hendrik Ebbers : > > Hi all, > I want to give some feedback to this proposal. > > Let?s start with a small example like this: > > @NotEmpty > private List values; > > Here I assume that we have a @NotEmpty constraint that can be used of several types (like collections or Strings). In the example above the annotation defines some metadata for the field. By doing so you will read it as ?The list should not be empty - The List should contain at least one element?. > I think this is the same syntax as it was done before and everyone will understand it. > > Here is the next example: > > private List<@NotEmpty String> desc; > > By defining it this way we have a list that can contain 0?n elements but each element must be a string with a length > 0. Since the @NotEmpty annotation now marks the generic type of the list it is related to the content of the list. > > The next example contains a mix: > > @NotEmpty > private List<@NotEmpty String> desc; > > Here 2 @NotEmpty annotations are used. In the end the field will be valid if the list contains at least one String and all Strings of the list have a length > 0. > > Based on this we could create a field that looks like this: > > private List>> spooky; > > Even here we can say that the field must contain a list with 0?n elements where each element contains a list that must not be empty. > > Until now I only worked with lists and here the approach is quite nice. Sadly it won?t work always. By adding an constraints annotation to the generic type of the list we know that the annotation mentions the content of the list. But this is only working because of one point: The generic type of a collection defines the type of the collection content. This works fine for collections (and for example JavaFX properties) but in other cases this will end in problems. > > Let?s say we have the following 2 interfaces: > > public interface CachedValue { > V getCachedValue(); > } > > public interface RealValue { > V getRealValue(); > } > > Based on this interfaces we can easily create a new class that implements both interfaces: > > public class CachableValue implements CachedValue, RealValue { > > private V cachedValue; > > @Override > public V getCachedValue() { > return cachedValue; > } > > @Override > public V getRealValue() { > V realValue = receiveValueFromServer(); > cachedValue = realValue; > return realValue; > } > > private V receiveValueFromServer() { > return ServerConnector.getCurrentValue(); //Some fake code > } > } > > Let?s try to add a constraint annotation to validate the content of such a CachableValue: > > private CachableValue<@NotEmpty String> myValue; > > Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem. Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea what will happen. > > The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on this I think that it will be a must to support all wrapper types. > > In addition I think that simply adding a constraints annotation to the generic type is wrong. All examples that we have mentioned are just perfect examples in that the generic type defines the content. Let?s say we have a class like this: > > public abstract class ConvertableInteger { > > private int value; > > public void setValue(int value) { this.value = value; } > > public int getValue() { return value; } > > public abstract V getConvertedValue(); > } > > If you want to validate an instance of this class you normally want to validate the integer and not the converted value: > > private ConvertableInteger<@Min(2_000_000) Date> myValue; > > Such an expression looks like if you want to validate a Date object. In this case the better solution would be something like this: > > @Min(2_000_000) > private ConvertableInteger myValue; > > And now we end in 2 different ways how we annotation value wrappers: > > private CachableValue<@NotEmpty String> myCachedValue; > > @Min(2_000_000) > private ConvertableInteger myIntegerValue; > > And this is not the only example. We already have some classes in JavaSE that will end in such problems: > The basic Property class in JavaFX can be used like this: > > private Property myStringProperty; > > Based on the current approach we should add a constraint annotation like this: > > private Property<@NotNull String> myStringProperty; > > But next to the property class JavaFX contains the class StringProperty that is a specific implementation of ?Property?. If we want to use this class we can not add a annotation to a generic type since we don?t have such a generic type. Here we need to do it this way: > > @NotNull > private StringProperty myStringProperty2; > > And again we have 2 different approaches: > > private Property<@NotNull String> myStringProperty; > > @NotNull > private StringProperty myStringProperty2; > > 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. To be true I do not have the ultimative solution for this problem. Currently I trying to add some metadata to the annotations to define it?s goal. Here is an example: > > @NotEmpty > private List names1; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names2; > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names3; > > 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 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 allowed) and in ?names3? the list must contain at least one element and all elements must have a length > 0. > > 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: > > @NotNull(applyTo = ConstraintsApplyTo.INTERNALS) > private StringProperty myStringProperty2; > > Extracting this information to an additional (optional) annotation will be a problem since this can end in such an expression: > > @NotEmpty > @ConstraintsApplyTo(CONTAINED_VALUES) > @NotEmpty > private List names3; > > 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. > > 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?). > Here are some code snippets that use additional information in the annotations to define the validation: > > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) > private List>> spooky; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class) > private RealValue myValue; > > The ?applyToInternalDepth? value is used to define how often the validator should get the internal value (depth). In the given example ?@NotEmpty(applyTo = ConstraintsApplyTo.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. > > Based on this a constraint annotation needs this additional fields: > > ConstraintsApplyTo applyTo() default ConstraintsApplyTo.VALUE; // VALUE or INTERNALS > > int applyToInternalDepth() default 1; > > Class valueContainerClass() default Object.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. > > I think it?s quite important to have support for all the wrapper classes. Validation collections and (JavaFX) properties will be a big benefit. > > > I don?t think that support for Optional is that important since having a field of type Optional looks like an anti-pattern to me. Normally Optional should be used as a method return type and not as a type for a field. Supporting it in the bean validation might end in strange model classes. > > Example: > > The following model looks good to me: > > public class Model { > > @NotNull > private String name; > > public String getName() { return name; } > > public void setName(String name) { this.name = name; } > > public Optional name() { return Optional.ofNullable(name);} > > } > > On the other hand this looks like an anti-pattern to me: > > public class Model { > > @NotNull > private Optional name; > > public Optional getName() { return name; } > > public void setName(String name) { this.name = Optional.ofNullable(name); } > > } > > I now that some of the code samples will not compile (for example several annotations of same type for element) but I think the code is more easy to read by doing it that way ;) > > Cheers, > > Hendrik > > >> Am 30.09.2016 um 14:35 schrieb Christian Kaltepoth >: >> >> Hey Gunnar, >> >> I was wondering whether the distinction between SingleContainerValueExtractor and ManyContainerValuesExtractor is really necessary. I'm not sure if the unnecessary instantiation of an iterator in the single value case is really a problem in practice. I think extractor implementations will provide some special implementation of the Iterator/Iterable contract in any case. Not sure how others feel about that. >> Good question. I reckon we'll know more after experimenting with this in the RI. >> >> I agree. The proposal mentions the possibility of having different functional rules and better performance for the single value case as reasons for the distinction. I just think that the latter one won't actually be a real problem. >> >> Section 2.1 states that BV will support Iterable and Map by default. What about Optional? We will support the JDK8 date/time API, so why don't we plan to support Optional? >> Optional will be part of it by default. It should be stated somewhere, I hope :) >> >> The document explicitly states: >> >> Bean Validation will have out of the box support for containers Iterable and Map. >> >> I was expecting Optional to be listed here too. That's why I mentioned it. :-) >> >> >> Christian >> >> >> >> -- >> Christian Kaltepoth >> Blog: http://blog.kaltepoth.de/ >> Twitter: http://twitter.com/chkal >> GitHub: https://github.com/chkal >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161117/d8efe1de/attachment-0001.html From hendrik.ebbers at me.com Thu Nov 17 04:42:37 2016 From: hendrik.ebbers at me.com (Hendrik Ebbers) Date: Thu, 17 Nov 2016 10:42:37 +0100 Subject: [bv-dev] The GitHub Team In-Reply-To: References: Message-ID: <36935E16-4FB5-4FDB-A127-7023FC828B98@me.com> Hi all, I will get a first sketch of the duke logo first week of December. Cheers, Hendrik > Am 13.09.2016 um 12:55 schrieb Marco Molteni : > > Thanks for the feedback Gunnar. The Duke it's fine for me too :) > > > Am 13.09.2016 11:21 schrieb "Gunnar Morling" >: > Hi, > > > Curiosity, why a Duke that stamps bean? > > I think the idea is to symbolize the approval/validation of beans. I like the idea, it's kind of funny for "insiders", and those not getting it still should find the Duke an attractive being ;) > > Personally I think it's fine if we - the EG and those discussing on this list - like and get behind one logo. Let's keep surveys and alike for stuff where we really need some input based on people's experiences with validation in practice. > > Hendrik, so if your friend could help out with this and create a logo for us, that'd be awesome. The only requirement really would be that it is provided with a suitable license, the 3-clause BSD license that the original is licensed under being the preferred option. > > Thanks a lot for driving this, > > --Gunnar > > > > > > 2016-09-09 11:40 GMT+02:00 Marco Molteni >: > Hendrik, excellent idea the logo. Curiosity, why a Duke that stamps bean? I think the concept to create the logo is another subject that requires the community feedback (an original cool logo or a business / technical concept around BV ?). > > On Fri, Sep 2, 2016 at 2:09 PM, Gunnar Morling > wrote: > Please still use a fork and send pull requests from that. > > We usually don't have feature branches in the "blessed" upstream repos, only if several people happen to work together on a single "thing" for a longer period of time. > > 2016-09-02 13:57 GMT+02:00 Hendrik Ebbers >: > Cool! > > Question: Should we still use forks or can we work with features branches directly in then bean validation repos? > > Hendrik > >> Am 02.09.2016 um 09:27 schrieb Gunnar Morling >: >> >> Hi Hendrik, >> >> Great ideas! Further details inline. >> >> 2016-09-01 16:30 GMT+02:00 Hendrik Ebbers >: >> Hi all, >> >> currently all JBV repos are part of https://github.com/beanvalidation which is really great. 3 people are part of this team at GitHub and I asked myself if I can become member of the team, too. >> >> I've set up a new team "eg-members" under the Bean Validation GitHub organization and sent you an invite for it (other EG members give me your GitHub handle if you want to be in there, too). This will show you under the list of org members and also allows to summon other experts's input on commits/PRs using the "@eg-members" alias. >> >> I've also granted write access to that team for the relevant repos. But please *never* push your own commits, instead always go through pull requests reviewed by other members. Collective code review is one of our core principles really. >> >> In addition I think that we need a logo for the JSR :) We could use this at Github, Twitter & beanvalidation.org . I know an illustrator that did a lot of Java-related images for me. If you know the JavaOne voting machines: He created all the duke animations (http://www.guigarage.com/2016/01/the-javaone-voting-machine/ ). I would love to ask him for a logo for the JRS. Currently I?m thinking about a Duke that stamps beans. What do you think? >> >> Yes, personally I'd love to have a log, the lack of one has been bugging me for quite a while. I'll reply to you off-list to sort out some details. >> >> Cheers, >> >> Hendrik >> >> --Gunnar >> >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161117/c81783d9/attachment.html From gunnar at hibernate.org Thu Nov 17 05:02:10 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Thu, 17 Nov 2016 11:02:10 +0100 Subject: [bv-dev] The GitHub Team In-Reply-To: <36935E16-4FB5-4FDB-A127-7023FC828B98@me.com> References: <36935E16-4FB5-4FDB-A127-7023FC828B98@me.com> Message-ID: Awesome, that's great news, Hendrik! Much appreciated! 2016-11-17 10:42 GMT+01:00 Hendrik Ebbers : > Hi all, > > I will get a first sketch of the duke logo first week of December. > > Cheers, > > Hendrik > > Am 13.09.2016 um 12:55 schrieb Marco Molteni : > > Thanks for the feedback Gunnar. The Duke it's fine for me too :) > > Am 13.09.2016 11:21 schrieb "Gunnar Morling" : > >> Hi, >> >> > Curiosity, why a Duke that stamps bean? >> >> I think the idea is to symbolize the approval/validation of beans. I like >> the idea, it's kind of funny for "insiders", and those not getting it still >> should find the Duke an attractive being ;) >> >> Personally I think it's fine if we - the EG and those discussing on this >> list - like and get behind one logo. Let's keep surveys and alike for stuff >> where we really need some input based on people's experiences with >> validation in practice. >> >> Hendrik, so if your friend could help out with this and create a logo for >> us, that'd be awesome. The only requirement really would be that it is >> provided with a suitable license, the 3-clause BSD license that the >> original is licensed under being the preferred option. >> >> Thanks a lot for driving this, >> >> --Gunnar >> >> >> >> >> >> 2016-09-09 11:40 GMT+02:00 Marco Molteni : >> >>> Hendrik, excellent idea the logo. Curiosity, why a Duke that stamps >>> bean? I think the concept to create the logo is another subject that >>> requires the community feedback (an original cool logo or a business / >>> technical concept around BV ?). >>> >>> On Fri, Sep 2, 2016 at 2:09 PM, Gunnar Morling >>> wrote: >>> >>>> Please still use a fork and send pull requests from that. >>>> >>>> We usually don't have feature branches in the "blessed" upstream repos, >>>> only if several people happen to work together on a single "thing" for a >>>> longer period of time. >>>> >>>> 2016-09-02 13:57 GMT+02:00 Hendrik Ebbers : >>>> >>>>> Cool! >>>>> >>>>> Question: Should we still use forks or can we work with features >>>>> branches directly in then bean validation repos? >>>>> >>>>> Hendrik >>>>> >>>>> Am 02.09.2016 um 09:27 schrieb Gunnar Morling : >>>>> >>>>> Hi Hendrik, >>>>> >>>>> Great ideas! Further details inline. >>>>> >>>>> 2016-09-01 16:30 GMT+02:00 Hendrik Ebbers : >>>>> >>>>>> Hi all, >>>>>> >>>>>> currently all JBV repos are part of https://github.com/beanvalidation >>>>>> which is really great. 3 people are part of this team at GitHub and I >>>>>> asked myself if I can become member of the team, too. >>>>>> >>>>> >>>>> I've set up a new team "eg-members" under the Bean Validation GitHub >>>>> organization and sent you an invite for it (other EG members give me your >>>>> GitHub handle if you want to be in there, too). This will show you under >>>>> the list of org members and also allows to summon other experts's input on >>>>> commits/PRs using the "@eg-members" alias. >>>>> >>>>> I've also granted write access to that team for the relevant repos. >>>>> But please *never* push your own commits, instead always go through pull >>>>> requests reviewed by other members. Collective code review is one of our >>>>> core principles really. >>>>> >>>>> In addition I think that we need a logo for the JSR :) We could use >>>>>> this at Github, Twitter & beanvalidation.org. I know an illustrator >>>>>> that did a lot of Java-related images for me. If you know the JavaOne >>>>>> voting machines: He created all the duke animations ( >>>>>> http://www.guigarage.com/2016/01/the-javaone-voting-machine/). I >>>>>> would love to ask him for a logo for the JRS. Currently I?m thinking about >>>>>> a Duke that stamps beans. What do you think? >>>>>> >>>>> >>>>> Yes, personally I'd love to have a log, the lack of one has been >>>>> bugging me for quite a while. I'll reply to you off-list to sort out some >>>>> details. >>>>> >>>>> Cheers, >>>>>> >>>>>> Hendrik >>>>>> >>>>> >>>>> --Gunnar >>>>> >>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> beanvalidation-dev mailing list >>>>>> beanvalidation-dev at lists.jboss.org >>>>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >>>>>> >>>>> >>>>> _______________________________________________ >>>>> beanvalidation-dev mailing list >>>>> beanvalidation-dev at lists.jboss.org >>>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> beanvalidation-dev mailing list >>>>> beanvalidation-dev at lists.jboss.org >>>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >>>>> >>>> >>>> >>>> _______________________________________________ >>>> beanvalidation-dev mailing list >>>> beanvalidation-dev at lists.jboss.org >>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >>>> >>> >>> >>> _______________________________________________ >>> beanvalidation-dev mailing list >>> beanvalidation-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >>> >> >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >> > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161117/b1b15705/attachment-0001.html From emmanuel at hibernate.org Thu Nov 17 05:18:07 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Thu, 17 Nov 2016 11:18:07 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: <2C2AEAB7-D984-4B82-ABA5-1C4F6731CFB6@me.com> References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <2C2AEAB7-D984-4B82-ABA5-1C4F6731CFB6@me.com> Message-ID: <4A555EB6-1F39-4B1F-8405-8119E9FB8414@hibernate.org> It?s all my fault. I?ve been (un)focused on a lot of non related Bean Validation workload. and all feedback from Sept 25th onward is still in my queue to process. Working hard to come back to this one , Gunnar is also putting pressure on me :) Emmanuel > On 17 Nov 2016, at 09:19, Hendrik Ebbers wrote: > > No feedback? :( > Wonder if I missed something or if you think that my thoughts go in the right direction / show real problems with the discussed approach. > > Cheers, > > Hendrik > > >> Am 07.11.2016 um 23:42 schrieb Hendrik Ebbers >: >> >> Hi all, >> I want to give some feedback to this proposal. >> >> Let?s start with a small example like this: >> >> @NotEmpty >> private List values; >> >> Here I assume that we have a @NotEmpty constraint that can be used of several types (like collections or Strings). In the example above the annotation defines some metadata for the field. By doing so you will read it as ?The list should not be empty - The List should contain at least one element?. >> I think this is the same syntax as it was done before and everyone will understand it. >> >> Here is the next example: >> >> private List<@NotEmpty String> desc; >> >> By defining it this way we have a list that can contain 0?n elements but each element must be a string with a length > 0. Since the @NotEmpty annotation now marks the generic type of the list it is related to the content of the list. >> >> The next example contains a mix: >> >> @NotEmpty >> private List<@NotEmpty String> desc; >> >> Here 2 @NotEmpty annotations are used. In the end the field will be valid if the list contains at least one String and all Strings of the list have a length > 0. >> >> Based on this we could create a field that looks like this: >> >> private List>> spooky; >> >> Even here we can say that the field must contain a list with 0?n elements where each element contains a list that must not be empty. >> >> Until now I only worked with lists and here the approach is quite nice. Sadly it won?t work always. By adding an constraints annotation to the generic type of the list we know that the annotation mentions the content of the list. But this is only working because of one point: The generic type of a collection defines the type of the collection content. This works fine for collections (and for example JavaFX properties) but in other cases this will end in problems. >> >> Let?s say we have the following 2 interfaces: >> >> public interface CachedValue { >> V getCachedValue(); >> } >> >> public interface RealValue { >> V getRealValue(); >> } >> >> Based on this interfaces we can easily create a new class that implements both interfaces: >> >> public class CachableValue implements CachedValue, RealValue { >> >> private V cachedValue; >> >> @Override >> public V getCachedValue() { >> return cachedValue; >> } >> >> @Override >> public V getRealValue() { >> V realValue = receiveValueFromServer(); >> cachedValue = realValue; >> return realValue; >> } >> >> private V receiveValueFromServer() { >> return ServerConnector.getCurrentValue(); //Some fake code >> } >> } >> >> Let?s try to add a constraint annotation to validate the content of such a CachableValue: >> >> private CachableValue<@NotEmpty String> myValue; >> >> Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem. Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea what will happen. >> >> The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on this I think that it will be a must to support all wrapper types. >> >> In addition I think that simply adding a constraints annotation to the generic type is wrong. All examples that we have mentioned are just perfect examples in that the generic type defines the content. Let?s say we have a class like this: >> >> public abstract class ConvertableInteger { >> >> private int value; >> >> public void setValue(int value) { this.value = value; } >> >> public int getValue() { return value; } >> >> public abstract V getConvertedValue(); >> } >> >> If you want to validate an instance of this class you normally want to validate the integer and not the converted value: >> >> private ConvertableInteger<@Min(2_000_000) Date> myValue; >> >> Such an expression looks like if you want to validate a Date object. In this case the better solution would be something like this: >> >> @Min(2_000_000) >> private ConvertableInteger myValue; >> >> And now we end in 2 different ways how we annotation value wrappers: >> >> private CachableValue<@NotEmpty String> myCachedValue; >> >> @Min(2_000_000) >> private ConvertableInteger myIntegerValue; >> >> And this is not the only example. We already have some classes in JavaSE that will end in such problems: >> The basic Property class in JavaFX can be used like this: >> >> private Property myStringProperty; >> >> Based on the current approach we should add a constraint annotation like this: >> >> private Property<@NotNull String> myStringProperty; >> >> But next to the property class JavaFX contains the class StringProperty that is a specific implementation of ?Property?. If we want to use this class we can not add a annotation to a generic type since we don?t have such a generic type. Here we need to do it this way: >> >> @NotNull >> private StringProperty myStringProperty2; >> >> And again we have 2 different approaches: >> >> private Property<@NotNull String> myStringProperty; >> >> @NotNull >> private StringProperty myStringProperty2; >> >> 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. To be true I do not have the ultimative solution for this problem. Currently I trying to add some metadata to the annotations to define it?s goal. Here is an example: >> >> @NotEmpty >> private List names1; >> >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) >> private List names2; >> >> @NotEmpty >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) >> private List names3; >> >> 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 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 allowed) and in ?names3? the list must contain at least one element and all elements must have a length > 0. >> >> 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: >> >> @NotNull(applyTo = ConstraintsApplyTo.INTERNALS) >> private StringProperty myStringProperty2; >> >> Extracting this information to an additional (optional) annotation will be a problem since this can end in such an expression: >> >> @NotEmpty >> @ConstraintsApplyTo(CONTAINED_VALUES) >> @NotEmpty >> private List names3; >> >> 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. >> >> 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?). >> Here are some code snippets that use additional information in the annotations to define the validation: >> >> >> @NotEmpty >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) >> private List>> spooky; >> >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class) >> private RealValue myValue; >> >> The ?applyToInternalDepth? value is used to define how often the validator should get the internal value (depth). In the given example ?@NotEmpty(applyTo = ConstraintsApplyTo.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. >> >> Based on this a constraint annotation needs this additional fields: >> >> ConstraintsApplyTo applyTo() default ConstraintsApplyTo.VALUE; // VALUE or INTERNALS >> >> int applyToInternalDepth() default 1; >> >> Class valueContainerClass() default Object.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. >> >> I think it?s quite important to have support for all the wrapper classes. Validation collections and (JavaFX) properties will be a big benefit. >> >> >> I don?t think that support for Optional is that important since having a field of type Optional looks like an anti-pattern to me. Normally Optional should be used as a method return type and not as a type for a field. Supporting it in the bean validation might end in strange model classes. >> >> Example: >> >> The following model looks good to me: >> >> public class Model { >> >> @NotNull >> private String name; >> >> public String getName() { return name; } >> >> public void setName(String name) { this.name = name; } >> >> public Optional name() { return Optional.ofNullable(name);} >> >> } >> >> On the other hand this looks like an anti-pattern to me: >> >> public class Model { >> >> @NotNull >> private Optional name; >> >> public Optional getName() { return name; } >> >> public void setName(String name) { this.name = Optional.ofNullable(name); } >> >> } >> >> I now that some of the code samples will not compile (for example several annotations of same type for element) but I think the code is more easy to read by doing it that way ;) >> >> Cheers, >> >> Hendrik >> >> >>> Am 30.09.2016 um 14:35 schrieb Christian Kaltepoth >: >>> >>> Hey Gunnar, >>> >>> I was wondering whether the distinction between SingleContainerValueExtractor and ManyContainerValuesExtractor is really necessary. I'm not sure if the unnecessary instantiation of an iterator in the single value case is really a problem in practice. I think extractor implementations will provide some special implementation of the Iterator/Iterable contract in any case. Not sure how others feel about that. >>> Good question. I reckon we'll know more after experimenting with this in the RI. >>> >>> I agree. The proposal mentions the possibility of having different functional rules and better performance for the single value case as reasons for the distinction. I just think that the latter one won't actually be a real problem. >>> >>> Section 2.1 states that BV will support Iterable and Map by default. What about Optional? We will support the JDK8 date/time API, so why don't we plan to support Optional? >>> Optional will be part of it by default. It should be stated somewhere, I hope :) >>> >>> The document explicitly states: >>> >>> Bean Validation will have out of the box support for containers Iterable and Map. >>> >>> I was expecting Optional to be listed here too. That's why I mentioned it. :-) >>> >>> >>> Christian >>> >>> >>> >>> -- >>> Christian Kaltepoth >>> Blog: http://blog.kaltepoth.de/ >>> Twitter: http://twitter.com/chkal >>> GitHub: https://github.com/chkal >>> >>> _______________________________________________ >>> beanvalidation-dev mailing list >>> beanvalidation-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161117/be44baf5/attachment-0001.html From christian at kaltepoth.de Fri Nov 18 02:26:16 2016 From: christian at kaltepoth.de (Christian Kaltepoth) Date: Fri, 18 Nov 2016 08:26:16 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: <4A555EB6-1F39-4B1F-8405-8119E9FB8414@hibernate.org> References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <2C2AEAB7-D984-4B82-ABA5-1C4F6731CFB6@me.com> <4A555EB6-1F39-4B1F-8405-8119E9FB8414@hibernate.org> Message-ID: Hey Hendrik, sorry for my late reply. And thank you for preparing this extensive feedback. I agree with you that the proposal only works good for classic "container like" types (Collection, Map, Optional, etc). And the examples you provided prove that it doesn't work well for many other cases of generic types. To be honest, I'm also not sure how to solve this. If we try to support all kinds of generic types we may end up with a ton of hard to read metadata users have to use to express their constraints. Any other thoughts? Christian 2016-11-17 11:18 GMT+01:00 Emmanuel Bernard : > It?s all my fault. I?ve been (un)focused on a lot of non related Bean > Validation workload. and all feedback from Sept 25th onward is still in my > queue to process. > Working hard to come back to this one , Gunnar is also putting pressure on > me :) > > Emmanuel > > On 17 Nov 2016, at 09:19, Hendrik Ebbers wrote: > > No feedback? :( > Wonder if I missed something or if you think that my thoughts go in the > right direction / show real problems with the discussed approach. > > Cheers, > > Hendrik > > > Am 07.11.2016 um 23:42 schrieb Hendrik Ebbers : > > Hi all, > I want to give some feedback to this proposal. > > Let?s start with a small example like this: > > @NotEmpty > private List values; > > Here I assume that we have a @NotEmpty constraint that can be used of > several types (like collections or Strings). In the example above the > annotation defines some metadata for the field. By doing so you will read > it as ?The list should not be empty - The List should contain at least one > element?. > I think this is the same syntax as it was done before and everyone will > understand it. > > Here is the next example: > > private List<@NotEmpty String> desc; > > By defining it this way we have a list that can contain 0?n elements but > each element must be a string with a length > 0. Since the @NotEmpty > annotation now marks the generic type of the list it is related to the > content of the list. > > The next example contains a mix: > > @NotEmpty > private List<@NotEmpty String> desc; > > Here 2 @NotEmpty annotations are used. In the end the field will be valid > if the list contains at least one String and all Strings of the list have a > length > 0. > > Based on this we could create a field that looks like this: > > private List>> spooky; > > Even here we can say that the field must contain a list with 0?n elements > where each element contains a list that must not be empty. > > Until now I only worked with lists and here the approach is quite nice. > Sadly it won?t work always. By adding an constraints annotation to the > generic type of the list we know that the annotation mentions the content > of the list. But this is only working because of one point: The generic > type of a collection defines the type of the collection content. This works > fine for collections (and for example JavaFX properties) but in other cases > this will end in problems. > > Let?s say we have the following 2 interfaces: > > public interface CachedValue { > V getCachedValue(); > } > > public interface RealValue { > V getRealValue(); > } > > Based on this interfaces we can easily create a new class that implements > both interfaces: > > public class CachableValue implements CachedValue, RealValue { > > private V cachedValue; > > @Override > public V getCachedValue() { > return cachedValue; > } > > @Override > public V getRealValue() { > V realValue = receiveValueFromServer(); > cachedValue = realValue; > return realValue; > } > > private V receiveValueFromServer() { > return ServerConnector.getCurrentValue(); //Some fake code > } > } > > Let?s try to add a constraint annotation to validate the content of such a > CachableValue: > > private CachableValue<@NotEmpty String> myValue; > > Based on this definition you have absolutely no idea if the @NotEmpty > annotation is defined for the real value, the cached value or both values. > From my point of view this is a big problem. Until now its was always easy > to see how the validation of a model should work based on the validation > information (annotations) in the model. With this new approach you have no > idea what will happen. > > The most simple solution would be to add the support only to some special > container / wrapper classes like collections, JavaFX properties, etc. I > think this is a bad idea since new default might come to future versions of > JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on > this I think that it will be a must to support all wrapper types. > > In addition I think that simply adding a constraints annotation to the > generic type is wrong. All examples that we have mentioned are just perfect > examples in that the generic type defines the content. Let?s say we have a > class like this: > > public abstract class ConvertableInteger { > > private int value; > > public void setValue(int value) { this.value = value; } > > public int getValue() { return value; } > > public abstract V getConvertedValue(); > } > > If you want to validate an instance of this class you normally want to > validate the integer and not the converted value: > > private ConvertableInteger<@Min(2_000_000) Date> myValue; > > Such an expression looks like if you want to validate a Date object. In > this case the better solution would be something like this: > > @Min(2_000_000) > private ConvertableInteger myValue; > > And now we end in 2 different ways how we annotation value wrappers: > > private CachableValue<@NotEmpty String> myCachedValue; > > @Min(2_000_000) > private ConvertableInteger myIntegerValue; > > And this is not the only example. We already have some classes in JavaSE > that will end in such problems: > The basic Property class in JavaFX can be used like this: > > private Property myStringProperty; > > Based on the current approach we should add a constraint annotation like > this: > > private Property<@NotNull String> myStringProperty; > > But next to the property class JavaFX contains the class StringProperty > that is a specific implementation of ?Property?. If we want to use > this class we can not add a annotation to a generic type since we don?t > have such a generic type. Here we need to do it this way: > > @NotNull > private StringProperty myStringProperty2; > > And again we have 2 different approaches: > > private Property<@NotNull String> myStringProperty; > > @NotNull > private StringProperty myStringProperty2; > > 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. To be > true I do not have the ultimative solution for this problem. Currently I > trying to add some metadata to the annotations to define it?s goal. Here is > an example: > > @NotEmpty > private List names1; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names2; > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names3; > > 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 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 allowed) and in ?names3? the list must > contain at least one element and all elements must have a length > 0. > > 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: > > @NotNull(applyTo = ConstraintsApplyTo.INTERNALS) > private StringProperty myStringProperty2; > > Extracting this information to an additional (optional) annotation will be > a problem since this can end in such an expression: > > @NotEmpty > @ConstraintsApplyTo(CONTAINED_VALUES) > @NotEmpty > private List names3; > > 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. > > 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?). > Here are some code snippets that use additional information in the > annotations to define the validation: > > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) > private List>> spooky; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = > RealValue.class) > private RealValue myValue; > > The ?applyToInternalDepth? value is used to define how often the validator > should get the internal value (depth). In the given example > ?@NotEmpty(applyTo = ConstraintsApplyTo.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. > > Based on this a constraint annotation needs this additional fields: > > ConstraintsApplyTo applyTo() default ConstraintsApplyTo.VALUE; // VALUE > or INTERNALS > > int applyToInternalDepth() default 1; > > Class valueContainerClass() default Object.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. > > I think it?s quite important to have support for all the wrapper classes. > Validation collections and (JavaFX) properties will be a big benefit. > > > I don?t think that support for Optional is that important since having a > field of type Optional looks like an anti-pattern to me. Normally Optional > should be used as a method return type and not as a type for a field. > Supporting it in the bean validation might end in strange model classes. > > Example: > > The following model looks good to me: > > public class Model { > > @NotNull > private String name; > > public String getName() { return name; } > > public void setName(String name) { this.name = name; } > > public Optional name() { return Optional.ofNullable(name);} > > } > > On the other hand this looks like an anti-pattern to me: > > public class Model { > > @NotNull > private Optional name; > > public Optional getName() { return name; } > > public void setName(String name) { this.name = Optional.ofNullable(name); > } > > } > > I now that some of the code samples will not compile (for example several > annotations of same type for element) but I think the code is more easy to > read by doing it that way ;) > > Cheers, > > Hendrik > > > Am 30.09.2016 um 14:35 schrieb Christian Kaltepoth >: > > Hey Gunnar, > > >>> 1. I was wondering whether the distinction between >>> SingleContainerValueExtractor and ManyContainerValuesExtractor is >>> really necessary. I'm not sure if the unnecessary instantiation of an >>> iterator in the single value case is really a problem in practice. I think >>> extractor implementations will provide some special implementation of the >>> Iterator/Iterable contract in any case. Not sure how others feel >>> about that. >>> >>> Good question. I reckon we'll know more after experimenting with this in >> the RI. >> > > I agree. The proposal mentions the possibility of having different > functional rules and better performance for the single value case as > reasons for the distinction. I just think that the latter one won't > actually be a real problem. > > >>> 1. Section 2.1 states that BV will support Iterable and Map by >>> default. What about Optional? We will support the JDK8 date/time >>> API, so why don't we plan to support Optional? >>> >>> Optional will be part of it by default. It should be stated somewhere, I >> hope :) >> > > The document explicitly states: > > * Bean Validation will have out of the box support for containers > Iterable and Map.* > > I was expecting Optional to be listed here too. That's why I mentioned it. > :-) > > > Christian > > > > -- > Christian Kaltepoth > Blog: http://blog.kaltepoth.de/ > Twitter: http://twitter.com/chkal > GitHub: https://github.com/chkal > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -- Christian Kaltepoth Blog: http://blog.kaltepoth.de/ Twitter: http://twitter.com/chkal GitHub: https://github.com/chkal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161118/e9041a37/attachment-0001.html From emmanuel at hibernate.org Fri Nov 18 08:56:55 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Fri, 18 Nov 2016 14:56:55 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: <20161118135655.GE6400@hibernate.org> Thanks for your input, some comments inline. On Sun 16-09-25 11:22, Christian Kaltepoth wrote: >Hey Emmanuel, Hey Gunnar, > >sorry for my late reply. Thank you very much for the enormous amount of >work you already spent on this proposal. This topic seems to be quite >complex and it looks like you spent many hours thinking about all this. It >is a bit difficult to give good feedback without being so deep into this >topic. But I'll try. ;-) > > 1. I was wondering whether the distinction between > SingleContainerValueExtractor and ManyContainerValuesExtractor is really > necessary. I'm not sure if the unnecessary instantiation of an iterator in > the single value case is really a problem in practice. I think extractor > implementations will provide some special implementation of the Iterator/ > Iterable contract in any case. Not sure how others feel about that. I thought about that but even with a special implementation of Iterator, you are stuck with one extra object created for each single object validated with no purpose. We don't have in Java way to decorate an object without extra invocation. The Bean Validation design is very sensible to performance in the critical path of object validation. But yes we should check how things react once we have a RI prototyle, I'll add a note to that effect. > 2. Section 2.1 states that BV will support Iterable and Map by default. > What about Optional? We will support the JDK8 date/time API, so why > don't we plan to support Optional? Yes that's an oversight. Fixed now. > 3. I like the idea that users can provide custom extractors for other > container types. Not sure if this is something the average developer will > do very often, but defining an SPI here seems like a good idea. Yes, it felt a bit over engineered at first but with the multitude of new languages on the VM, such a contract is very useful. > 4. I'm not completely sure if the "one extractor per container" or the > "one extractor per container + value" approach makes more sense. That's a > very difficult questions. I think I need some more time to think about that. Gunnar explained that he prefers "one extractor per container" to avoid the need for for @ExtractedValue on the type parameter. I personally find the "one extractor per container + value" nicer for a couple of reasons: * the actual implementations are straight to the point of extracting values instead of also handling type parameter references and having to implement `getNode` which is a bit of a mystery to me now (I used to know why). * it leaves the side responsibilities (type param / node) to the BV engine * it is inherently more composable. I can add a new extractor after the fact * it only extracts objects that need to be validated (constrained ones) vs returning all objects (i.e. only return Map.value vs Map.key and value) It's main drawback I think is that to read a Map which is constrained on both key and values, it requires to walk through it twice. You can work around it in the BV engine but that requires to be slight off the standard semantic of this proposed SPI. From emmanuel at hibernate.org Fri Nov 18 09:08:25 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Fri, 18 Nov 2016 15:08:25 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: <20161118140825.GF6400@hibernate.org> On Fri 16-09-30 14:35, Christian Kaltepoth wrote: >Hey Gunnar, > > >>> 1. I was wondering whether the distinction between >>> SingleContainerValueExtractor and ManyContainerValuesExtractor is >>> really necessary. I'm not sure if the unnecessary instantiation of an >>> iterator in the single value case is really a problem in practice. I think >>> extractor implementations will provide some special implementation of the >>> Iterator/Iterable contract in any case. Not sure how others feel >>> about that. >>> >>> Good question. I reckon we'll know more after experimenting with this in >> the RI. >> > >I agree. The proposal mentions the possibility of having different >functional rules and better performance for the single value case as >reasons for the distinction. I just think that the latter one won't >actually be a real problem. I know optimisation is the root of all evil and all that but remember that many ask us, how much slower will validation make my code. We have also experienced areas of Hibernate the ORM where the critical path was creating unobtrusive objects that turned out to be a limiting factor in performance tests. I get I got scars. On the functional rules, let me try and make things a bit more concrete. While we are trying to treat all containers as equal, you can imagine that different rules fror single ones vs multiple ones might make sense. For example, should @Valid be mandatory in case of a single container vs a multiple container //@Valid Optional<@Pattern(...) String> email; @Valid Collection<@Pattern(...) String> emails; These difference might be a bad idea but they are not out of the equation for this BV release or a future one. A different interface was a way to differentiate single vs multiple. An alternative is an annotation but I'm not sure that's an imp[rovementBV release or a future one. A different interface was a way to differentiate single vs multiple. An alternative is an annotation but I'm not sure that's an improvement. Emmanuel From emmanuel at hibernate.org Mon Nov 21 07:47:30 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 13:47:30 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: Thank you Hendrick ! This is a very thoughtful feedback. Some issues that we had identified already some we had not. Since it really addresses several cases, I?ll start sub threads so we can more easily discuss. More on subthreads. Emmanuel > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > Hi all, > I want to give some feedback to this proposal. > > Let?s start with a small example like this: > > @NotEmpty > private List values; > > Here I assume that we have a @NotEmpty constraint that can be used of several types (like collections or Strings). In the example above the annotation defines some metadata for the field. By doing so you will read it as ?The list should not be empty - The List should contain at least one element?. > I think this is the same syntax as it was done before and everyone will understand it. > > Here is the next example: > > private List<@NotEmpty String> desc; > > By defining it this way we have a list that can contain 0?n elements but each element must be a string with a length > 0. Since the @NotEmpty annotation now marks the generic type of the list it is related to the content of the list. > > The next example contains a mix: > > @NotEmpty > private List<@NotEmpty String> desc; > > Here 2 @NotEmpty annotations are used. In the end the field will be valid if the list contains at least one String and all Strings of the list have a length > 0. > > Based on this we could create a field that looks like this: > > private List>> spooky; > > Even here we can say that the field must contain a list with 0?n elements where each element contains a list that must not be empty. > > Until now I only worked with lists and here the approach is quite nice. Sadly it won?t work always. By adding an constraints annotation to the generic type of the list we know that the annotation mentions the content of the list. But this is only working because of one point: The generic type of a collection defines the type of the collection content. This works fine for collections (and for example JavaFX properties) but in other cases this will end in problems. > > Let?s say we have the following 2 interfaces: > > public interface CachedValue { > V getCachedValue(); > } > > public interface RealValue { > V getRealValue(); > } > > Based on this interfaces we can easily create a new class that implements both interfaces: > > public class CachableValue implements CachedValue, RealValue { > > private V cachedValue; > > @Override > public V getCachedValue() { > return cachedValue; > } > > @Override > public V getRealValue() { > V realValue = receiveValueFromServer(); > cachedValue = realValue; > return realValue; > } > > private V receiveValueFromServer() { > return ServerConnector.getCurrentValue(); //Some fake code > } > } > > Let?s try to add a constraint annotation to validate the content of such a CachableValue: > > private CachableValue<@NotEmpty String> myValue; > > Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem. Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea what will happen. > > The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on this I think that it will be a must to support all wrapper types. > > In addition I think that simply adding a constraints annotation to the generic type is wrong. All examples that we have mentioned are just perfect examples in that the generic type defines the content. Let?s say we have a class like this: > > public abstract class ConvertableInteger { > > private int value; > > public void setValue(int value) { this.value = value; } > > public int getValue() { return value; } > > public abstract V getConvertedValue(); > } > > If you want to validate an instance of this class you normally want to validate the integer and not the converted value: > > private ConvertableInteger<@Min(2_000_000) Date> myValue; > > Such an expression looks like if you want to validate a Date object. In this case the better solution would be something like this: > > @Min(2_000_000) > private ConvertableInteger myValue; > > And now we end in 2 different ways how we annotation value wrappers: > > private CachableValue<@NotEmpty String> myCachedValue; > > @Min(2_000_000) > private ConvertableInteger myIntegerValue; > > And this is not the only example. We already have some classes in JavaSE that will end in such problems: > The basic Property class in JavaFX can be used like this: > > private Property myStringProperty; > > Based on the current approach we should add a constraint annotation like this: > > private Property<@NotNull String> myStringProperty; > > But next to the property class JavaFX contains the class StringProperty that is a specific implementation of ?Property?. If we want to use this class we can not add a annotation to a generic type since we don?t have such a generic type. Here we need to do it this way: > > @NotNull > private StringProperty myStringProperty2; > > And again we have 2 different approaches: > > private Property<@NotNull String> myStringProperty; > > @NotNull > private StringProperty myStringProperty2; > > 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. To be true I do not have the ultimative solution for this problem. Currently I trying to add some metadata to the annotations to define it?s goal. Here is an example: > > @NotEmpty > private List names1; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names2; > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names3; > > 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 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 allowed) and in ?names3? the list must contain at least one element and all elements must have a length > 0. > > 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: > > @NotNull(applyTo = ConstraintsApplyTo.INTERNALS) > private StringProperty myStringProperty2; > > Extracting this information to an additional (optional) annotation will be a problem since this can end in such an expression: > > @NotEmpty > @ConstraintsApplyTo(CONTAINED_VALUES) > @NotEmpty > private List names3; > > 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. > > 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?). > Here are some code snippets that use additional information in the annotations to define the validation: > > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) > private List>> spooky; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class) > private RealValue myValue; > > The ?applyToInternalDepth? value is used to define how often the validator should get the internal value (depth). In the given example ?@NotEmpty(applyTo = ConstraintsApplyTo.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. > > Based on this a constraint annotation needs this additional fields: > > ConstraintsApplyTo applyTo() default ConstraintsApplyTo.VALUE; // VALUE or INTERNALS > > int applyToInternalDepth() default 1; > > Class valueContainerClass() default Object.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. > > I think it?s quite important to have support for all the wrapper classes. Validation collections and (JavaFX) properties will be a big benefit. > > > I don?t think that support for Optional is that important since having a field of type Optional looks like an anti-pattern to me. Normally Optional should be used as a method return type and not as a type for a field. Supporting it in the bean validation might end in strange model classes. > > Example: > > The following model looks good to me: > > public class Model { > > @NotNull > private String name; > > public String getName() { return name; } > > public void setName(String name) { this.name = name; } > > public Optional name() { return Optional.ofNullable(name);} > > } > > On the other hand this looks like an anti-pattern to me: > > public class Model { > > @NotNull > private Optional name; > > public Optional getName() { return name; } > > public void setName(String name) { this.name = Optional.ofNullable(name); } > > } > > I now that some of the code samples will not compile (for example several annotations of same type for element) but I think the code is more easy to read by doing it that way ;) > > Cheers, > > Hendrik > > >> Am 30.09.2016 um 14:35 schrieb Christian Kaltepoth >: >> >> Hey Gunnar, >> >> I was wondering whether the distinction between SingleContainerValueExtractor and ManyContainerValuesExtractor is really necessary. I'm not sure if the unnecessary instantiation of an iterator in the single value case is really a problem in practice. I think extractor implementations will provide some special implementation of the Iterator/Iterable contract in any case. Not sure how others feel about that. >> Good question. I reckon we'll know more after experimenting with this in the RI. >> >> I agree. The proposal mentions the possibility of having different functional rules and better performance for the single value case as reasons for the distinction. I just think that the latter one won't actually be a real problem. >> >> Section 2.1 states that BV will support Iterable and Map by default. What about Optional? We will support the JDK8 date/time API, so why don't we plan to support Optional? >> Optional will be part of it by default. It should be stated somewhere, I hope :) >> >> The document explicitly states: >> >> Bean Validation will have out of the box support for containers Iterable and Map. >> >> I was expecting Optional to be listed here too. That's why I mentioned it. :-) >> >> >> Christian >> >> >> >> -- >> Christian Kaltepoth >> Blog: http://blog.kaltepoth.de/ >> Twitter: http://twitter.com/chkal >> GitHub: https://github.com/chkal >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/404a17fa/attachment-0001.html From emmanuel at hibernate.org Mon Nov 21 08:07:33 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 14:07:33 +0100 Subject: [bv-dev] Support for constraints on container values (e.g. Collection<@Email String>) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: <475FED0B-0A63-40B2-841A-EC78D7DA8053@hibernate.org> > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > Let?s say we have the following 2 interfaces: > > public interface CachedValue { > V getCachedValue(); > } > > public interface RealValue { > V getRealValue(); > } > > Based on this interfaces we can easily create a new class that implements both interfaces: > > public class CachableValue implements CachedValue, RealValue { > > private V cachedValue; > > @Override > public V getCachedValue() { > return cachedValue; > } > > @Override > public V getRealValue() { > V realValue = receiveValueFromServer(); > cachedValue = realValue; > return realValue; > } > > private V receiveValueFromServer() { > return ServerConnector.getCurrentValue(); //Some fake code > } > } > > Let?s try to add a constraint annotation to validate the content of such a CachableValue: > > private CachableValue<@NotEmpty String> myValue; > > Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem. Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea what will happen. > > The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on this I think that it will be a must to support all wrapper types. Interesting. I did think about extractors of subtypes but not extractors of parallel types. I have been thinking about it and explored a few paths: - validating all parallel extractors - use one - validate none - fail In the end, I think the cleanest solution is to follow what Ceylon and Java do for default methods, they don?t allow ambiguous use and force a redefinition. http://stackoverflow.com/questions/16764791/how-does-java-8-new-default-interface-model-works-incl-diamond-multiple-inhe#16788295 In practice for us, if there are extractors for CachedValue and for RealValue, then CachableValue should fail and require the definition of an explicit CachableValue extractor. What is interesting in this case is that CachableValue extractor can be see as either: - a ManyContainerValuesExtractor that will return getCachedValue and getRealValue just like a Collection would return get(0) and get(1). This approach does not reflect the path difference though - or two SingleContainerValueExtractor from the same container type and the same value type (*) (*) this is something we do not allow for the moment, we have a unique extractor per container + value type. We need to think about how to make that work and still allow people to override extractors. So back to your original concern of uncertainty, I think forcing a more specific extractor solves the uncertainty that you mentioned. Granted, the user would have to know the extractor(s) behavior but in many ways, people do need to know about that regardless. Thoughts? Emmanuel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/bc3cab20/attachment.html From emmanuel at hibernate.org Mon Nov 21 08:28:24 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 14:28:24 +0100 Subject: [bv-dev] Constraint on non generic types (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > In addition I think that simply adding a constraints annotation to the generic type is wrong. All examples that we have mentioned are just perfect examples in that the generic type defines the content. Let?s say we have a class like this: > > public abstract class ConvertableInteger { > > private int value; > > public void setValue(int value) { this.value = value; } > > public int getValue() { return value; } > > public abstract V getConvertedValue(); > } > > If you want to validate an instance of this class you normally want to validate the integer and not the converted value: > > private ConvertableInteger<@Min(2_000_000) Date> myValue; > > Such an expression looks like if you want to validate a Date object. In this case the better solution would be something like this: > > @Min(2_000_000) > private ConvertableInteger myValue; > > And now we end in 2 different ways how we annotation value wrappers: > > private CachableValue<@NotEmpty String> myCachedValue; > > @Min(2_000_000) > private ConvertableInteger myIntegerValue; First off, your specific example does not work as is as the class is abstract. You would need an explicit subclass (e.g. DateConvertableInteger extends ConvertableInteger). And in that situation, The more natural BV approach would be to do this: public class DateConvertableInteger extend ConvertableInteger { @Min(@2_000_000) public int getValue() { return value; } @NotEmpty public Date getConvertedValue(); } class SomeClass { @Valid private StringConvertableInteger myValue; } == overriding constraint declarations Now if you want a way to override the constraints of an embedded (@Valid) object (graph), then I think that is a different subject that we can try and address. JPA for example has the notion of @AttributeOverride. It is more complicated in the case of Bean Validation as we would need to override actual annotations. Not sure how to express that for now. Do we think that it is a valid and important requirement? To clarify, here is what is required public class Embeddable { @NotEmpty String foo; } public class Entity { @Valid @Override(path=?foo?, constraints=@Min(3)) // note that this is not valid Java syntax Embeddable embeddable; } == Constraint on non parameterized containers That raises another question, the proposal allows to to three things: - apply constraints on a type use generic declaration(*): Collection<@NotEmpty String> foo; - apply constraints on specialized generic parameters (*): @Pattern(?) StringProperty prop; //where StringProperty extends Property - apply constraints on container with no generic: @Min(3) IntegerContainer prop; // where class IntegerContainer{ Integer value; } i.e. no generic (*) I don?t know the actual proper names so sorry if I butchered notions I am liking option 3 less and less and as far as I can remember, it does not rely on an explicitly identified use case. Who is wanting to support that usage, vs restrict the container feature to parameterized containers? I?m not sure I was all that clear, so please ask any question if you have any doubt. Emmanuel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/bec3fa01/attachment.html From emmanuel at hibernate.org Mon Nov 21 08:32:43 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 14:32:43 +0100 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > I don?t think that support for Optional is that important since having a field of type Optional looks like an anti-pattern to me. Normally Optional should be used as a method return type and not as a type for a field. Supporting it in the bean validation might end in strange model classes. > > Example: > > The following model looks good to me: > > public class Model { > > @NotNull > private String name; > > public String getName() { return name; } > > public void setName(String name) { this.name = name; } > > public Optional name() { return Optional.ofNullable(name);} > > } > > On the other hand this looks like an anti-pattern to me: > > public class Model { > > @NotNull > private Optional name; > > public Optional getName() { return name; } > > public void setName(String name) { this.name = Optional.ofNullable(name); } > > } Yes Optional on a property is deemed an anti pattern by the JDK team but since Bean Validation supports contraints on method parameters and return values, this is still a valid use case Optional<@Email String> getUserEmail(@NotNull UUID userId); Emmanuel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/553e43bf/attachment-0001.html From gunnar at hibernate.org Mon Nov 21 09:18:38 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Mon, 21 Nov 2016 15:18:38 +0100 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: Yes, probably we should not support Optional for fields. Also parameters are dubious (the JDK team discourages that afaik). But supporting it for return values (and getter-based properties) seems reasonable. 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard : > > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > I don?t think that support for Optional is that important since having a > field of type Optional looks like an anti-pattern to me. Normally Optional > should be used as a method return type and not as a type for a field. > Supporting it in the bean validation might end in strange model classes. > > Example: > > The following model looks good to me: > > public class Model { > > @NotNull > private String name; > > public String getName() { return name; } > > public void setName(String name) { this.name = name; } > > public Optional name() { return Optional.ofNullable(name);} > > } > > On the other hand this looks like an anti-pattern to me: > > public class Model { > > @NotNull > private Optional name; > > public Optional getName() { return name; } > > public void setName(String name) { this.name = Optional.ofNullable(name); > } > > } > > > Yes Optional on a property is deemed an anti pattern by the JDK team but > since Bean Validation supports contraints on method parameters and return > values, this is still a valid use case > > Optional<@Email String> getUserEmail(@NotNull UUID userId); > > Emmanuel > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/d564a593/attachment.html From mbenson at apache.org Mon Nov 21 09:51:06 2016 From: mbenson at apache.org (Matt Benson) Date: Mon, 21 Nov 2016 08:51:06 -0600 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: On Mon, Nov 21, 2016 at 8:18 AM, Gunnar Morling wrote: > Yes, probably we should not support Optional for fields. Also parameters are > dubious (the JDK team discourages that afaik). But supporting it for return > values (and getter-based properties) seems reasonable. +1 Matt (with apologies for not having participated earlier in the spec 2.0 process) > > 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard : >> >> >> On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: >> >> I don?t think that support for Optional is that important since having a >> field of type Optional looks like an anti-pattern to me. Normally Optional >> should be used as a method return type and not as a type for a field. >> Supporting it in the bean validation might end in strange model classes. >> >> Example: >> >> The following model looks good to me: >> >> public class Model { >> >> @NotNull >> private String name; >> >> public String getName() { return name; } >> >> public void setName(String name) { this.name = name; } >> >> public Optional name() { return Optional.ofNullable(name);} >> >> } >> >> On the other hand this looks like an anti-pattern to me: >> >> public class Model { >> >> @NotNull >> private Optional name; >> >> public Optional getName() { return name; } >> >> public void setName(String name) { this.name = Optional.ofNullable(name); >> } >> >> } >> >> >> Yes Optional on a property is deemed an anti pattern by the JDK team but >> since Bean Validation supports contraints on method parameters and return >> values, this is still a valid use case >> >> Optional<@Email String> getUserEmail(@NotNull UUID userId); >> >> Emmanuel >> >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev From hendrik.ebbers at me.com Mon Nov 21 10:14:28 2016 From: hendrik.ebbers at me.com (Hendrik Ebbers) Date: Mon, 21 Nov 2016 16:14:28 +0100 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: <04398991-5CE7-49EA-837C-8BACB50AD4CA@me.com> +1 > Am 21.11.2016 um 15:51 schrieb Matt Benson : > > On Mon, Nov 21, 2016 at 8:18 AM, Gunnar Morling > wrote: >> Yes, probably we should not support Optional for fields. Also parameters are >> dubious (the JDK team discourages that afaik). But supporting it for return >> values (and getter-based properties) seems reasonable. > > +1 > > Matt (with apologies for not having participated earlier in the spec > 2.0 process) > >> >> 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard : >>> >>> >>> On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: >>> >>> I don?t think that support for Optional is that important since having a >>> field of type Optional looks like an anti-pattern to me. Normally Optional >>> should be used as a method return type and not as a type for a field. >>> Supporting it in the bean validation might end in strange model classes. >>> >>> Example: >>> >>> The following model looks good to me: >>> >>> public class Model { >>> >>> @NotNull >>> private String name; >>> >>> public String getName() { return name; } >>> >>> public void setName(String name) { this.name = name; } >>> >>> public Optional name() { return Optional.ofNullable(name);} >>> >>> } >>> >>> On the other hand this looks like an anti-pattern to me: >>> >>> public class Model { >>> >>> @NotNull >>> private Optional name; >>> >>> public Optional getName() { return name; } >>> >>> public void setName(String name) { this.name = Optional.ofNullable(name); >>> } >>> >>> } >>> >>> >>> Yes Optional on a property is deemed an anti pattern by the JDK team but >>> since Bean Validation supports contraints on method parameters and return >>> values, this is still a valid use case >>> >>> Optional<@Email String> getUserEmail(@NotNull UUID userId); >>> >>> Emmanuel >>> >>> >>> _______________________________________________ >>> beanvalidation-dev mailing list >>> beanvalidation-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >> >> >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/d4a09499/attachment-0001.html From emmanuel at hibernate.org Mon Nov 21 11:08:04 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 17:08:04 +0100 Subject: [bv-dev] Placing constraints on the container vs the contained type use (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: <5F0C4C29-6F1E-4B76-9CEE-4A20BA6F5F4C@hibernate.org> > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > And this is not the only example. We already have some classes in JavaSE that will end in such problems: > The basic Property class in JavaFX can be used like this: > > private Property myStringProperty; > > Based on the current approach we should add a constraint annotation like this: > > private Property<@NotNull String> myStringProperty; > > But next to the property class JavaFX contains the class StringProperty that is a specific implementation of ?Property?. If we want to use this class we can not add a annotation to a generic type since we don?t have such a generic type. Here we need to do it this way: > > @NotNull > private StringProperty myStringProperty2; > > And again we have 2 different approaches: > > private Property<@NotNull String> myStringProperty; > > @NotNull > private StringProperty myStringProperty2; > > 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. General comment on you entire email. 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. 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. 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. But everywhere we have a parameterized type use, we should have the app developer make use of them instead of using the @ConstraintAppliesTo workaround. > To be true I do not have the ultimative solution for this problem. Currently I trying to add some metadata to the annotations to define it?s goal. Here is an example: > > @NotEmpty > private List names1; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names2; > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names3; > > 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 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 allowed) and in ?names3? the list must contain at least one element and all elements must have a length > 0. > > 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: > > @NotNull(applyTo = ConstraintsApplyTo.INTERNALS) > private StringProperty myStringProperty2; > > Extracting this information to an additional (optional) annotation will be a problem since this can end in such an expression: > > @NotEmpty > @ConstraintsApplyTo(CONTAINED_VALUES) > @NotEmpty > private List names3; > > 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. > 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: - you need a lot of information on side that it not trivial to digest - each existing constraint annotation will have to be changed to add these new attributes - 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 - at the end of the day, the feature is really for code using type use, so we are twisting it for edge cases But I am very open to the idea of doing per annotation location overriding if people think that they are an important feature. > 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?). > Here are some code snippets that use additional information in the annotations to define the validation: > > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) > private List>> spooky; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class) > private RealValue myValue; > > The ?applyToInternalDepth? value is used to define how often the validator should get the internal value (depth). In the given example ?@NotEmpty(applyTo = ConstraintsApplyTo.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. 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. On the depth approach, your example would be more easily rewritten as @NotEmpty List<@NotEmpty List<@NotEmpty List<@NotEmpty StringProperty>>> spooky; which clarifies everything. But let?s assume we have a type ListOfListOfListOfStringProperty type. do we really want to support @NotEmpty @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) private ListOfListOfListOfStringProperty spooky; or even @NotEmpty // support nested levels by positioning ConstraintsApplyTo at the right level private List<@NotEmpty List<@NotEmpty @NotEmpty(applyTo = ConstraintsApplyTo.CONTAINED_VALUES) ListOfStringProperty>> spooky; 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. > > Based on this a constraint annotation needs this additional fields: > > ConstraintsApplyTo applyTo() default ConstraintsApplyTo.VALUE; // VALUE or INTERNALS > > int applyToInternalDepth() default 1; > > Class valueContainerClass() default Object.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. > > I think it?s quite important to have support for all the wrapper classes. Validation collections and (JavaFX) properties will be a big benefit. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/4c5809ec/attachment.html From emmanuel at hibernate.org Mon Nov 21 11:21:07 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 17:21:07 +0100 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: What?s the difference between a field and a getter based property? It is the same for all intended purposes in Bean Validation. > On 21 Nov 2016, at 15:51, Matt Benson wrote: > > On Mon, Nov 21, 2016 at 8:18 AM, Gunnar Morling wrote: >> Yes, probably we should not support Optional for fields. Also parameters are >> dubious (the JDK team discourages that afaik). But supporting it for return >> values (and getter-based properties) seems reasonable. > > +1 > > Matt (with apologies for not having participated earlier in the spec > 2.0 process) > >> >> 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard : >>> >>> >>> On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: >>> >>> I don?t think that support for Optional is that important since having a >>> field of type Optional looks like an anti-pattern to me. Normally Optional >>> should be used as a method return type and not as a type for a field. >>> Supporting it in the bean validation might end in strange model classes. >>> >>> Example: >>> >>> The following model looks good to me: >>> >>> public class Model { >>> >>> @NotNull >>> private String name; >>> >>> public String getName() { return name; } >>> >>> public void setName(String name) { this.name = name; } >>> >>> public Optional name() { return Optional.ofNullable(name);} >>> >>> } >>> >>> On the other hand this looks like an anti-pattern to me: >>> >>> public class Model { >>> >>> @NotNull >>> private Optional name; >>> >>> public Optional getName() { return name; } >>> >>> public void setName(String name) { this.name = Optional.ofNullable(name); >>> } >>> >>> } >>> >>> >>> Yes Optional on a property is deemed an anti pattern by the JDK team but >>> since Bean Validation supports contraints on method parameters and return >>> values, this is still a valid use case >>> >>> Optional<@Email String> getUserEmail(@NotNull UUID userId); >>> >>> Emmanuel >>> >>> >>> _______________________________________________ >>> beanvalidation-dev mailing list >>> beanvalidation-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >> >> >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev From christian at kaltepoth.de Mon Nov 21 11:25:34 2016 From: christian at kaltepoth.de (Christian Kaltepoth) Date: Mon, 21 Nov 2016 17:25:34 +0100 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: Not sure I like the idea of supporting Optional for return types but not for fields and method parameters. Is there any technical reason for this restriction? I agree that using Optional for fields is an anti-pattern, but I don't see any reason for not supporting it nevertheless. Am I missing something here? 2016-11-21 15:18 GMT+01:00 Gunnar Morling : > Yes, probably we should not support Optional for fields. Also parameters > are dubious (the JDK team discourages that afaik). But supporting it for > return values (and getter-based properties) seems reasonable. > > 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard : > >> >> On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: >> >> I don?t think that support for Optional is that important since having a >> field of type Optional looks like an anti-pattern to me. Normally Optional >> should be used as a method return type and not as a type for a field. >> Supporting it in the bean validation might end in strange model classes. >> >> Example: >> >> The following model looks good to me: >> >> public class Model { >> >> @NotNull >> private String name; >> >> public String getName() { return name; } >> >> public void setName(String name) { this.name = name; } >> >> public Optional name() { return Optional.ofNullable(name);} >> >> } >> >> On the other hand this looks like an anti-pattern to me: >> >> public class Model { >> >> @NotNull >> private Optional name; >> >> public Optional getName() { return name; } >> >> public void setName(String name) { this.name = >> Optional.ofNullable(name); } >> >> } >> >> >> Yes Optional on a property is deemed an anti pattern by the JDK team but >> since Bean Validation supports contraints on method parameters and return >> values, this is still a valid use case >> >> Optional<@Email String> getUserEmail(@NotNull UUID userId); >> >> Emmanuel >> >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >> > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -- Christian Kaltepoth Blog: http://blog.kaltepoth.de/ Twitter: http://twitter.com/chkal GitHub: https://github.com/chkal -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/ad1c288b/attachment-0001.html From emmanuel at hibernate.org Mon Nov 21 11:27:43 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 17:27:43 +0100 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: <382552BE-38CC-457C-8118-41027CB3CBB8@hibernate.org> I have the same feeling and arguments. > On 21 Nov 2016, at 17:25, Christian Kaltepoth wrote: > > Not sure I like the idea of supporting Optional for return types but not for fields and method parameters. Is there any technical reason for this restriction? I agree that using Optional for fields is an anti-pattern, but I don't see any reason for not supporting it nevertheless. > > Am I missing something here? > > 2016-11-21 15:18 GMT+01:00 Gunnar Morling >: > Yes, probably we should not support Optional for fields. Also parameters are dubious (the JDK team discourages that afaik). But supporting it for return values (and getter-based properties) seems reasonable. > > 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard >: > >> On 7 Nov 2016, at 23:42, Hendrik Ebbers > wrote: >> >> I don?t think that support for Optional is that important since having a field of type Optional looks like an anti-pattern to me. Normally Optional should be used as a method return type and not as a type for a field. Supporting it in the bean validation might end in strange model classes. >> >> Example: >> >> The following model looks good to me: >> >> public class Model { >> >> @NotNull >> private String name; >> >> public String getName() { return name; } >> >> public void setName(String name) { this.name = name; } >> >> public Optional name() { return Optional.ofNullable(name);} >> >> } >> >> On the other hand this looks like an anti-pattern to me: >> >> public class Model { >> >> @NotNull >> private Optional name; >> >> public Optional getName() { return name; } >> >> public void setName(String name) { this.name = Optional.ofNullable(name); } >> >> } > > Yes Optional on a property is deemed an anti pattern by the JDK team but since Bean Validation supports contraints on method parameters and return values, this is still a valid use case > > Optional<@Email String> getUserEmail(@NotNull UUID userId); > > Emmanuel > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > > -- > Christian Kaltepoth > Blog: http://blog.kaltepoth.de/ > Twitter: http://twitter.com/chkal > GitHub: https://github.com/chkal > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/f9ee74e2/attachment.html From mbenson at apache.org Mon Nov 21 11:28:31 2016 From: mbenson at apache.org (Matt Benson) Date: Mon, 21 Nov 2016 10:28:31 -0600 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: On Mon, Nov 21, 2016 at 10:21 AM, Emmanuel Bernard wrote: > What?s the difference between a field and a getter based property? > It is the same for all intended purposes in Bean Validation. Point taken; I was thinking more of return values for business methods, personally. But like Christian says, perhaps it's more straightforward not to discriminate. Matt > >> On 21 Nov 2016, at 15:51, Matt Benson wrote: >> >> On Mon, Nov 21, 2016 at 8:18 AM, Gunnar Morling wrote: >>> Yes, probably we should not support Optional for fields. Also parameters are >>> dubious (the JDK team discourages that afaik). But supporting it for return >>> values (and getter-based properties) seems reasonable. >> >> +1 >> >> Matt (with apologies for not having participated earlier in the spec >> 2.0 process) >> >>> >>> 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard : >>>> >>>> >>>> On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: >>>> >>>> I don?t think that support for Optional is that important since having a >>>> field of type Optional looks like an anti-pattern to me. Normally Optional >>>> should be used as a method return type and not as a type for a field. >>>> Supporting it in the bean validation might end in strange model classes. >>>> >>>> Example: >>>> >>>> The following model looks good to me: >>>> >>>> public class Model { >>>> >>>> @NotNull >>>> private String name; >>>> >>>> public String getName() { return name; } >>>> >>>> public void setName(String name) { this.name = name; } >>>> >>>> public Optional name() { return Optional.ofNullable(name);} >>>> >>>> } >>>> >>>> On the other hand this looks like an anti-pattern to me: >>>> >>>> public class Model { >>>> >>>> @NotNull >>>> private Optional name; >>>> >>>> public Optional getName() { return name; } >>>> >>>> public void setName(String name) { this.name = Optional.ofNullable(name); >>>> } >>>> >>>> } >>>> >>>> >>>> Yes Optional on a property is deemed an anti pattern by the JDK team but >>>> since Bean Validation supports contraints on method parameters and return >>>> values, this is still a valid use case >>>> >>>> Optional<@Email String> getUserEmail(@NotNull UUID userId); >>>> >>>> Emmanuel >>>> >>>> >>>> _______________________________________________ >>>> beanvalidation-dev mailing list >>>> beanvalidation-dev at lists.jboss.org >>>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >>> >>> >>> >>> _______________________________________________ >>> beanvalidation-dev mailing list >>> beanvalidation-dev at lists.jboss.org >>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev >> >> _______________________________________________ >> beanvalidation-dev mailing list >> beanvalidation-dev at lists.jboss.org >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev From emmanuel at hibernate.org Mon Nov 21 11:31:29 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Mon, 21 Nov 2016 17:31:29 +0100 Subject: [bv-dev] Glossary Message-ID: <5D275F4F-75C9-4E12-B9B0-F7BD10AA6CCF@hibernate.org> If like me, you can?t remember how these class Foo and other List<@Email String> and other generics soup ingredients are named, there is a glossary of how we use these terms in Bean Validation http://beanvalidation.org/glossary/ From gunnar at hibernate.org Mon Nov 21 11:40:02 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Mon, 21 Nov 2016 17:40:02 +0100 Subject: [bv-dev] On the support for Optional (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: Agreed that it can be made work for all cases (the RI does it already more or less). Question is whether by supporting e.g. Optional fields we encourage modelling styles that are discouraged by the JDK team. But maybe that's just a question of documentation/wording, i.e. we could support it everywhere but only show usage on return values / getter props in the spec. > It is the same for all intended purposes in Bean Validation. There is one subtle difference actually. What should we return from PropertyDescriptor#getElementClass() if the field is Foo, but the getter is Optional? That's a case where our nice unified model falls apart a little bit. One quick thought would be to return Foo and have a new method isOptional(), though that wouldn't answer whether the field or the getter is optional. 2016-11-21 17:21 GMT+01:00 Emmanuel Bernard : > What?s the difference between a field and a getter based property? > It is the same for all intended purposes in Bean Validation. > > > On 21 Nov 2016, at 15:51, Matt Benson wrote: > > > > On Mon, Nov 21, 2016 at 8:18 AM, Gunnar Morling > wrote: > >> Yes, probably we should not support Optional for fields. Also > parameters are > >> dubious (the JDK team discourages that afaik). But supporting it for > return > >> values (and getter-based properties) seems reasonable. > > > > +1 > > > > Matt (with apologies for not having participated earlier in the spec > > 2.0 process) > > > >> > >> 2016-11-21 14:32 GMT+01:00 Emmanuel Bernard : > >>> > >>> > >>> On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > >>> > >>> I don?t think that support for Optional is that important since having > a > >>> field of type Optional looks like an anti-pattern to me. Normally > Optional > >>> should be used as a method return type and not as a type for a field. > >>> Supporting it in the bean validation might end in strange model > classes. > >>> > >>> Example: > >>> > >>> The following model looks good to me: > >>> > >>> public class Model { > >>> > >>> @NotNull > >>> private String name; > >>> > >>> public String getName() { return name; } > >>> > >>> public void setName(String name) { this.name = name; } > >>> > >>> public Optional name() { return Optional.ofNullable(name);} > >>> > >>> } > >>> > >>> On the other hand this looks like an anti-pattern to me: > >>> > >>> public class Model { > >>> > >>> @NotNull > >>> private Optional name; > >>> > >>> public Optional getName() { return name; } > >>> > >>> public void setName(String name) { this.name = > Optional.ofNullable(name); > >>> } > >>> > >>> } > >>> > >>> > >>> Yes Optional on a property is deemed an anti pattern by the JDK team > but > >>> since Bean Validation supports contraints on method parameters and > return > >>> values, this is still a valid use case > >>> > >>> Optional<@Email String> getUserEmail(@NotNull UUID userId); > >>> > >>> Emmanuel > >>> > >>> > >>> _______________________________________________ > >>> beanvalidation-dev mailing list > >>> beanvalidation-dev at lists.jboss.org > >>> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > >> > >> > >> > >> _______________________________________________ > >> beanvalidation-dev mailing list > >> beanvalidation-dev at lists.jboss.org > >> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > > _______________________________________________ > > beanvalidation-dev mailing list > > beanvalidation-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161121/79a36e76/attachment-0001.html From gunnar at hibernate.org Tue Nov 22 05:29:14 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Tue, 22 Nov 2016 11:29:14 +0100 Subject: [bv-dev] BV 2.0 - Add constraints? In-Reply-To: References: Message-ID: 2016-10-22 9:31 GMT+02:00 Christian Kaltepoth : > Hey Gunnar, > > thanks a lot for summarizing the results of the survey. See some comments > inline: > > > The survey has closed and we got some very interesting results from it >> (240 answers): >> >> * 97.9% wish for @NotEmpty >> * 87.9% wish for @NotBlank >> * 72.9% wish for @Positive/@Negative >> > > I expected these to be voted very often. These constraints are really > useful and therefore I think it would be very valuable to add them to the > spec. > > > * @Email is mentioned several times. As said in my blog post I'm very >> skeptical about supporting it, as a) requirements around e-mail validation >> are very different for different scenarios) and b) specs/RFCs around e-mail >> are not necessarily consistent. Hence I'm concerned about entering a mine >> field of everlasting bug reports around it. >> >> But Emmanuel made an interesting proposal that may work: Add the @Email >> constraint itself but leave the specific interpretation to BV providers. >> That'd make code using it portable in terms of compilation, but runtime >> behavior may differ of course. Feedback on this idea is welcome. >> > > Validating email addresses is a very common requirement. And therefor I > agree with people that it would be good to have it in the BV spec. However, > I also agree with Gunnar that validating email addresses isn't easy and > there are many weird corner cases. I actually like Emmanuel's idea. We > define the constraint in the spec and implementing the details correctly is > up to the BV implementation. IMO this is fine even if BV implementations > behave differently for certain corner cases which are usually very rare. > I've filed https://hibernate.atlassian.net/browse/BVAL-548 for the constraints above and @Email. Should have a proposal done for it quickly unless someone else feels like going for it. * Another interesting one is support for Unicode surrogate pairs (it's >> mentioned several times, though I'm not sure whether that was not one and >> the same person, given I've *never* heard about requests for it before). >> The issue is that there are characters with a code unit greater than what >> can be stored in two bytes. These are represented by "surrogate pairs", >> causing for instance "?".length() to return 2 and not 1 as one may expect. >> Hence values given in @Size need to take that into account. I feel people >> are best off with a custom validator addressing this case, but I'd be >> curious to hear what others think. We may explore support in the RI. >> > > That really looks too specific in my opinion. But I may be wrong about > that. Other thoughts? > I've got the same feeling, too. One more theme is cross-field / simpler class-level validation support. I >> hope we may address this in the course of BVAL-214. >> > > +1 > > > Christian > > > -- > Christian Kaltepoth > Blog: http://blog.kaltepoth.de/ > Twitter: http://twitter.com/chkal > GitHub: https://github.com/chkal > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161122/095d67d6/attachment.html From gunnar at hibernate.org Tue Nov 22 06:09:46 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Tue, 22 Nov 2016 12:09:46 +0100 Subject: [bv-dev] BV 2.0 - Add constraints? In-Reply-To: <20161026070200.GB72969@hibernate.org> References: <20161026070200.GB72969@hibernate.org> Message-ID: 2016-10-26 9:02 GMT+02:00 Emmanuel Bernard : > On Wed 16-10-19 12:09, Gunnar Morling wrote: > >* Another interesting one is support for Unicode surrogate pairs (it's > >mentioned several times, though I'm not sure whether that was not one and > >the same person, given I've *never* heard about requests for it before). > >The issue is that there are characters with a code unit greater than what > >can be stored in two bytes. These are represented by "surrogate pairs", > >causing for instance "?".length() to return 2 and not 1 as one may > expect. > >Hence values given in @Size need to take that into account. I feel people > >are best off with a custom validator addressing this case, but I'd be > >curious to hear what others think. We may explore support in the RI. > > About surrogate pairs, I am not at all familiar with it but could it be > resolve with a provider specific global option to handle surrogate pairs > or not. > I suppose your reluctance to support it is because it will take extra > CPU time for the common case correct? > It's not that so much, but more staying consistent with the semantics of CharacterSequence/String#length(). The docs of @Size say "length of character sequence is evaluated", so linking this to String#length() appears as the most natural and consistent thing to do. The docs of String#size() say "The length is equal to the number of Unicode code units in the string". I.e. the length of "?" is defined as 2, not 1. I think the user is best off to implement their own validator or constraint @CodePointCount. We could make it an option in the RI or provide such constraint/validator in the RI, but then it's the first and only time I've heard about this requirement so I'm not sure whether it pulls its weight. On another subject, one of the proposal was support for EL. Should we > leave it to the providers? Or embrace it? > Good question. We could promote @ScriptAssert from the RI. What do others think? That remark in the survey was targeted towards cross-field validation, so we'd need some more work on top of that (@ScriptAssert is a pure class-level constraint atm.). I hope cross-field support to fall out of BVAL-214 by some kind of detyped validator API, i.e. EL wouldn't even be needed for this use case. > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161122/7acce8d5/attachment.html From gunnar at hibernate.org Tue Nov 22 06:36:55 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Tue, 22 Nov 2016 12:36:55 +0100 Subject: [bv-dev] Constraint on non generic types (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: Just replying to this one: > == Constraint on non parameterized containers > I am liking option 3 less and less and as far as I can remember, it does not rely on an explicitly > identified use case. Who is wanting to support that usage, vs restrict the container feature to > parameterized containers? I'm not sure where this requirement is coming from. Wouldn't it simply be addressed by providing a validator for @Min + IntegerContainer? I.e. do we need any explicit support for this at all compared to what's possible today? Also the JavaFX case (your 2nd example around StringProperty) could be satisfied by just adding explicit validators for StringProperty, IntegerProperty etc. Agreed it's not as elegant/generic and wouldn't work for custom types. May still be a way forward, though. 2016-11-21 14:28 GMT+01:00 Emmanuel Bernard : > > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > In addition I think that simply adding a constraints annotation to the > generic type is wrong. All examples that we have mentioned are just perfect > examples in that the generic type defines the content. Let?s say we have a > class like this: > > public abstract class ConvertableInteger { > > private int value; > > public void setValue(int value) { this.value = value; } > > public int getValue() { return value; } > > public abstract V getConvertedValue(); > } > > If you want to validate an instance of this class you normally want to > validate the integer and not the converted value: > > private ConvertableInteger<@Min(2_000_000) Date> myValue; > > Such an expression looks like if you want to validate a Date object. In > this case the better solution would be something like this: > > @Min(2_000_000) > private ConvertableInteger myValue; > > > And now we end in 2 different ways how we annotation value wrappers: > > private CachableValue<@NotEmpty String> myCachedValue; > > @Min(2_000_000) > private ConvertableInteger myIntegerValue; > > > First off, your specific example does not work as is as the class is > abstract. You would need an explicit subclass (e.g. DateConvertableInteger > extends ConvertableInteger). And in that situation, The more natural > BV approach would be to do this: > > public class DateConvertableInteger extend ConvertableInteger { > > @Min(@2_000_000) > public int getValue() { return value; } > > @NotEmpty > public Date getConvertedValue(); > } > > class SomeClass { > @Valid > private StringConvertableInteger myValue; > } > > == overriding constraint declarations > > Now if you want a way to override the constraints of an embedded (@Valid) > object (graph), then I think that is a different subject that we can try > and address. JPA for example has the notion of @AttributeOverride. It is > more complicated in the case of Bean Validation as we would need to > override actual annotations. Not sure how to express that for now. Do we > think that it is a valid and important requirement? > > To clarify, here is what is required > > public class Embeddable { > @NotEmpty String foo; > } > > public class Entity { > @Valid @Override(path=?foo?, constraints=@Min(3)) // note that this is > not valid Java syntax > Embeddable embeddable; > } > > == Constraint on non parameterized containers > > That raises another question, the proposal allows to to three things: > > - apply constraints on a type use generic declaration(*): > Collection<@NotEmpty String> foo; > - apply constraints on specialized generic parameters (*): @Pattern(?) > StringProperty prop; //where StringProperty extends Property > - apply constraints on container with no generic: @Min(3) IntegerContainer > prop; // where class IntegerContainer{ Integer value; } i.e. no generic > > (*) I don?t know the actual proper names so sorry if I butchered notions > > I am liking option 3 less and less and as far as I can remember, it does > not rely on an explicitly identified use case. Who is wanting to support > that usage, vs restrict the container feature to parameterized containers? > > I?m not sure I was all that clear, so please ask any question if you have > any doubt. > > Emmanuel > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161122/38d00e42/attachment-0001.html From emmanuel at hibernate.org Tue Nov 22 08:13:56 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Tue, 22 Nov 2016 14:13:56 +0100 Subject: [bv-dev] Constraint on non generic types (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> Message-ID: <20161122131356.GD74045@hibernate.org> On Tue 16-11-22 12:36, Gunnar Morling wrote: >Just replying to this one: > >> == Constraint on non parameterized containers >> I am liking option 3 less and less and as far as I can remember, it does >not rely on an explicitly >> identified use case. Who is wanting to support that usage, vs restrict >the container feature to >> parameterized containers? > >I'm not sure where this requirement is coming from. Wouldn't it simply be >addressed by providing a validator for @Min + IntegerContainer? I.e. do we >need any explicit support for this at all compared to what's possible today? The big thing you lose by know understanding the notion of container is that validation won't be cascaded to objects in the container. @Valid AddressContainer This is close to impossible to reproduce by hand. >Also the JavaFX case (your 2nd example around StringProperty) could be >satisfied by just adding explicit validators for StringProperty, >IntegerProperty etc. Agreed it's not as elegant/generic and wouldn't work >for custom types. May still be a way forward, though. No, you can't do that. Unless you accept that @MyEmail constraint cannot be applied on a StringProperty. That's a big blocker for me. From emmanuel at hibernate.org Tue Nov 22 14:15:36 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Tue, 22 Nov 2016 20:15:36 +0100 Subject: [bv-dev] Extractors vs cascading logic (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: <475FED0B-0A63-40B2-841A-EC78D7DA8053@hibernate.org> References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <475FED0B-0A63-40B2-841A-EC78D7DA8053@hibernate.org> Message-ID: > On 21 Nov 2016, at 14:07, Emmanuel Bernard wrote: > > >> On 7 Nov 2016, at 23:42, Hendrik Ebbers > wrote: >> >> Let?s say we have the following 2 interfaces: >> >> public interface CachedValue { >> V getCachedValue(); >> } >> >> public interface RealValue { >> V getRealValue(); >> } >> >> Based on this interfaces we can easily create a new class that implements both interfaces: >> >> public class CachableValue implements CachedValue, RealValue { >> >> private V cachedValue; >> >> @Override >> public V getCachedValue() { >> return cachedValue; >> } >> >> @Override >> public V getRealValue() { >> V realValue = receiveValueFromServer(); >> cachedValue = realValue; >> return realValue; >> } >> >> private V receiveValueFromServer() { >> return ServerConnector.getCurrentValue(); //Some fake code >> } >> } >> >> Let?s try to add a constraint annotation to validate the content of such a CachableValue: >> >> private CachableValue<@NotEmpty String> myValue; >> >> Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem. Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea what will happen. >> >> The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on this I think that it will be a must to support all wrapper types. > > Interesting. > > I did think about extractors of subtypes but not extractors of parallel types. > I have been thinking about it and explored a few paths: > - validating all parallel extractors > - use one > - validate none > - fail > > In the end, I think the cleanest solution is to follow what Ceylon and Java do for default methods, they don?t allow ambiguous use and force a redefinition. > http://stackoverflow.com/questions/16764791/how-does-java-8-new-default-interface-model-works-incl-diamond-multiple-inhe#16788295 > > In practice for us, if there are extractors for CachedValue and for RealValue, then CachableValue should fail and require the definition of an explicit CachableValue extractor. > What is interesting in this case is that CachableValue extractor can be see as either: > - a ManyContainerValuesExtractor that will return getCachedValue and getRealValue just like a Collection would return get(0) and get(1). This approach does not reflect the path difference though > - or two SingleContainerValueExtractor from the same container type and the same value type (*) > > (*) this is something we do not allow for the moment, we have a unique extractor per container + value type. We need to think about how to make that work and still allow people to override extractors. > > So back to your original concern of uncertainty, I think forcing a more specific extractor solves the uncertainty that you mentioned. Granted, the user would have to know the extractor(s) behavior but in many ways, people do need to know about that regardless. > > Thoughts? Gunnar and I discussed this problem further and the proposal at large, in particular in the light of his alternative proposal (section 3). The main question we have is how common are constraints on user defined type like: - CachableValue // CacheableValue<@Email String> value; - Tuple // Tuple<@Email String, @Valid Address> userIdAndAddress; - ? Here I am excluding: - Optional - Collection and Map (and all Iterable really) - even Collections of non Java languages (Scala, Ceylon, Kotlin if they have their own collection type, etc) If constraints on the user defined types described above are common, then we need a more systematic solution than imposing to write an extractor for each of these cases. If they are uncommon and the only containers are Optional, Collection, Map, JavaFX containers and other language collections, or more generally framework provided containers, then a requiring an extractor implementation is not too problematic. To put some context, the overall BVAL-508 proposal addresses several things: - how to extract value from a container - where to express constraints on the values of a container - how and when the cascading logic should work In my proposal. extractors are explicit implementations (with built-in as well as custom implementations). The extractors: - extract the value(s) - express the link between the extractor and the type parameter (and thus the parameterized type) - must be implemented explicitly for each tuple extractor / type parameter Gunnar has an alternative proposal or rather a proposal that builds on top of the existing one but provide a default generic extractor logic. If no explicit extractor exists, the following will happen Assuming Tuple<@Email String, @Valid Address> userIdAndAddress; class Tuple { V1 v1; V2 v2; V1 getV1() { return v1; }; V2 getV2() { return v2; }; } The default extractor would look for all getters that return the parameterized type(s) and use the getter as extractor. It then would apply the constraint. In our case, the code would validate getV1() against @Email and getV2() will be cascaded. This is elegant and extremely regular. But it has a very ugly angle: should we validate the getters or the fields or the getters then the fields? The rule proposed by Gunnar is to validate the getters first because he likes them better and then look for fields with no corresponding getter and validate them. Assuming Tuple<@Email String, @Valid Address> userIdAndAddress; class Tuple { V1 v1; V1 v1b; V2 v2; V1 getV1() { return v1; }; V2 getV2() { return v2; }; } In this example, the code would validate getV1() against @Email, getV2() will be cascaded and v1b will be validated against @Email. This alternative proposal has two advantages: - it reduces the number of necessary extractor implementations (assuming the relevant elements have getters) - it makes the problem described by Hendrik with CacheableValue fully deterministic - it makes the logic of cascading very regular (for non collection at least) - it still requires the ability to write custom extractors for collection type containers I have to admit I hate the arbitrary logic of choosing getters and then fields. So my questions to you are: - how common do you see the Tuple, CacheableValue and other user defined type needing validation? - would you be satisfied by the getter approach as an extractor? - what do you think of the getter priority logic? What do you think? Emmanuel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161122/ea197c9e/attachment.html From mbenson at apache.org Tue Nov 22 15:22:14 2016 From: mbenson at apache.org (Matt Benson) Date: Tue, 22 Nov 2016 14:22:14 -0600 Subject: [bv-dev] Extractors vs cascading logic (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <475FED0B-0A63-40B2-841A-EC78D7DA8053@hibernate.org> Message-ID: In Therian there is a custom annotation to specify a method that provides a Type value at runtime. Specifically It allows one to designate a method that returns an instance of the Typed interface from Apache Commons Lang 3.x. Annotation: https://github.com/mbenson/therian/blob/master/core/src/main/java/therian/BindTypeVariable.java Example: https://github.com/mbenson/therian/blob/master/core/src/main/java/therian/operation/Transform.java Utilities: https://github.com/mbenson/therian/blob/master/core/src/main/java/therian/util/Types.java#L88 An approach like this would of course put some onus onto users with the payoff of being very explicit. In any case, it might provide food for thought on the subject. Matt On Tue, Nov 22, 2016 at 1:15 PM, Emmanuel Bernard wrote: > > On 21 Nov 2016, at 14:07, Emmanuel Bernard wrote: > > > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > Let?s say we have the following 2 interfaces: > > public interface CachedValue { > V getCachedValue(); > } > > public interface RealValue { > V getRealValue(); > } > > Based on this interfaces we can easily create a new class that implements > both interfaces: > > public class CachableValue implements CachedValue, RealValue { > > private V cachedValue; > > @Override > public V getCachedValue() { > return cachedValue; > } > > @Override > public V getRealValue() { > V realValue = receiveValueFromServer(); > cachedValue = realValue; > return realValue; > } > > private V receiveValueFromServer() { > return ServerConnector.getCurrentValue(); //Some fake code > } > } > > Let?s try to add a constraint annotation to validate the content of such a > CachableValue: > > private CachableValue<@NotEmpty String> myValue; > > Based on this definition you have absolutely no idea if the @NotEmpty > annotation is defined for the real value, the cached value or both values. > From my point of view this is a big problem. Until now its was always easy > to see how the validation of a model should work based on the validation > information (annotations) in the model. With this new approach you have no > idea what will happen. > > The most simple solution would be to add the support only to some special > container / wrapper classes like collections, JavaFX properties, etc. I > think this is a bad idea since new default might come to future versions of > JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on > this I think that it will be a must to support all wrapper types. > > > Interesting. > > I did think about extractors of subtypes but not extractors of parallel > types. > I have been thinking about it and explored a few paths: > - validating all parallel extractors > - use one > - validate none > - fail > > In the end, I think the cleanest solution is to follow what Ceylon and Java > do for default methods, they don?t allow ambiguous use and force a > redefinition. > http://stackoverflow.com/questions/16764791/how-does-java-8-new-default-interface-model-works-incl-diamond-multiple-inhe#16788295 > > In practice for us, if there are extractors for CachedValue and for > RealValue, then CachableValue should fail and require the definition of an > explicit CachableValue extractor. > What is interesting in this case is that CachableValue extractor can be see > as either: > - a ManyContainerValuesExtractor that will return getCachedValue and > getRealValue just like a Collection would return get(0) and get(1). This > approach does not reflect the path difference though > - or two SingleContainerValueExtractor from the same container type and the > same value type (*) > > (*) this is something we do not allow for the moment, we have a unique > extractor per container + value type. We need to think about how to make > that work and still allow people to override extractors. > > So back to your original concern of uncertainty, I think forcing a more > specific extractor solves the uncertainty that you mentioned. Granted, the > user would have to know the extractor(s) behavior but in many ways, people > do need to know about that regardless. > > Thoughts? > > > Gunnar and I discussed this problem further and the proposal at large, in > particular in the light of his alternative proposal (section 3). > > The main question we have is how common are constraints on user defined type > like: > > - CachableValue // CacheableValue<@Email String> value; > - Tuple // Tuple<@Email String, @Valid Address> userIdAndAddress; > - ? > > Here I am excluding: > - Optional > - Collection and Map (and all Iterable really) > - even Collections of non Java languages (Scala, Ceylon, Kotlin if they have > their own collection type, etc) > > If constraints on the user defined types described above are common, then we > need a more systematic solution than imposing to write an extractor for each > of these cases. > If they are uncommon and the only containers are Optional, Collection, Map, > JavaFX containers and other language collections, or more generally > framework provided containers, then a requiring an extractor implementation > is not too problematic. > > > To put some context, the overall BVAL-508 proposal addresses several things: > - how to extract value from a container > - where to express constraints on the values of a container > - how and when the cascading logic should work > > In my proposal. extractors are explicit implementations (with built-in as > well as custom implementations). The extractors: > - extract the value(s) > - express the link between the extractor and the type parameter (and thus > the parameterized type) > - must be implemented explicitly for each tuple extractor / type parameter > > Gunnar has an alternative proposal or rather a proposal that builds on top > of the existing one but provide a default generic extractor logic. > > If no explicit extractor exists, the following will happen > > Assuming > > Tuple<@Email String, @Valid Address> userIdAndAddress; > > class Tuple { > V1 v1; > V2 v2; > > V1 getV1() { return v1; }; > V2 getV2() { return v2; }; > } > > The default extractor would look for all getters that return the > parameterized type(s) and use the getter as extractor. It then would apply > the constraint. > In our case, the code would validate getV1() against @Email and getV2() will > be cascaded. > > This is elegant and extremely regular. But it has a very ugly angle: should > we validate the getters or the fields or the getters then the fields? > > The rule proposed by Gunnar is to validate the getters first because he > likes them better and then look for fields with no corresponding getter and > validate them. > > Assuming > > Tuple<@Email String, @Valid Address> userIdAndAddress; > > class Tuple { > V1 v1; > V1 v1b; > V2 v2; > > V1 getV1() { return v1; }; > V2 getV2() { return v2; }; > } > > In this example, the code would validate getV1() against @Email, getV2() > will be cascaded and v1b will be validated against @Email. > > This alternative proposal has two advantages: > - it reduces the number of necessary extractor implementations (assuming the > relevant elements have getters) > - it makes the problem described by Hendrik with CacheableValue fully > deterministic > - it makes the logic of cascading very regular (for non collection at least) > - it still requires the ability to write custom extractors for collection > type containers > > I have to admit I hate the arbitrary logic of choosing getters and then > fields. > > So my questions to you are: > - how common do you see the Tuple, CacheableValue and other user defined > type needing validation? > - would you be satisfied by the getter approach as an extractor? > - what do you think of the getter priority logic? > > What do you think? > > Emmanuel > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev From gunnar at hibernate.org Wed Nov 23 02:46:32 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Wed, 23 Nov 2016 08:46:32 +0100 Subject: [bv-dev] Extractors vs cascading logic (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <475FED0B-0A63-40B2-841A-EC78D7DA8053@hibernate.org> Message-ID: Hey Matt, It's great to see you here, has been a while :) Regarding that annotation, could you provide a small example tailored to the issue at hand to show what you have in mind with it? It's not fully clear to me yet. Thanks, --Gunnar 2016-11-22 21:22 GMT+01:00 Matt Benson : > In Therian there is a custom annotation to specify a method that > provides a Type value at runtime. Specifically It allows one to > designate a method that returns an instance of the Typed interface > from Apache Commons Lang 3.x. > > Annotation: https://github.com/mbenson/therian/blob/master/core/src/ > main/java/therian/BindTypeVariable.java > Example: https://github.com/mbenson/therian/blob/master/core/src/ > main/java/therian/operation/Transform.java > Utilities: https://github.com/mbenson/therian/blob/master/core/src/ > main/java/therian/util/Types.java#L88 > > An approach like this would of course put some onus onto users with > the payoff of being very explicit. In any case, it might provide food > for thought on the subject. > > Matt > > > On Tue, Nov 22, 2016 at 1:15 PM, Emmanuel Bernard > wrote: > > > > On 21 Nov 2016, at 14:07, Emmanuel Bernard > wrote: > > > > > > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > > > Let?s say we have the following 2 interfaces: > > > > public interface CachedValue { > > V getCachedValue(); > > } > > > > public interface RealValue { > > V getRealValue(); > > } > > > > Based on this interfaces we can easily create a new class that implements > > both interfaces: > > > > public class CachableValue implements CachedValue, RealValue { > > > > private V cachedValue; > > > > @Override > > public V getCachedValue() { > > return cachedValue; > > } > > > > @Override > > public V getRealValue() { > > V realValue = receiveValueFromServer(); > > cachedValue = realValue; > > return realValue; > > } > > > > private V receiveValueFromServer() { > > return ServerConnector.getCurrentValue(); //Some fake code > > } > > } > > > > Let?s try to add a constraint annotation to validate the content of such > a > > CachableValue: > > > > private CachableValue<@NotEmpty String> myValue; > > > > Based on this definition you have absolutely no idea if the @NotEmpty > > annotation is defined for the real value, the cached value or both > values. > > From my point of view this is a big problem. Until now its was always > easy > > to see how the validation of a model should work based on the validation > > information (annotations) in the model. With this new approach you have > no > > idea what will happen. > > > > The most simple solution would be to add the support only to some special > > container / wrapper classes like collections, JavaFX properties, etc. I > > think this is a bad idea since new default might come to future versions > of > > JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on > > this I think that it will be a must to support all wrapper types. > > > > > > Interesting. > > > > I did think about extractors of subtypes but not extractors of parallel > > types. > > I have been thinking about it and explored a few paths: > > - validating all parallel extractors > > - use one > > - validate none > > - fail > > > > In the end, I think the cleanest solution is to follow what Ceylon and > Java > > do for default methods, they don?t allow ambiguous use and force a > > redefinition. > > http://stackoverflow.com/questions/16764791/how-does- > java-8-new-default-interface-model-works-incl-diamond- > multiple-inhe#16788295 > > > > In practice for us, if there are extractors for CachedValue and for > > RealValue, then CachableValue should fail and require the definition of > an > > explicit CachableValue extractor. > > What is interesting in this case is that CachableValue extractor can be > see > > as either: > > - a ManyContainerValuesExtractor that will return getCachedValue and > > getRealValue just like a Collection would return get(0) and get(1). This > > approach does not reflect the path difference though > > - or two SingleContainerValueExtractor from the same container type and > the > > same value type (*) > > > > (*) this is something we do not allow for the moment, we have a unique > > extractor per container + value type. We need to think about how to make > > that work and still allow people to override extractors. > > > > So back to your original concern of uncertainty, I think forcing a more > > specific extractor solves the uncertainty that you mentioned. Granted, > the > > user would have to know the extractor(s) behavior but in many ways, > people > > do need to know about that regardless. > > > > Thoughts? > > > > > > Gunnar and I discussed this problem further and the proposal at large, in > > particular in the light of his alternative proposal (section 3). > > > > The main question we have is how common are constraints on user defined > type > > like: > > > > - CachableValue // CacheableValue<@Email String> value; > > - Tuple // Tuple<@Email String, @Valid Address> userIdAndAddress; > > - ? > > > > Here I am excluding: > > - Optional > > - Collection and Map (and all Iterable really) > > - even Collections of non Java languages (Scala, Ceylon, Kotlin if they > have > > their own collection type, etc) > > > > If constraints on the user defined types described above are common, > then we > > need a more systematic solution than imposing to write an extractor for > each > > of these cases. > > If they are uncommon and the only containers are Optional, Collection, > Map, > > JavaFX containers and other language collections, or more generally > > framework provided containers, then a requiring an extractor > implementation > > is not too problematic. > > > > > > To put some context, the overall BVAL-508 proposal addresses several > things: > > - how to extract value from a container > > - where to express constraints on the values of a container > > - how and when the cascading logic should work > > > > In my proposal. extractors are explicit implementations (with built-in as > > well as custom implementations). The extractors: > > - extract the value(s) > > - express the link between the extractor and the type parameter (and thus > > the parameterized type) > > - must be implemented explicitly for each tuple extractor / type > parameter > > > > Gunnar has an alternative proposal or rather a proposal that builds on > top > > of the existing one but provide a default generic extractor logic. > > > > If no explicit extractor exists, the following will happen > > > > Assuming > > > > Tuple<@Email String, @Valid Address> userIdAndAddress; > > > > class Tuple { > > V1 v1; > > V2 v2; > > > > V1 getV1() { return v1; }; > > V2 getV2() { return v2; }; > > } > > > > The default extractor would look for all getters that return the > > parameterized type(s) and use the getter as extractor. It then would > apply > > the constraint. > > In our case, the code would validate getV1() against @Email and getV2() > will > > be cascaded. > > > > This is elegant and extremely regular. But it has a very ugly angle: > should > > we validate the getters or the fields or the getters then the fields? > > > > The rule proposed by Gunnar is to validate the getters first because he > > likes them better and then look for fields with no corresponding getter > and > > validate them. > > > > Assuming > > > > Tuple<@Email String, @Valid Address> userIdAndAddress; > > > > class Tuple { > > V1 v1; > > V1 v1b; > > V2 v2; > > > > V1 getV1() { return v1; }; > > V2 getV2() { return v2; }; > > } > > > > In this example, the code would validate getV1() against @Email, getV2() > > will be cascaded and v1b will be validated against @Email. > > > > This alternative proposal has two advantages: > > - it reduces the number of necessary extractor implementations (assuming > the > > relevant elements have getters) > > - it makes the problem described by Hendrik with CacheableValue fully > > deterministic > > - it makes the logic of cascading very regular (for non collection at > least) > > - it still requires the ability to write custom extractors for collection > > type containers > > > > I have to admit I hate the arbitrary logic of choosing getters and then > > fields. > > > > So my questions to you are: > > - how common do you see the Tuple, CacheableValue and other user defined > > type needing validation? > > - would you be satisfied by the getter approach as an extractor? > > - what do you think of the getter priority logic? > > > > What do you think? > > > > Emmanuel > > > > _______________________________________________ > > beanvalidation-dev mailing list > > beanvalidation-dev at lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161123/55bead9a/attachment.html From gunnar at hibernate.org Wed Nov 23 03:06:59 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Wed, 23 Nov 2016 09:06:59 +0100 Subject: [bv-dev] Placing constraints on the container vs the contained type use (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: <5F0C4C29-6F1E-4B76-9CEE-4A20BA6F5F4C@hibernate.org> References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <5F0C4C29-6F1E-4B76-9CEE-4A20BA6F5F4C@hibernate.org> Message-ID: 2016-11-21 17:08 GMT+01:00 Emmanuel Bernard : > > On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: > > And this is not the only example. We already have some classes in JavaSE > that will end in such problems: > The basic Property class in JavaFX can be used like this: > > private Property myStringProperty; > > Based on the current approach we should add a constraint annotation like > this: > > private Property<@NotNull String> myStringProperty; > > But next to the property class JavaFX contains the class StringProperty > that is a specific implementation of ?Property?. If we want to use > this class we can not add a annotation to a generic type since we don?t > have such a generic type. Here we need to do it this way: > > @NotNull > private StringProperty myStringProperty2; > > And again we have 2 different approaches: > > private Property<@NotNull String> myStringProperty; > > @NotNull > private StringProperty myStringProperty2; > > 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. > > > General comment on you entire email. > > 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. > > 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. > +100. 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. > But everywhere we have a parameterized type use, we should have the app > developer make use of them instead of using the @ConstraintAppliesTo > workaround. > > > To be true I do not have the ultimative solution for this problem. > Currently I trying to add some metadata to the annotations to define it?s > goal. Here is an example: > > @NotEmpty > private List names1; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names2; > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > private List names3; > > 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 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 allowed) and in ?names3? the list must > contain at least one element and all elements must have a length > 0. > > 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: > > @NotNull(applyTo = ConstraintsApplyTo.INTERNALS) > private StringProperty myStringProperty2; > > Extracting this information to an additional (optional) annotation will be > a problem since this can end in such an expression: > > @NotEmpty > @ConstraintsApplyTo(CONTAINED_VALUES) > @NotEmpty > private List names3; > > 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. > > > 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: > > - you need a lot of information on side that it not trivial to digest > - each existing constraint annotation will have to be changed to add these > new attributes > - 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 > - at the end of the day, the feature is really for code using type use, so > we are twisting it for edge cases > > But I am very open to the idea of doing per annotation location overriding > if people think that they are an important feature. > > 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?). > Here are some code snippets that use additional information in the > annotations to define the validation: > > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) > private List>> spooky; > > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = > RealValue.class) > private RealValue myValue; > > The ?applyToInternalDepth? value is used to define how often the validator > should get the internal value (depth). In the given example > ?@NotEmpty(applyTo = ConstraintsApplyTo.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. > > > 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. > > On the depth approach, your example would be more easily rewritten as > > @NotEmpty List<@NotEmpty List<@NotEmpty List<@NotEmpty > StringProperty>>> spooky; > > which clarifies everything. But let?s assume we have a type > ListOfListOfListOfStringProperty type. do we really want to support > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) > private ListOfListOfListOfStringProperty spooky; > > or even > > @NotEmpty > // support nested levels by positioning ConstraintsApplyTo at the right > level > private List<@NotEmpty List<@NotEmpty @NotEmpty(applyTo = > ConstraintsApplyTo.CONTAINED_VALUES) ListOfStringProperty>> spooky; > > 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. > I'm also not convinced of this. In a way it seems to me like breaking encapsulation. 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: public class CustomerContacts { List> contacts; // one single inner list contains the contacts valid at a given time } 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. Instead the constraints should be declared within CustomerContacts itself. It's different for generic types. When dealing with a type like List>, 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. > Based on this a constraint annotation needs this additional fields: > > ConstraintsApplyTo applyTo() default ConstraintsApplyTo.VALUE; // VALUE > or INTERNALS > > int applyToInternalDepth() default 1; > > Class valueContainerClass() default Object.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. > > I think it?s quite important to have support for all the wrapper classes. > Validation collections and (JavaFX) properties will be a big benefit. > > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161123/1a4a5195/attachment-0001.html From emmanuel at hibernate.org Wed Nov 23 04:51:31 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Wed, 23 Nov 2016 10:51:31 +0100 Subject: [bv-dev] Placing constraints on the container vs the contained type use (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <5F0C4C29-6F1E-4B76-9CEE-4A20BA6F5F4C@hibernate.org> Message-ID: > On 23 Nov 2016, at 09:06, Gunnar Morling wrote: > > > > 2016-11-21 17:08 GMT+01:00 Emmanuel Bernard >: > >> On 7 Nov 2016, at 23:42, Hendrik Ebbers > wrote: > >> 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?). >> Here are some code snippets that use additional information in the annotations to define the validation: >> >> >> @NotEmpty >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) >> private List>> spooky; >> >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = RealValue.class) >> private RealValue myValue; >> >> The ?applyToInternalDepth? value is used to define how often the validator should get the internal value (depth). In the given example ?@NotEmpty(applyTo = ConstraintsApplyTo.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. > > 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. > > On the depth approach, your example would be more easily rewritten as > > @NotEmpty List<@NotEmpty List<@NotEmpty List<@NotEmpty StringProperty>>> spooky; > > which clarifies everything. But let?s assume we have a type ListOfListOfListOfStringProperty type. do we really want to support > > @NotEmpty > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 2) > @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = 3) > private ListOfListOfListOfStringProperty spooky; > > or even > > @NotEmpty > // support nested levels by positioning ConstraintsApplyTo at the right level > private List<@NotEmpty List<@NotEmpty @NotEmpty(applyTo = ConstraintsApplyTo.CONTAINED_VALUES) ListOfStringProperty>> spooky; > > 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. > > I'm also not convinced of this. In a way it seems to me like breaking encapsulation. > > 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: > > public class CustomerContacts { > List> contacts; // one single inner list contains the contacts valid at a given time > } > > 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. > > Instead the constraints should be declared within CustomerContacts itself. > > It's different for generic types. When dealing with a type like List>, 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. Ah interesting point of view. I?ve never thought of it that way. 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. @Email(validApplyTo=ConsgraintsApplyTo.CONTAINED_VALUE) Collection emails; But back to the question, is that even a valid use case in 2016? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161123/53eb6496/attachment.html From gunnar at hibernate.org Wed Nov 23 05:14:06 2016 From: gunnar at hibernate.org (Gunnar Morling) Date: Wed, 23 Nov 2016 11:14:06 +0100 Subject: [bv-dev] Placing constraints on the container vs the contained type use (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <5F0C4C29-6F1E-4B76-9CEE-4A20BA6F5F4C@hibernate.org> Message-ID: Personally, I wouldn't bother supporting raw collection types. Raw type usage is discouraged and may even go away in future Java versions IIUC. And you don't know what value type is in there from looking at the declaration, so we'd loose the ability to check correct constraint placement at compile time. 2016-11-23 10:51 GMT+01:00 Emmanuel Bernard : > > On 23 Nov 2016, at 09:06, Gunnar Morling wrote: > > > > 2016-11-21 17:08 GMT+01:00 Emmanuel Bernard : > >> >> On 7 Nov 2016, at 23:42, Hendrik Ebbers wrote: >> >> 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?). >> Here are some code snippets that use additional information in the >> annotations to define the validation: >> >> >> @NotEmpty >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = >> 2) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = >> 3) >> private List>> spooky; >> >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, valueContainerClass = >> RealValue.class) >> private RealValue myValue; >> >> The ?applyToInternalDepth? value is used to define how often the >> validator should get the internal value (depth). In the given example >> ?@NotEmpty(applyTo = ConstraintsApplyTo.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. >> >> >> 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. >> >> On the depth approach, your example would be more easily rewritten as >> >> @NotEmpty List<@NotEmpty List<@NotEmpty List<@NotEmpty >> StringProperty>>> spooky; >> >> which clarifies everything. But let?s assume we have a type >> ListOfListOfListOfStringProperty type. do we really want to support >> >> @NotEmpty >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = >> 2) >> @NotEmpty(applyTo = ConstraintsApplyTo.INTERNALS, applyToInternalDepth = >> 3) >> private ListOfListOfListOfStringProperty spooky; >> >> or even >> >> @NotEmpty >> // support nested levels by positioning ConstraintsApplyTo at the right >> level >> private List<@NotEmpty List<@NotEmpty @NotEmpty(applyTo = >> ConstraintsApplyTo.CONTAINED_VALUES) ListOfStringProperty>> spooky; >> >> 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. >> > > I'm also not convinced of this. In a way it seems to me like breaking > encapsulation. > > 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: > > public class CustomerContacts { > List> contacts; // one single inner list contains the > contacts valid at a given time > } > > 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. > > Instead the constraints should be declared within CustomerContacts itself. > > It's different for generic types. When dealing with a type like > List>, 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. > > > Ah interesting point of view. I?ve never thought of it that way. > > 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. > > @Email(validApplyTo=ConsgraintsApplyTo.CONTAINED_VALUE) > Collection emails; > > But back to the question, is that even a valid use case in 2016? > > > > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161123/3b87e146/attachment-0001.html From hardy at hibernate.org Wed Nov 23 06:19:26 2016 From: hardy at hibernate.org (Hardy Ferentschik) Date: Wed, 23 Nov 2016 12:19:26 +0100 Subject: [bv-dev] On the support for Optional In-Reply-To: References: <14D9EF93-484E-4176-AE8B-A1E6B8EEA72A@hibernate.org> Message-ID: <20161123111926.GA16743@nineveh.local> Hi, On Mon, 21-Nov-2016 17:40, Gunnar Morling wrote: > Agreed that it can be made work for all cases (the RI does it already more > or less). Question is whether by supporting e.g. Optional fields we > encourage modelling styles that are discouraged by the JDK team. But maybe > that's just a question of documentation/wording, i.e. we could support it > everywhere but only show usage on return values / getter props in the spec. I think I would also vote for making it possible for the sake of consistency. If your argument about minimising/preventing "misuse" would hold, one would need to look at supporting date types without timezone information again. There the argument was also that a user should not be prevented to use Bean Validation constraints and documentation is enough to make the user aware of potential dangers. --Hardy -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 496 bytes Desc: not available Url : http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161123/b8a3f80e/attachment.bin From emmanuel at hibernate.org Wed Nov 23 10:46:54 2016 From: emmanuel at hibernate.org (Emmanuel Bernard) Date: Wed, 23 Nov 2016 16:46:54 +0100 Subject: [bv-dev] Extractors vs cascading logic (was Re: Support for constraints on container values (e.g. Collection<@Email String>)) In-Reply-To: References: <20160906161213.GA35574@hibernate.org> <20160919112820.GE17874@hibernate.org> <475FED0B-0A63-40B2-841A-EC78D7DA8053@hibernate.org> Message-ID: <20F15885-9C0D-46FD-A7C3-BFE1C365B1CC@hibernate.org> I?ve created a blog post and survey on the subject http://beanvalidation.org/news/2016/11/23/survey-constraints-and-parameterized-type/ Tweet, share and spread around the world :) Emmanuel > On 22 Nov 2016, at 20:15, Emmanuel Bernard wrote: > > >> On 21 Nov 2016, at 14:07, Emmanuel Bernard > wrote: >> >> >>> On 7 Nov 2016, at 23:42, Hendrik Ebbers > wrote: >>> >>> Let?s say we have the following 2 interfaces: >>> >>> public interface CachedValue { >>> V getCachedValue(); >>> } >>> >>> public interface RealValue { >>> V getRealValue(); >>> } >>> >>> Based on this interfaces we can easily create a new class that implements both interfaces: >>> >>> public class CachableValue implements CachedValue, RealValue { >>> >>> private V cachedValue; >>> >>> @Override >>> public V getCachedValue() { >>> return cachedValue; >>> } >>> >>> @Override >>> public V getRealValue() { >>> V realValue = receiveValueFromServer(); >>> cachedValue = realValue; >>> return realValue; >>> } >>> >>> private V receiveValueFromServer() { >>> return ServerConnector.getCurrentValue(); //Some fake code >>> } >>> } >>> >>> Let?s try to add a constraint annotation to validate the content of such a CachableValue: >>> >>> private CachableValue<@NotEmpty String> myValue; >>> >>> Based on this definition you have absolutely no idea if the @NotEmpty annotation is defined for the real value, the cached value or both values. From my point of view this is a big problem. Until now its was always easy to see how the validation of a model should work based on the validation information (annotations) in the model. With this new approach you have no idea what will happen. >>> >>> The most simple solution would be to add the support only to some special container / wrapper classes like collections, JavaFX properties, etc. I think this is a bad idea since new default might come to future versions of JavaSE and JavaEE (or maybe Spring) and that won?t be supported. Based on this I think that it will be a must to support all wrapper types. >> >> Interesting. >> >> I did think about extractors of subtypes but not extractors of parallel types. >> I have been thinking about it and explored a few paths: >> - validating all parallel extractors >> - use one >> - validate none >> - fail >> >> In the end, I think the cleanest solution is to follow what Ceylon and Java do for default methods, they don?t allow ambiguous use and force a redefinition. >> http://stackoverflow.com/questions/16764791/how-does-java-8-new-default-interface-model-works-incl-diamond-multiple-inhe#16788295 >> >> In practice for us, if there are extractors for CachedValue and for RealValue, then CachableValue should fail and require the definition of an explicit CachableValue extractor. >> What is interesting in this case is that CachableValue extractor can be see as either: >> - a ManyContainerValuesExtractor that will return getCachedValue and getRealValue just like a Collection would return get(0) and get(1). This approach does not reflect the path difference though >> - or two SingleContainerValueExtractor from the same container type and the same value type (*) >> >> (*) this is something we do not allow for the moment, we have a unique extractor per container + value type. We need to think about how to make that work and still allow people to override extractors. >> >> So back to your original concern of uncertainty, I think forcing a more specific extractor solves the uncertainty that you mentioned. Granted, the user would have to know the extractor(s) behavior but in many ways, people do need to know about that regardless. >> >> Thoughts? > > Gunnar and I discussed this problem further and the proposal at large, in particular in the light of his alternative proposal (section 3). > > The main question we have is how common are constraints on user defined type like: > > - CachableValue // CacheableValue<@Email String> value; > - Tuple // Tuple<@Email String, @Valid Address> userIdAndAddress; > - ? > > Here I am excluding: > - Optional > - Collection and Map (and all Iterable really) > - even Collections of non Java languages (Scala, Ceylon, Kotlin if they have their own collection type, etc) > > If constraints on the user defined types described above are common, then we need a more systematic solution than imposing to write an extractor for each of these cases. > If they are uncommon and the only containers are Optional, Collection, Map, JavaFX containers and other language collections, or more generally framework provided containers, then a requiring an extractor implementation is not too problematic. > > > To put some context, the overall BVAL-508 proposal addresses several things: > - how to extract value from a container > - where to express constraints on the values of a container > - how and when the cascading logic should work > > In my proposal. extractors are explicit implementations (with built-in as well as custom implementations). The extractors: > - extract the value(s) > - express the link between the extractor and the type parameter (and thus the parameterized type) > - must be implemented explicitly for each tuple extractor / type parameter > > Gunnar has an alternative proposal or rather a proposal that builds on top of the existing one but provide a default generic extractor logic. > > If no explicit extractor exists, the following will happen > > Assuming > > Tuple<@Email String, @Valid Address> userIdAndAddress; > > class Tuple { > V1 v1; > V2 v2; > > V1 getV1() { return v1; }; > V2 getV2() { return v2; }; > } > > The default extractor would look for all getters that return the parameterized type(s) and use the getter as extractor. It then would apply the constraint. > In our case, the code would validate getV1() against @Email and getV2() will be cascaded. > > This is elegant and extremely regular. But it has a very ugly angle: should we validate the getters or the fields or the getters then the fields? > > The rule proposed by Gunnar is to validate the getters first because he likes them better and then look for fields with no corresponding getter and validate them. > > Assuming > > Tuple<@Email String, @Valid Address> userIdAndAddress; > > class Tuple { > V1 v1; > V1 v1b; > V2 v2; > > V1 getV1() { return v1; }; > V2 getV2() { return v2; }; > } > > In this example, the code would validate getV1() against @Email, getV2() will be cascaded and v1b will be validated against @Email. > > This alternative proposal has two advantages: > - it reduces the number of necessary extractor implementations (assuming the relevant elements have getters) > - it makes the problem described by Hendrik with CacheableValue fully deterministic > - it makes the logic of cascading very regular (for non collection at least) > - it still requires the ability to write custom extractors for collection type containers > > I have to admit I hate the arbitrary logic of choosing getters and then fields. > > So my questions to you are: > - how common do you see the Tuple, CacheableValue and other user defined type needing validation? > - would you be satisfied by the getter approach as an extractor? > - what do you think of the getter priority logic? > > What do you think? > > Emmanuel > _______________________________________________ > beanvalidation-dev mailing list > beanvalidation-dev at lists.jboss.org > https://lists.jboss.org/mailman/listinfo/beanvalidation-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.jboss.org/pipermail/beanvalidation-dev/attachments/20161123/dfecc01f/attachment.html