-
Notifications
You must be signed in to change notification settings - Fork 566
/
ClassBasedValidatorDescriptor.java
102 lines (84 loc) · 3.79 KB
/
ClassBasedValidatorDescriptor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
*/
package org.hibernate.validator.internal.engine.constraintvalidation;
import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.EnumSet;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
import org.hibernate.validator.internal.util.TypeHelper;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
/**
* Represents an implementation of {@link ConstraintValidator}.
*
* @author Gunnar Morling
* @author Guillaume Smet
*/
class ClassBasedValidatorDescriptor<A extends Annotation> implements ConstraintValidatorDescriptor<A> {
private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
private final Class<? extends ConstraintValidator<A, ?>> validatorClass;
private final Type validatedType;
private final EnumSet<ValidationTarget> validationTargets;
private ClassBasedValidatorDescriptor(Class<? extends ConstraintValidator<A, ?>> validatorClass) {
this.validatorClass = validatorClass;
this.validatedType = TypeHelper.extractValidatedType( validatorClass );
this.validationTargets = determineValidationTargets( validatorClass );
}
public static <T extends Annotation> ClassBasedValidatorDescriptor<T> of(Class<? extends ConstraintValidator<T, ?>> validatorClass,
Class<? extends Annotation> registeredConstraintAnnotationType) {
Type definedConstraintAnnotationType = TypeHelper.extractConstraintType( validatorClass );
if ( !registeredConstraintAnnotationType.equals( definedConstraintAnnotationType ) ) {
throw LOG.getConstraintValidatorDefinitionConstraintMismatchException( validatorClass, registeredConstraintAnnotationType,
definedConstraintAnnotationType );
}
return new ClassBasedValidatorDescriptor<T>( validatorClass );
}
/**
* Constraint checking is relaxed for built-in constraints as they have been carefully crafted so we are sure types
* are right.
*/
public static <T extends Annotation> ClassBasedValidatorDescriptor<T> ofBuiltin(Class<? extends ConstraintValidator<T, ?>> validatorClass,
Class<? extends Annotation> registeredConstraintAnnotationType) {
return new ClassBasedValidatorDescriptor<T>( validatorClass );
}
private static EnumSet<ValidationTarget> determineValidationTargets(Class<? extends ConstraintValidator<?, ?>> validatorClass) {
SupportedValidationTarget supportedTargetAnnotation = validatorClass.getAnnotation(
SupportedValidationTarget.class );
// by default constraints target the annotated element
if ( supportedTargetAnnotation == null ) {
return EnumSet.of( ValidationTarget.ANNOTATED_ELEMENT );
}
else {
return EnumSet.copyOf( Arrays.asList( supportedTargetAnnotation.value() ) );
}
}
@Override
public Class<? extends ConstraintValidator<A, ?>> getValidatorClass() {
return validatorClass;
}
@Override
public ConstraintValidator<A, ?> newInstance(ConstraintValidatorFactory constraintValidatorFactory) {
ConstraintValidator<A, ?> constraintValidator = constraintValidatorFactory.getInstance( validatorClass );
if ( constraintValidator == null ) {
throw LOG.getConstraintValidatorFactoryMustNotReturnNullException( validatorClass );
}
return constraintValidator;
}
@Override
public Type getValidatedType() {
return validatedType;
}
@Override
public EnumSet<ValidationTarget> getValidationTargets() {
return validationTargets;
}
}