1
7 package org.hibernate.validator.internal.engine.constraintvalidation;
8
9 import java.lang.annotation.Annotation;
10 import java.lang.invoke.MethodHandles;
11 import java.lang.reflect.Type;
12 import java.util.Arrays;
13 import java.util.EnumSet;
14
15 import javax.validation.ConstraintValidator;
16 import javax.validation.ConstraintValidatorFactory;
17 import javax.validation.constraintvalidation.SupportedValidationTarget;
18 import javax.validation.constraintvalidation.ValidationTarget;
19
20 import org.hibernate.validator.internal.util.TypeHelper;
21 import org.hibernate.validator.internal.util.logging.Log;
22 import org.hibernate.validator.internal.util.logging.LoggerFactory;
23
24
30 class ClassBasedValidatorDescriptor<A extends Annotation> implements ConstraintValidatorDescriptor<A> {
31
32 private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
33
34 private final Class<? extends ConstraintValidator<A, ?>> validatorClass;
35 private final Type validatedType;
36 private final EnumSet<ValidationTarget> validationTargets;
37
38 private ClassBasedValidatorDescriptor(Class<? extends ConstraintValidator<A, ?>> validatorClass) {
39 this.validatorClass = validatorClass;
40 this.validatedType = TypeHelper.extractValidatedType( validatorClass );
41 this.validationTargets = determineValidationTargets( validatorClass );
42 }
43
44 public static <T extends Annotation> ClassBasedValidatorDescriptor<T> of(Class<? extends ConstraintValidator<T, ?>> validatorClass,
45 Class<? extends Annotation> registeredConstraintAnnotationType) {
46 Type definedConstraintAnnotationType = TypeHelper.extractConstraintType( validatorClass );
47 if ( !registeredConstraintAnnotationType.equals( definedConstraintAnnotationType ) ) {
48 throw LOG.getConstraintValidatorDefinitionConstraintMismatchException( validatorClass, registeredConstraintAnnotationType,
49 definedConstraintAnnotationType );
50 }
51
52 return new ClassBasedValidatorDescriptor<T>( validatorClass );
53 }
54
55
59 public static <T extends Annotation> ClassBasedValidatorDescriptor<T> ofBuiltin(Class<? extends ConstraintValidator<T, ?>> validatorClass,
60 Class<? extends Annotation> registeredConstraintAnnotationType) {
61 return new ClassBasedValidatorDescriptor<T>( validatorClass );
62 }
63
64 private static EnumSet<ValidationTarget> determineValidationTargets(Class<? extends ConstraintValidator<?, ?>> validatorClass) {
65 SupportedValidationTarget supportedTargetAnnotation = validatorClass.getAnnotation(
66 SupportedValidationTarget.class );
67
68
69 if ( supportedTargetAnnotation == null ) {
70 return EnumSet.of( ValidationTarget.ANNOTATED_ELEMENT );
71 }
72 else {
73 return EnumSet.copyOf( Arrays.asList( supportedTargetAnnotation.value() ) );
74 }
75 }
76
77 @Override
78 public Class<? extends ConstraintValidator<A, ?>> getValidatorClass() {
79 return validatorClass;
80 }
81
82 @Override
83 public ConstraintValidator<A, ?> newInstance(ConstraintValidatorFactory constraintValidatorFactory) {
84 ConstraintValidator<A, ?> constraintValidator = constraintValidatorFactory.getInstance( validatorClass );
85
86 if ( constraintValidator == null ) {
87 throw LOG.getConstraintValidatorFactoryMustNotReturnNullException( validatorClass );
88 }
89
90 return constraintValidator;
91 }
92
93 @Override
94 public Type getValidatedType() {
95 return validatedType;
96 }
97
98 @Override
99 public EnumSet<ValidationTarget> getValidationTargets() {
100 return validationTargets;
101 }
102 }
103