[bv-dev] Cross parameter validation convergence

Hardy Ferentschik hardy at hibernate.org
Wed Aug 29 06:00:57 EDT 2012


Hi,

Answering the question from http://beanvalidation.org/proposals/BVAL-232/

#1. Generic approach vs Type-safe approach (with annotation processors)

+1 for the Generic approach, meaning 'boolean isValid(Object[] parameterValues, ConstraintValidatorContext context);'

#2. Do we also support the type-safe approach in parallel?

-1 it seems simpler to just go for the generic approach first. Since the type-safe approach can be a simple add-on we can leave
it for a later BV version and see first how users react to the generic approach

#3. In case type-safe approach is supported, do we keep the generic isValid method on the interface

+1 I believe it is important that at least this part of the contract is enforced 


--Hardy




On 29 Jan 2012, at 11:03 AM, Emmanuel Bernard wrote:

> I would like to bring home cross parameter validation which is one of the main open issues in method validation.
> We have been discussing it for literally 11 months, it's time to converge. If you could give your feedback quickly, Gunnar 
> might be able to add it to the spec in the next few days. I am already pushing him harder than I should to
> move BV forward so give him some help :)
> 
> The following is a less readable copy of what you can find at http://beanvalidation.org/proposals/BVAL-232/
> 
> ### Cross parameter validation and return value
> 
> Do we agree that validating both the parameters and the return value in a single
> constraint validator is not a use case we want to cover?
> To me that would be awkward to support it as we would need to execute the method
> to validate it.
> 
> ### Where to host cross-parameter constraints
> 
> We use the method as host to the return value constraints and possibly `@Valid`.
> That is unfortunately also the natural place for cross parameter constraints.
> 
> I cannot think of another place to put them. There is also no easy way to add a
> visual cue and differentiate a regular constraint from a cross param constraint
> except by its meta annotation. We would rely on the user adding a visual cue in
> the constraint name. Which kind of cue? Put `param` in the constraint name?
> 
> Any one can think of a better approach?
> 
> #### Bean Validation class
> 
>    @interface CrossParameterConstraint {
>        public Class<? extends CrossParameterConstraintValidator<?, ?>>[] validatedBy();
>    }
> 
>    interface CrossParameterConstraintValidator<A extends Annotation> {
>        void initialize(A constraintAnnotation);
>        [...]
>    }
> 
>> Question: does these different annotations/interfaces affect the metadata API?
>> 
>> Question: can the same constraint annotation be annotated by both
>> `@Constraint` and `@CrossParameterConstraint`: `@ScriptAssert` is a good candidate
>> Note: how does composition plays into this?
> 
> #### Constraint coder class
> 
>    @CrossParameterConstraint(validatedBy=CheckRetypedPasswordValidator.class)
>    @interface  CheckRetypedPasswordParameter {
>        String message() default "...";
>        Class<?>[] groups() default {};
>        class<? extends Payload>[] payload();
>    }
> 
>    class CheckRetypedPasswordValidator implements
>            CrossParameterConstraintValidator<CheckRetypedPasswordParameter> {
>        ...
>    }
> 
> #### User code
> 
>    class AccountService {
>        //cross param constraints
>        @CheckRetypedPasswordParameter
>        //return value constraints 
>        @Valid @NotNull
>        User createUser(@NotEmpty String username, @Email String email, String password, String retypedPassword);
>    }
> 
> ### What is the cross parameter constraint validator contract?
> 
> There has been two leading proposals. the others are described in the
> [previous proposal][previous proposal].
> 
> #### Generic approach
> 
>    interface CrossParameterConstraintValidator<A extends Annotations> {
>        void initialize(...) { ... }
>        boolean isValid(Object[] parameterValues, ConstraintValidatorContext context);
>    }
> 
> #### Type-safe approach (with annotation processors)
> 
> A more type-safe approach is to reuse the parameters signature of the method to match.
> While the Java compiler cannot discover problems, both an annotation processor and the bean validation provider at runtime
> can detect inconsistent contracts and raise respectively compilation errors and deployment time exception.
> 
>    class CheckRetypedPasswordValidator implements
>            CrossParameterConstraintValidator<CheckRetypedPasswordParameter> {
>        void initialize(...) { ... }
>        boolean isValid(String username, String email, String password, String retypedPassword,
>                        ConstraintValidatorContext context) {
>            ...
>        }
>    }
> 
> #### Discussions
> 
> I think we must put the generic approach in because that's the only way to write non
> method specific cross parameter constraints. Two examples of such constraints are
> 
> - script based constraints
> - generic password retype checks based on the parameter indexes
>  `@AreEqual(indexes={2,3}, message="Passwords must be identical")`
> 
> So the remaining question is do we also support the type-safe approach in parallel?
> I am inclined to think yes. We can do it on the same `CrossParameterConstraintValidator`
> implementation:
> 
> 
>    class CheckRetypedPasswordValidator implements
>            CrossParameterConstraintValidator<CheckRetypedPasswordParameter> {
>        void initialize(...) { ... }
> 
>        boolean isValid(Object[] parameterValues, ConstraintValidatorContext context);
> 
>        boolean isValid(String username, String email, String password, String retypedPassword,
>                        ConstraintValidatorContext context) {
>            ...
>        }
>    }
> 
> If the method validated has a matching signature, we use it, otherwise we use the generic
> method.
> 
> Do we keep the generic `isValid` method on the interface, thus forcing people to implement
> it? Or is that an optional non constrained contract?
> I am tempted to think that forcing is a better approach (the implementation can raise an
> exception). Thoughts?
> 
> [jira]: https://hibernate.onjira.com/browse/BVAL-232
> [previous proposal]: /proposals/BVAL-241/#cross_parameter
> 
> 
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev




More information about the beanvalidation-dev mailing list