Gunnar asked me an interesting question on Bean Validation. Instead of keeping the knowledge private, I thought it would be useful to share more wildly.
Is it possible to determine whether a given constraint is specified at field or property level using the constraint metadata API?
First off, in many case you don't need to do the distinction. Had Java support properties from the ground up, we would not have this problem (sigh).
Anyways, the answer is yes. You can fine tune what is returned from the metadata API.
PropertyDescriptor property = validator.getConstraintsForClass(Address.class) .getConstraintsForProperty("street1"); Set<ConstraintDescriptor<?>> fieldConstraints = property .findConstraints() .lookingAt(Scope.LOCAL_ELEMENT) .declaredOn(ElementType.FIELD) .getConstraintDescriptors(); Set<ConstraintDescriptor<?>> propertyConstraints = property .findConstraints() .lookingAt(Scope.LOCAL_ELEMENT) .declaredOn(ElementType.METHOD) .getConstraintDescriptors();
The key here is the use of the findConstraints() fluent API. You have three ways to restrict the metadata retrieved:
- declaredOn(ElementType... types): defines where to look the constraints (METHOD, FIELD etc)
- lookingAt(Scope scope): defines whether to look for constraints hosted on superclass/interfaces (default) or not
- unorderedAndMatchingGroups(Class<?>... groups): restrict to the constraints matching a given set of groups for this element (note that the ordering of group sequences is not respected)