you're obviously right, I didn't foresee so many annotations.
I've quickly tried an implementation of SizeContraint to implement
multiple times the interfaces,
as in Validator<String>,Validator<Map> but it won't compile as
technically I'm repeating the same interface.
So I agree with you, I don't see better options and you really need
more than one implementation per annotation.
Sanne
2009/1/25 Emmanuel Bernard <emmanuel(a)hibernate.org>:
On Jan 25, 2009, at 06:45, Sanne Grinovero wrote:
> The "check String length" "check Array size" and "check
Collection
> size" validators could use different annotations;
> by the same criteria it would be fine for Collection, Map and Set to
> share the same annotation to check for
> size, as the implementation is only concerned about receiving a
> Collection as common superinterface.
So if we take the built-in constraints, we would have
@NotNull, @Null => ConstraintValidator<?, Object>
@AssertTrue, @AssertFAlse => ConstraintValidator<?, Boolean> (autoboxing)
@MinForNumber, @MaxForNumer => ConstraintValidator<?, Number> (autoboxing +
BigDecimal and BigInteger)
@MinForString, @MaxForString => ConstraintValidator<?, String>
@SizeForCollection => ConstraintValidator<?, Collection>
@SizeForMap => ConstraintValidator<?, Map>
@SizeForArray => ConstraintValidator<?, Object[]>
@SizeForString => ConstraintValidator<?, String>
@DigitsForNumbers => ConstraintValidator<?, Number> (autoboxing + BigDecimal
and BigInteger)
@DigitsForString => ConstraintValidator<?, String>
@PastForDate => ConstraintValidator<?, Date>
@PastForCalendar => ConstraintValidator<?, Calendar>
@FutureForDate => ConstraintValidator<?, Date>
@FutureForCalendar => ConstraintValidator<?, Calendar>
And if for some reason we need to differenciate Bigdecimal/Integer from the
other Number subclasses, we will need to do
@MaxForInteger
@MaxForShort
@MaxForLong
@MaxForFloat
@MaxForDouble
@MaxForBigInteger
@MaxForBigDecimal
Same when the new Date framework will show up, we will have another set of
@Past* and @Future*
So instead of 10 primitive cosntraints, we end up with 18 up to 38+
annotations
Are you *sure* you prefer the monotype with its proliferation of annotations
to the multitype drawbacks?
>
>
> I can live with some more annotations if it is more explicit to
> understand which one is going to be used,
> especially if the validation framework warns me about incompatible
> types at startup.
> (and developers wouldn't need to consider mystic
> AmbiguousValidatorException implications).
No the Validation framework cannot warn you of incompatible types at startup
because the list of bans is not known at startup. The exception will be
raised when validator.validate(runtimeSpecificTypeInstance); is called and
only if one of the getter values lead to inconsistency.
Your IDE or findbugs or whatever you use can help you (ie has the knowledge)
but this is not enforced at compile time.
On ambiguity we can have three kind of rules:
- raise an exception
- choose the first validator matching in the constraint provider list the
object instance type
- choose the first validator matching in the constraint provider list the
getter return type (ie the expected superset of the object instance type).
Note that if the constraint implementor is careful, this kind of ambiguity
never happens:
- String, Number, Date, Calendar combinations are never ambiguous
- Object and any other type is never ambiguous
Things become ambiguous when you:
- mix several "compatible" interfaces (ie interfaces that can be
implemented by the same object and are not in the same hierarchy) eg.
Serialuzable, Clonable
- mix supertypes and interfaces (eg ArrayList and Serializable and if
someone subclass ArrayList)