[Stripes-users] ValidateNestedProperties on more than one level
Hi all! I was wondering : is it possible to do nested validation to more than one level? Lets say I want to validate the name of an Account contained in a WebModel, for instance : getWebModel().getAccount().getName() I know the annotation @ValidateNestedProperties makes it possible to validate one level , but apparently it is impossible to go deeper... I think i ll fall back to validation methods but that would have been nice, no? Any idea? Cheers -- Samuel Baudouin -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users
Re: [Stripes-users] ValidateNestedProperties on more than one level
Hi Samuel, Apparently, you're right : @ValidateNestedProperties references @Validate, not @ValidateNestedProperties again... If this can help you, I have a workaround. I'm using a custom NestedValidationMetadataProvider in Woko, that allows you to write validation annotations inside your POJOs, and have Stripes use them. Stuff like this : class MyAction implements ActionBean { ... @ValidateNestedProperties([]) MyClass myProp ... } and class MyClass { @Validate(required=true) String foo } The basic idea is that when an action bean property's marked with an empty @ValidateNestedProperties, the NestedMetadataValidationProvider recurses into the property and applies it's validation info. With the example above, request parameter 'myProp.foo' has to be provided. Of course, the provider can recurse to any depth, which means you can even write this : class MyClass { @ValidateNestedProperties([]) MyOtherClass other } class MyOtherClass { @Validate(...) String bar } Last, the metadata provider will favor the run-time type of the property. You can even write this : class MyAction implements ActionBean { ... @ValidateNestedProperties([]) Object prop } Then the validation metadata provider will (if prop ain't null of course) get the runtime type of the instance referenced by 'prop' and introspect for validation errors. I tend to think this behavior should be standard in Stripes. Yeah, I know, you shouldn't have dependencies of your Domain Model on Stripes, it's bd... But I often have collaborators to my actions that are not part of the domain model. They're UI objects. And I don't always know the runtime type of the action's properties (hey, inheritance...). So I'd like to annotate whatever class I want with @Validate, and if it's reachable by the action bean at request processing time, then have Stripes validate everything. Feels natural, doesn't it ? Last, this nested validation metadata provider allows for better factorization the validation logic : you can delegate to action collaborators, and the validation rules will depend on the objects referenced by your action bean. Anyway, in case you're interested : https://github.com/vankeisb/woko2/blob/master/stripes-plugins/src/main/java/woko/actions/nestedvalidation/NestedValidationMetadataProvider.java I'd be happy to have the community feedback on this btw... HTH Cheers Remi 2011/3/10 samuel baudouin osenseij...@gmail.com Hi all! I was wondering : is it possible to do nested validation to more than one level? Lets say I want to validate the name of an Account contained in a WebModel, for instance : getWebModel().getAccount().getName() I know the annotation @ValidateNestedProperties makes it possible to validate one level , but apparently it is impossible to go deeper... I think i ll fall back to validation methods but that would have been nice, no? Any idea? Cheers -- Samuel Baudouin -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users
Re: [Stripes-users] ValidateNestedProperties on more than one level
Hi Remi and thanks for your answer! I can see I'm not the only that faced that problem! Like you said, that forces the dev to think about the validation outside the ActionBean... Wouldn't that be a problem if you only want to validate on one of them and not others? I was in the source code of the validation process of Stripes jsut now and I saw that : public class DefaultValidationMetadataProvider implements ValidationMetadataProvider { [] protected MapString, ValidationMetadata loadForClass(Class? beanType) { [..] // add all sub-properties referenced in @ValidateNestedProperties if (nested != null) { Validate[] validates = nested.value(); if (validates != null) { for (Validate validate : validates) { if (validate.field() != null !.equals(validate.field())) { String fullName = propertyName + '.' + validate.field(); if (meta.containsKey(fullName)) { log.warn(More than one nested @Validate with same field name: + validate.field() + on property + propertyName); } meta.put(fullName, new ValidationMetadata(fullName, validate)); } else { log.warn(Field name missing from nested @Validate: , clazz, , property , propertyName); } } } } [] Which is exactly what you overrided. But wouldn't it possible to do something like : // add all sub-properties referenced in @ValidateNestedProperties if (nested != null) { Validate[] validates = nested.value(); if (validates != null) { for (Validate validate : validates) { if (validate.field() != null !.equals(validate.field())) { String fullName = propertyName + '.' + validate.field(); if (meta.containsKey(fullName)) { log.warn(More than one nested @Validate with same field name: + validate.field() + on property + propertyName); } meta.put(fullName, new ValidationMetadata(fullName, validate)); } else { log.warn(Field name missing from nested @Validate: , clazz, , property , propertyName); } } ValidateNestedProperties[] nestedProps = nested.nestedProps(); for (ValidateNestedProperties current : nestedProps) { [yada yada] } } } where in [yada yada] a call to a recursive method could be made ... and of course modify ValidateNestedProperties annotation to match that... What decisions made you code NestedValidationMetadataProvider that way? There has to be something that I don't see but what? Regards, Sam On Thu, Mar 10, 2011 at 7:08 PM, VANKEISBELCK Remi r...@rvkb.com wrote: Hi Samuel, Apparently, you're right : @ValidateNestedProperties references @Validate, not @ValidateNestedProperties again... If this can help you, I have a workaround. I'm using a custom NestedValidationMetadataProvider in Woko, that allows you to write validation annotations inside your POJOs, and have Stripes use them. Stuff like this : class MyAction implements ActionBean { ... @ValidateNestedProperties([]) MyClass myProp ... } and class MyClass { @Validate(required=true) String foo } The basic idea is that when an action bean property's marked with an empty @ValidateNestedProperties, the NestedMetadataValidationProvider recurses into the property and applies it's validation info. With the example above, request parameter 'myProp.foo' has to be provided. Of course, the provider can recurse to any depth, which means you can even write this : class MyClass { @ValidateNestedProperties([]) MyOtherClass other } class MyOtherClass { @Validate(...) String bar } Last, the metadata provider will favor the run-time type of the property. You can even write this : class MyAction implements ActionBean { ... @ValidateNestedProperties([]) Object prop } Then the
Re: [Stripes-users] ValidateNestedProperties on more than one level
Hi again, Yes for sure, if you want to keep the validation on the bean class, the immediate option would probably be : @ValidateMetadataProperties([ @Validate(field=foo, ..), @ValidateNestedProperties([ @Validate(field=bar) ]) )] It doesn't seem possible to achieve this currently (we'd need some kind of inheritance in the annotations, plus some work in DefaultValidationMetadataProvider). Feel free to open a feature request in JIRA ! I've pointed you to Woko's NestedValidationMetadataProvider as a workaround to this problem. And yes, as you've noticed, it goes a bit further by doing all this dynamically... In short, Woko is one action bean, that doesn't know the runtime type of some of its bound properties : class WokoActionBean implements ActionBean { Object facet // - can be anything ! } So I needed this to be working at runtime, even when the declared property in the action bean is java.lang.Object. And as Stripes validation annotations are neat, well, I wanted to use them in non-actionbean classes too, and have everything work smoothly. In that case the static approach to validation in Stripes doesn't work : I don't know the type of the action's properties at the time I write the action itself :) Cheers Remi 2011/3/10 samuel baudouin osenseij...@gmail.com Hi Remi and thanks for your answer! I can see I'm not the only that faced that problem! Like you said, that forces the dev to think about the validation outside the ActionBean... Wouldn't that be a problem if you only want to validate on one of them and not others? I was in the source code of the validation process of Stripes jsut now and I saw that : public class DefaultValidationMetadataProvider implements ValidationMetadataProvider { [] protected MapString, ValidationMetadata loadForClass(Class? beanType) { [..] // add all sub-properties referenced in @ValidateNestedProperties if (nested != null) { Validate[] validates = nested.value(); if (validates != null) { for (Validate validate : validates) { if (validate.field() != null !.equals(validate.field())) { String fullName = propertyName + '.' + validate.field(); if (meta.containsKey(fullName)) { log.warn(More than one nested @Validate with same field name: + validate.field() + on property + propertyName); } meta.put(fullName, new ValidationMetadata(fullName, validate)); } else { log.warn(Field name missing from nested @Validate: , clazz, , property , propertyName); } } } } [] Which is exactly what you overrided. But wouldn't it possible to do something like : // add all sub-properties referenced in @ValidateNestedProperties if (nested != null) { Validate[] validates = nested.value(); if (validates != null) { for (Validate validate : validates) { if (validate.field() != null !.equals(validate.field())) { String fullName = propertyName + '.' + validate.field(); if (meta.containsKey(fullName)) { log.warn(More than one nested @Validate with same field name: + validate.field() + on property + propertyName); } meta.put(fullName, new ValidationMetadata(fullName, validate)); } else { log.warn(Field name missing from nested @Validate: , clazz, , property , propertyName); } } ValidateNestedProperties[] nestedProps = nested.nestedProps(); for (ValidateNestedProperties current : nestedProps) { [yada yada] } } } where in [yada yada] a call to a recursive method could be made ... and of course modify ValidateNestedProperties annotation to match that... What decisions made you code NestedValidationMetadataProvider that way? There has to be something that I don't see but
Re: [Stripes-users] ValidateNestedProperties on more than one level
Properties can be nested as deeply as you need them to be. Nested field names are separated by dots. For your example, you'd use: @ValidateNestedProperties(@Validate(field=*account.name*, ...)) private WebModel webModel; -Ben On Thu, Mar 10, 2011 at 5:48 AM, samuel baudouin osenseij...@gmail.comwrote: Hi all! I was wondering : is it possible to do nested validation to more than one level? Lets say I want to validate the name of an Account contained in a WebModel, for instance : getWebModel().getAccount().getName() I know the annotation @ValidateNestedProperties makes it possible to validate one level , but apparently it is impossible to go deeper... I think i ll fall back to validation methods but that would have been nice, no? Any idea? Cheers -- Samuel Baudouin -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users
Re: [Stripes-users] ValidateNestedProperties on more than one level
Remi, thanks for those precisions! But it seems like Stripes beats us again! Ben, thanks for that! Sometimes the most obvious is not what we think about in the first place! Cheers all, Sam On Thu, Mar 10, 2011 at 9:36 PM, Ben Gunter gunter...@gmail.com wrote: Properties can be nested as deeply as you need them to be. Nested field names are separated by dots. For your example, you'd use: @ValidateNestedProperties(@Validate(field=account.name, ...)) private WebModel webModel; -Ben On Thu, Mar 10, 2011 at 5:48 AM, samuel baudouin osenseij...@gmail.com wrote: Hi all! I was wondering : is it possible to do nested validation to more than one level? Lets say I want to validate the name of an Account contained in a WebModel, for instance : getWebModel().getAccount().getName() I know the annotation @ValidateNestedProperties makes it possible to validate one level , but apparently it is impossible to go deeper... I think i ll fall back to validation methods but that would have been nice, no? Any idea? Cheers -- Samuel Baudouin -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users -- Samuel Baudouin -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users
Re: [Stripes-users] ValidateNestedProperties on more than one level
Even easier :) Still, doesn't address the dynamic aspect of the problem. Cheers Remi 2011/3/10 samuel baudouin osenseij...@gmail.com Remi, thanks for those precisions! But it seems like Stripes beats us again! Ben, thanks for that! Sometimes the most obvious is not what we think about in the first place! Cheers all, Sam On Thu, Mar 10, 2011 at 9:36 PM, Ben Gunter gunter...@gmail.com wrote: Properties can be nested as deeply as you need them to be. Nested field names are separated by dots. For your example, you'd use: @ValidateNestedProperties(@Validate(field=account.name, ...)) private WebModel webModel; -Ben On Thu, Mar 10, 2011 at 5:48 AM, samuel baudouin osenseij...@gmail.com wrote: Hi all! I was wondering : is it possible to do nested validation to more than one level? Lets say I want to validate the name of an Account contained in a WebModel, for instance : getWebModel().getAccount().getName() I know the annotation @ValidateNestedProperties makes it possible to validate one level , but apparently it is impossible to go deeper... I think i ll fall back to validation methods but that would have been nice, no? Any idea? Cheers -- Samuel Baudouin -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users -- Samuel Baudouin -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d ___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users -- Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d___ Stripes-users mailing list Stripes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/stripes-users