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 Map<String, 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 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
> > baaaad...
> > 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
> >
> >
>
>
>
> --
> 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

Reply via email to