Em Thu, 07 Jan 2010 17:07:27 -0200, Igor Drobiazko
<[email protected]> escreveu:
Hi Thiago,
Hi!
ValidationConstraintGenerator is invoked when the default binding for
validators is created.The generated validation contraints are used for
both server-side and client-side validation.
Ok!
Because of some differences between
JSR-303 validators and Tapestry validator you can't invoke a JSR-303
validator when default bindings are created. It's just too early.
I have a package in the Ars Machina Project that integrates Hibernate
Validator 3 annotations by implementing ValidationConstraintGenerators
that look at the property annnotations.
In contrast client-side validation constraints should be created very
early in order to render the javascript. That's why we need some
mechanism to map constraint annotations to javascript methods.
ValidationConstraintGenerator is not appropriate for JSR-303 validators.
First of all because of the
differences between @Vaidate and a bunch of JSR-303 validators.
The out-of-the-box ValidationConstraintGenerators use the @Validate
annotation, but you can add more implementations that take a look at other
annotations.
In Tapestry we have a single annotation (@Validate) that has the only one
attribute 'value'. In JSR-303 there is a bunch of annotations,
each with *several* attributes. A Tapestry validator can only have a
*single* constraint: e.g. maxlength=1 or min=5 whereby JSR-validator can
have several constraints.
You can generate more than one Tapestry validation for a single property.
And don't forget that the ValidationConstraintGenerator is a pipeline
service.
The annotation @Size for example has 'min' and 'max'
attributes,
In this specific case, you can implement it as a single
ValidationConstraintGenerator:
final public class SizeValidationConstraintsGenerator implements
ValidationConstraintGenerator {
@SuppressWarnings("unchecked")
public List<String> buildConstraints(Class propertyType,
AnnotationProvider annotationProvider) {
List<String> validations = null;
Size size = annotationProvider.getAnnotation(Size.class);
if (size != null) {
validations = new ArrayList<String>();
validations.add(String.format("min=%d", size.min()));
validations.add(String.format("max=%d", size.max()));
}
return strings;
}
}
The error message of the JSR-303 constraint is also defined inside the
annotation. You have to interpolate (MessageInterpolator#interpolate) the
message and pass the result to the javascript function in order to have
the same error message for server-side and client-side validation.
Now you've convinced me. :)
In summary I would say that the validation mechanism of Tapestry and
JSR-303 differ more than I would expect. I tried many things and
experimented a lot. You can believe me that I tried to prototype
different approaches to come up with the best possible solution. The
current implementation is the result of these experiments.
I believe you. ;) Keep up the good work!
--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da
Informação Ltda.
http://www.arsmachina.com.br
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]