[Stripes-users] ValidateNestedProperties on more than one level

2011-03-10 Thread samuel baudouin
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

2011-03-10 Thread VANKEISBELCK Remi
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

2011-03-10 Thread samuel baudouin
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

2011-03-10 Thread VANKEISBELCK Remi
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

2011-03-10 Thread Ben Gunter
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

2011-03-10 Thread samuel baudouin
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

2011-03-10 Thread VANKEISBELCK Remi
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