[bv-dev] Method validation: cross-parameter constraints
Gunnar Morling
gunnar.morling at googlemail.com
Sun Feb 26 06:21:11 EST 2012
Hi all,
one of the larger open points related to method validation is how to
support cross-parameter constraints.
The BVAL-241 proposal discusses pro's and con's of several variants
[1]. The different options are:
#1 - Don't support cross-parameter constraints in BV 1.1
#2 - New interface MethodConstraintValidator
public interface MethodConstraintValidator<A extends Annotation> {
void initialize(A constraintAnnotation);
boolean isValid(Object[] parameterValues,
ConstraintValidatorContext context);
}
#3 - Invoke validator methods by signature matching
public class DateParameterCheckValidator implements
Initializable<DateParameterCheck> {
//defined in Initializable
public void initialize(DateParameterCheck constraint) {}
//invoked by convention for methods annotated with
@DataParameterCheck and the argument types Customer, Date, Date
public boolean isValid(Customer customer, Date from, Date to,
ConstraintValidatorContext context) { ... }
//invoked by convention for methods annotated with
@DataParameterCheck and the argument types Customer, Date, Date, Date
public boolean isValid(Customer customer, Date from, Date to, Date
alternativeTo, ConstraintValidatorContext context) { ... }
}
#4 - Script based approach
public class ReservationService {
@ParameterAssert(script="arg1.before(arg2)", lang="javascript")
void bookHotel(@NotNull Customer customer, @NotNull Date from,
@NotNull Date to) { ... }
}
#5 Parametrized interfaces MethodConstraintValidatorN for N method parameters
public interface MethodConstraintValidator3<A extends Annotation, T1, T2, T3> {
void initialize(A constraintAnnotation);
boolean isValid(T1 parameter1, T2 parameter2, T3 parameter3,
ConstraintValidatorContext context);
}
public class DateParameterCheckValidator implements
MethodConstraintValidator3<DateParameterCheck, Customer, Date, Date> {
public void initialize(DateParameterCheck constraint) {}
public boolean isValid(Customer customer, Date from, Date to,
ConstraintValidatorContext context) { ... }
}
Please refer to the proposal document [1] for the individual pro's and
con's. Emmanuel, Hardy and I also discussed this on GitHub [2]:
* our preference is generally for something around #2 and #3
* we might offer a mixed approach, both supporting #2 *and* #3
While #2 would define a more strict MethodConstraintValidator contract
it would require implementors to do some ugly casts. #3 has a less
strict MethodConstraintValidator contract (it works by convention) but
would provide implementors a more typed experience.
Personally I think both approaches actually aren't that much
different. Both are inherently type-unsafe, but #3 would move the
efforts for dealing with that away from the constraint implementor
towards the BV provider. Note that #3 could also be checked by an
annotation processor, while #2 couldn't.
Note also that all approaches are somewhat inconsistent compared to
"normal" parameter and return value constraints, as they are based on
a method-level annotation (opposed to parameter-level). But I don't
see really a way around that.
What do you other folks think about that? Which approach would you
prefer, and why? Do you have another idea altogether?
@Emmanuel: For the first BV 1.1 draft I suggest to leave out
cross-parameter constraints. This shouldn't change the general scheme
of method validation, so we could add that in a later draft revision.
--Gunnar
[1] http://beanvalidation.org/proposals/BVAL-241/#cross_parameter
[2] https://github.com/beanvalidation/beanvalidation.org/commit/bc37cfec514b79f7695ccb35f9990115c5fdeab8#commitcomment-968467
More information about the beanvalidation-dev
mailing list