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]

Reply via email to