1 /*
2  * Hibernate Validator, declare and validate application constraints
3  *
4  * License: Apache License, Version 2.0
5  * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6  */

7 package org.hibernate.validator.internal.metadata.core;
8
9 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_ASSERT_FALSE;
10 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_ASSERT_TRUE;
11 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MAX;
12 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MIN;
13 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_DIGITS;
14 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_EMAIL;
15 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_FUTURE;
16 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_FUTURE_OR_PRESENT;
17 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_MAX;
18 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_MIN;
19 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE;
20 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE_OR_ZERO;
21 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NOT_BLANK;
22 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NOT_EMPTY;
23 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL;
24 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NULL;
25 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_PAST;
26 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_PAST_OR_PRESENT;
27 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_PATTERN;
28 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_POSITIVE;
29 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_POSITIVE_OR_ZERO;
30 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_SIZE;
31 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CNPJ;
32 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CPF;
33 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_TITULO_ELEITORAL;
34 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CODE_POINT_LENGTH;
35 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CREDIT_CARD_NUMBER;
36 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CURRENCY;
37 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EAN;
38 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EMAIL;
39 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_ISBN;
40 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LENGTH;
41 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LUHN_CHECK;
42 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK;
43 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK;
44 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD_CHECK;
45 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NORMALIZED;
46 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_BLANK;
47 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_EMPTY;
48 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PARAMETER_SCRIPT_ASSERT;
49 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_NIP;
50 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_PESEL;
51 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_REGON;
52 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_RANGE;
53 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SAFE_HTML;
54 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SCRIPT_ASSERT;
55 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MAX;
56 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MIN;
57 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_UNIQUE_ELEMENTS;
58 import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_URL;
59 import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES;
60
61 import java.lang.annotation.Annotation;
62 import java.lang.invoke.MethodHandles;
63 import java.lang.reflect.Method;
64 import java.security.AccessController;
65 import java.security.PrivilegedAction;
66 import java.util.ArrayList;
67 import java.util.Arrays;
68 import java.util.Collections;
69 import java.util.HashMap;
70 import java.util.HashSet;
71 import java.util.List;
72 import java.util.Map;
73 import java.util.Set;
74 import java.util.concurrent.ConcurrentHashMap;
75 import java.util.concurrent.ConcurrentMap;
76 import java.util.function.Function;
77 import java.util.stream.Collectors;
78 import java.util.stream.Stream;
79
80 import javax.validation.Constraint;
81 import javax.validation.ConstraintTarget;
82 import javax.validation.ConstraintValidator;
83 import javax.validation.constraints.AssertFalse;
84 import javax.validation.constraints.AssertTrue;
85 import javax.validation.constraints.DecimalMax;
86 import javax.validation.constraints.DecimalMin;
87 import javax.validation.constraints.Digits;
88 import javax.validation.constraints.Email;
89 import javax.validation.constraints.Future;
90 import javax.validation.constraints.FutureOrPresent;
91 import javax.validation.constraints.Max;
92 import javax.validation.constraints.Min;
93 import javax.validation.constraints.Negative;
94 import javax.validation.constraints.NegativeOrZero;
95 import javax.validation.constraints.NotBlank;
96 import javax.validation.constraints.NotEmpty;
97 import javax.validation.constraints.NotNull;
98 import javax.validation.constraints.Null;
99 import javax.validation.constraints.Past;
100 import javax.validation.constraints.PastOrPresent;
101 import javax.validation.constraints.Pattern;
102 import javax.validation.constraints.Positive;
103 import javax.validation.constraints.PositiveOrZero;
104 import javax.validation.constraints.Size;
105 import javax.validation.constraintvalidation.ValidationTarget;
106
107 import org.hibernate.validator.constraints.CodePointLength;
108 import org.hibernate.validator.constraints.ConstraintComposition;
109 import org.hibernate.validator.constraints.CreditCardNumber;
110 import org.hibernate.validator.constraints.Currency;
111 import org.hibernate.validator.constraints.EAN;
112 import org.hibernate.validator.constraints.ISBN;
113 import org.hibernate.validator.constraints.Length;
114 import org.hibernate.validator.constraints.LuhnCheck;
115 import org.hibernate.validator.constraints.Mod10Check;
116 import org.hibernate.validator.constraints.Mod11Check;
117 import org.hibernate.validator.constraints.ModCheck;
118 import org.hibernate.validator.constraints.Normalized;
119 import org.hibernate.validator.constraints.ParameterScriptAssert;
120 import org.hibernate.validator.constraints.Range;
121 import org.hibernate.validator.constraints.SafeHtml;
122 import org.hibernate.validator.constraints.ScriptAssert;
123 import org.hibernate.validator.constraints.URL;
124 import org.hibernate.validator.constraints.UniqueElements;
125 import org.hibernate.validator.constraints.br.CNPJ;
126 import org.hibernate.validator.constraints.br.CPF;
127 import org.hibernate.validator.constraints.br.TituloEleitoral;
128 import org.hibernate.validator.constraints.pl.NIP;
129 import org.hibernate.validator.constraints.pl.PESEL;
130 import org.hibernate.validator.constraints.pl.REGON;
131 import org.hibernate.validator.constraints.time.DurationMax;
132 import org.hibernate.validator.constraints.time.DurationMin;
133 import org.hibernate.validator.internal.constraintvalidators.bv.AssertFalseValidator;
134 import org.hibernate.validator.internal.constraintvalidators.bv.AssertTrueValidator;
135 import org.hibernate.validator.internal.constraintvalidators.bv.DigitsValidatorForCharSequence;
136 import org.hibernate.validator.internal.constraintvalidators.bv.DigitsValidatorForNumber;
137 import org.hibernate.validator.internal.constraintvalidators.bv.EmailValidator;
138 import org.hibernate.validator.internal.constraintvalidators.bv.NotBlankValidator;
139 import org.hibernate.validator.internal.constraintvalidators.bv.NotNullValidator;
140 import org.hibernate.validator.internal.constraintvalidators.bv.NullValidator;
141 import org.hibernate.validator.internal.constraintvalidators.bv.PatternValidator;
142 import org.hibernate.validator.internal.constraintvalidators.bv.money.CurrencyValidatorForMonetaryAmount;
143 import org.hibernate.validator.internal.constraintvalidators.bv.money.DecimalMaxValidatorForMonetaryAmount;
144 import org.hibernate.validator.internal.constraintvalidators.bv.money.DecimalMinValidatorForMonetaryAmount;
145 import org.hibernate.validator.internal.constraintvalidators.bv.money.DigitsValidatorForMonetaryAmount;
146 import org.hibernate.validator.internal.constraintvalidators.bv.money.MaxValidatorForMonetaryAmount;
147 import org.hibernate.validator.internal.constraintvalidators.bv.money.MinValidatorForMonetaryAmount;
148 import org.hibernate.validator.internal.constraintvalidators.bv.money.NegativeOrZeroValidatorForMonetaryAmount;
149 import org.hibernate.validator.internal.constraintvalidators.bv.money.NegativeValidatorForMonetaryAmount;
150 import org.hibernate.validator.internal.constraintvalidators.bv.money.PositiveOrZeroValidatorForMonetaryAmount;
151 import org.hibernate.validator.internal.constraintvalidators.bv.money.PositiveValidatorForMonetaryAmount;
152 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArray;
153 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfBoolean;
154 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfByte;
155 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfChar;
156 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfDouble;
157 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfFloat;
158 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfInt;
159 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfLong;
160 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForArraysOfShort;
161 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForCharSequence;
162 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForCollection;
163 import org.hibernate.validator.internal.constraintvalidators.bv.notempty.NotEmptyValidatorForMap;
164 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForBigDecimal;
165 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForBigInteger;
166 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForByte;
167 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForCharSequence;
168 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForDouble;
169 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForFloat;
170 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForInteger;
171 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForLong;
172 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForNumber;
173 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MaxValidatorForShort;
174 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForBigDecimal;
175 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForBigInteger;
176 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForByte;
177 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForCharSequence;
178 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForDouble;
179 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForFloat;
180 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForInteger;
181 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForLong;
182 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForNumber;
183 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.MinValidatorForShort;
184 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForBigDecimal;
185 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForBigInteger;
186 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForByte;
187 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForCharSequence;
188 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForDouble;
189 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForFloat;
190 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForInteger;
191 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForLong;
192 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForNumber;
193 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMaxValidatorForShort;
194 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForBigDecimal;
195 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForBigInteger;
196 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForByte;
197 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForCharSequence;
198 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForDouble;
199 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForFloat;
200 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForInteger;
201 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForLong;
202 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForNumber;
203 import org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal.DecimalMinValidatorForShort;
204 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForBigDecimal;
205 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForBigInteger;
206 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForByte;
207 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForCharSequence;
208 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForDouble;
209 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForFloat;
210 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForInteger;
211 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForLong;
212 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForNumber;
213 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeOrZeroValidatorForShort;
214 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForBigDecimal;
215 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForBigInteger;
216 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForByte;
217 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForCharSequence;
218 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForDouble;
219 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForFloat;
220 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForInteger;
221 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForLong;
222 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForNumber;
223 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.NegativeValidatorForShort;
224 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForBigDecimal;
225 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForBigInteger;
226 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForByte;
227 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForCharSequence;
228 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForDouble;
229 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForFloat;
230 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForInteger;
231 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForLong;
232 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForNumber;
233 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveOrZeroValidatorForShort;
234 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForBigDecimal;
235 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForBigInteger;
236 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForByte;
237 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForCharSequence;
238 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForDouble;
239 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForFloat;
240 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForInteger;
241 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForLong;
242 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForNumber;
243 import org.hibernate.validator.internal.constraintvalidators.bv.number.sign.PositiveValidatorForShort;
244 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArray;
245 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfBoolean;
246 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfByte;
247 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfChar;
248 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfDouble;
249 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfFloat;
250 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfInt;
251 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfLong;
252 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForArraysOfShort;
253 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForCharSequence;
254 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForCollection;
255 import org.hibernate.validator.internal.constraintvalidators.bv.size.SizeValidatorForMap;
256 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForCalendar;
257 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForDate;
258 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForHijrahDate;
259 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForInstant;
260 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForJapaneseDate;
261 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForLocalDate;
262 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForLocalDateTime;
263 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForLocalTime;
264 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForMinguoDate;
265 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForMonthDay;
266 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForOffsetDateTime;
267 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForOffsetTime;
268 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForReadableInstant;
269 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForReadablePartial;
270 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForThaiBuddhistDate;
271 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForYear;
272 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForYearMonth;
273 import org.hibernate.validator.internal.constraintvalidators.bv.time.future.FutureValidatorForZonedDateTime;
274 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForCalendar;
275 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForDate;
276 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForHijrahDate;
277 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForInstant;
278 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForJapaneseDate;
279 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForLocalDate;
280 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForLocalDateTime;
281 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForLocalTime;
282 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForMinguoDate;
283 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForMonthDay;
284 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForOffsetDateTime;
285 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForOffsetTime;
286 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForReadableInstant;
287 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForReadablePartial;
288 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForThaiBuddhistDate;
289 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForYear;
290 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForYearMonth;
291 import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForZonedDateTime;
292 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForCalendar;
293 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForDate;
294 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForHijrahDate;
295 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForInstant;
296 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForJapaneseDate;
297 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForLocalDate;
298 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForLocalDateTime;
299 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForLocalTime;
300 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForMinguoDate;
301 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForMonthDay;
302 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForOffsetDateTime;
303 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForOffsetTime;
304 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForReadableInstant;
305 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForReadablePartial;
306 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForThaiBuddhistDate;
307 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForYear;
308 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForYearMonth;
309 import org.hibernate.validator.internal.constraintvalidators.bv.time.past.PastValidatorForZonedDateTime;
310 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForCalendar;
311 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForDate;
312 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForHijrahDate;
313 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForInstant;
314 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForJapaneseDate;
315 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForLocalDate;
316 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForLocalDateTime;
317 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForLocalTime;
318 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForMinguoDate;
319 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForMonthDay;
320 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForOffsetDateTime;
321 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForOffsetTime;
322 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForReadableInstant;
323 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForReadablePartial;
324 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForThaiBuddhistDate;
325 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForYear;
326 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForYearMonth;
327 import org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent.PastOrPresentValidatorForZonedDateTime;
328 import org.hibernate.validator.internal.constraintvalidators.hv.CodePointLengthValidator;
329 import org.hibernate.validator.internal.constraintvalidators.hv.EANValidator;
330 import org.hibernate.validator.internal.constraintvalidators.hv.ISBNValidator;
331 import org.hibernate.validator.internal.constraintvalidators.hv.LengthValidator;
332 import org.hibernate.validator.internal.constraintvalidators.hv.LuhnCheckValidator;
333 import org.hibernate.validator.internal.constraintvalidators.hv.Mod10CheckValidator;
334 import org.hibernate.validator.internal.constraintvalidators.hv.Mod11CheckValidator;
335 import org.hibernate.validator.internal.constraintvalidators.hv.ModCheckValidator;
336 import org.hibernate.validator.internal.constraintvalidators.hv.NormalizedValidator;
337 import org.hibernate.validator.internal.constraintvalidators.hv.ParameterScriptAssertValidator;
338 import org.hibernate.validator.internal.constraintvalidators.hv.SafeHtmlValidator;
339 import org.hibernate.validator.internal.constraintvalidators.hv.ScriptAssertValidator;
340 import org.hibernate.validator.internal.constraintvalidators.hv.URLValidator;
341 import org.hibernate.validator.internal.constraintvalidators.hv.UniqueElementsValidator;
342 import org.hibernate.validator.internal.constraintvalidators.hv.br.CNPJValidator;
343 import org.hibernate.validator.internal.constraintvalidators.hv.br.CPFValidator;
344 import org.hibernate.validator.internal.constraintvalidators.hv.pl.NIPValidator;
345 import org.hibernate.validator.internal.constraintvalidators.hv.pl.PESELValidator;
346 import org.hibernate.validator.internal.constraintvalidators.hv.pl.REGONValidator;
347 import org.hibernate.validator.internal.constraintvalidators.hv.time.DurationMaxValidator;
348 import org.hibernate.validator.internal.constraintvalidators.hv.time.DurationMinValidator;
349 import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorDescriptor;
350 import org.hibernate.validator.internal.util.CollectionHelper;
351 import org.hibernate.validator.internal.util.Contracts;
352 import org.hibernate.validator.internal.util.logging.Log;
353 import org.hibernate.validator.internal.util.logging.LoggerFactory;
354 import org.hibernate.validator.internal.util.privilegedactions.GetAnnotationAttribute;
355 import org.hibernate.validator.internal.util.privilegedactions.GetDeclaredMethods;
356 import org.hibernate.validator.internal.util.privilegedactions.GetMethod;
357 import org.hibernate.validator.internal.util.privilegedactions.IsClassPresent;
358 import org.hibernate.validator.internal.util.stereotypes.Immutable;
359
360 /**
361  * Keeps track of builtin constraints and their validator implementations, as well as already resolved validator definitions.
362  *
363  * @author Hardy Ferentschik
364  * @author Alaa Nassef
365  * @author Gunnar Morling
366  * @author Guillaume Smet
367  */

368 public class ConstraintHelper {
369
370     public static final String GROUPS = "groups";
371     public static final String PAYLOAD = "payload";
372     public static final String MESSAGE = "message";
373     public static final String VALIDATION_APPLIES_TO = "validationAppliesTo";
374
375     private static final List<String> SUPPORTED_VALID_METHODS = Collections.singletonList( VALIDATION_APPLIES_TO );
376
377     private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
378     private static final String JODA_TIME_CLASS_NAME = "org.joda.time.ReadableInstant";
379     private static final String JAVA_MONEY_CLASS_NAME = "javax.money.MonetaryAmount";
380     private static final String JSOUP_CLASS_NAME = "org.jsoup.Jsoup";
381
382     @Immutable
383     private final Map<Class<? extends Annotation>, List<? extends ConstraintValidatorDescriptor<?>>> enabledBuiltinConstraints;
384
385     private final ConcurrentMap<Class<? extends Annotation>, Boolean> externalConstraints = new ConcurrentHashMap<>();
386
387     private final ConcurrentMap<Class<? extends Annotation>, Boolean> multiValueConstraints = new ConcurrentHashMap<>();
388
389     private final ValidatorDescriptorMap validatorDescriptors = new ValidatorDescriptorMap();
390
391     private Boolean javaMoneyInClasspath;
392
393     private Boolean jodaTimeInClassPath;
394
395     private Boolean jsoupInClasspath;
396
397     public static ConstraintHelper forAllBuiltinConstraints() {
398         return new ConstraintHelper( new HashSet<>( Arrays.asList( BuiltinConstraint.values() ) ) );
399     }
400
401     public static ConstraintHelper forBuiltinConstraints(Set<String> enabledConstraints) {
402         return new ConstraintHelper( BuiltinConstraint.resolve( enabledConstraints ) );
403     }
404
405     @SuppressWarnings("deprecation")
406     private ConstraintHelper(Set<BuiltinConstraint> enabledBuiltinConstraints) {
407         if ( enabledBuiltinConstraints.isEmpty() ) {
408             this.enabledBuiltinConstraints = Collections.emptyMap();
409             return;
410         }
411
412         Map<Class<? extends Annotation>, List<ConstraintValidatorDescriptor<?>>> tmpConstraints = new HashMap<>();
413
414         // Bean Validation constraints
415
416         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_ASSERT_FALSE ) ) {
417             putBuiltinConstraint( tmpConstraints, AssertFalse.class, AssertFalseValidator.class );
418         }
419         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_ASSERT_TRUE ) ) {
420             putBuiltinConstraint( tmpConstraints, AssertTrue.class, AssertTrueValidator.class );
421         }
422
423         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MAX ) ) {
424             List<Class<? extends ConstraintValidator<DecimalMax, ?>>> decimalMaxValidators = new ArrayList<>();
425             decimalMaxValidators.add( DecimalMaxValidatorForBigDecimal.class );
426             decimalMaxValidators.add( DecimalMaxValidatorForBigInteger.class );
427             decimalMaxValidators.add( DecimalMaxValidatorForByte.class );
428             decimalMaxValidators.add( DecimalMaxValidatorForDouble.class );
429             decimalMaxValidators.add( DecimalMaxValidatorForFloat.class );
430             decimalMaxValidators.add( DecimalMaxValidatorForLong.class );
431             decimalMaxValidators.add( DecimalMaxValidatorForInteger.class );
432             decimalMaxValidators.add( DecimalMaxValidatorForNumber.class );
433             decimalMaxValidators.add( DecimalMaxValidatorForShort.class );
434             decimalMaxValidators.add( DecimalMaxValidatorForCharSequence.class );
435             if ( isJavaMoneyInClasspath() ) {
436                 decimalMaxValidators.add( DecimalMaxValidatorForMonetaryAmount.class );
437             }
438             putBuiltinConstraints( tmpConstraints, DecimalMax.class, decimalMaxValidators );
439         }
440         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MIN ) ) {
441             List<Class<? extends ConstraintValidator<DecimalMin, ?>>> decimalMinValidators = new ArrayList<>();
442             decimalMinValidators.add( DecimalMinValidatorForBigDecimal.class );
443             decimalMinValidators.add( DecimalMinValidatorForBigInteger.class );
444             decimalMinValidators.add( DecimalMinValidatorForByte.class );
445             decimalMinValidators.add( DecimalMinValidatorForDouble.class );
446             decimalMinValidators.add( DecimalMinValidatorForFloat.class );
447             decimalMinValidators.add( DecimalMinValidatorForLong.class );
448             decimalMinValidators.add( DecimalMinValidatorForInteger.class );
449             decimalMinValidators.add( DecimalMinValidatorForNumber.class );
450             decimalMinValidators.add( DecimalMinValidatorForShort.class );
451             decimalMinValidators.add( DecimalMinValidatorForCharSequence.class );
452             if ( isJavaMoneyInClasspath() ) {
453                 decimalMinValidators.add( DecimalMinValidatorForMonetaryAmount.class );
454             }
455             putBuiltinConstraints( tmpConstraints, DecimalMin.class, decimalMinValidators );
456         }
457         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_DIGITS ) ) {
458             List<Class<? extends ConstraintValidator<Digits, ?>>> digitsValidators = new ArrayList<>();
459             digitsValidators.add( DigitsValidatorForCharSequence.class );
460             digitsValidators.add( DigitsValidatorForNumber.class );
461             if ( isJavaMoneyInClasspath() ) {
462                 digitsValidators.add( DigitsValidatorForMonetaryAmount.class );
463             }
464             putBuiltinConstraints( tmpConstraints, Digits.class, digitsValidators );
465         }
466
467         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_EMAIL ) ) {
468             putBuiltinConstraint( tmpConstraints, Email.class, EmailValidator.class );
469         }
470
471         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_FUTURE ) ) {
472             List<Class<? extends ConstraintValidator<Future, ?>>> futureValidators = new ArrayList<>( 18 );
473             futureValidators.add( FutureValidatorForCalendar.class );
474             futureValidators.add( FutureValidatorForDate.class );
475             if ( isJodaTimeInClasspath() ) {
476                 futureValidators.add( FutureValidatorForReadableInstant.class );
477                 futureValidators.add( FutureValidatorForReadablePartial.class );
478             }
479             // Java 8 date/time API validators
480             futureValidators.add( FutureValidatorForHijrahDate.class );
481             futureValidators.add( FutureValidatorForInstant.class );
482             futureValidators.add( FutureValidatorForJapaneseDate.class );
483             futureValidators.add( FutureValidatorForLocalDate.class );
484             futureValidators.add( FutureValidatorForLocalDateTime.class );
485             futureValidators.add( FutureValidatorForLocalTime.class );
486             futureValidators.add( FutureValidatorForMinguoDate.class );
487             futureValidators.add( FutureValidatorForMonthDay.class );
488             futureValidators.add( FutureValidatorForOffsetDateTime.class );
489             futureValidators.add( FutureValidatorForOffsetTime.class );
490             futureValidators.add( FutureValidatorForThaiBuddhistDate.class );
491             futureValidators.add( FutureValidatorForYear.class );
492             futureValidators.add( FutureValidatorForYearMonth.class );
493             futureValidators.add( FutureValidatorForZonedDateTime.class );
494
495             putBuiltinConstraints( tmpConstraints, Future.class, futureValidators );
496         }
497
498         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_FUTURE_OR_PRESENT ) ) {
499             List<Class<? extends ConstraintValidator<FutureOrPresent, ?>>> futureOrPresentValidators = new ArrayList<>( 18 );
500             futureOrPresentValidators.add( FutureOrPresentValidatorForCalendar.class );
501             futureOrPresentValidators.add( FutureOrPresentValidatorForDate.class );
502             if ( isJodaTimeInClasspath() ) {
503                 futureOrPresentValidators.add( FutureOrPresentValidatorForReadableInstant.class );
504                 futureOrPresentValidators.add( FutureOrPresentValidatorForReadablePartial.class );
505             }
506             // Java 8 date/time API validators
507             futureOrPresentValidators.add( FutureOrPresentValidatorForHijrahDate.class );
508             futureOrPresentValidators.add( FutureOrPresentValidatorForInstant.class );
509             futureOrPresentValidators.add( FutureOrPresentValidatorForJapaneseDate.class );
510             futureOrPresentValidators.add( FutureOrPresentValidatorForLocalDate.class );
511             futureOrPresentValidators.add( FutureOrPresentValidatorForLocalDateTime.class );
512             futureOrPresentValidators.add( FutureOrPresentValidatorForLocalTime.class );
513             futureOrPresentValidators.add( FutureOrPresentValidatorForMinguoDate.class );
514             futureOrPresentValidators.add( FutureOrPresentValidatorForMonthDay.class );
515             futureOrPresentValidators.add( FutureOrPresentValidatorForOffsetDateTime.class );
516             futureOrPresentValidators.add( FutureOrPresentValidatorForOffsetTime.class );
517             futureOrPresentValidators.add( FutureOrPresentValidatorForThaiBuddhistDate.class );
518             futureOrPresentValidators.add( FutureOrPresentValidatorForYear.class );
519             futureOrPresentValidators.add( FutureOrPresentValidatorForYearMonth.class );
520             futureOrPresentValidators.add( FutureOrPresentValidatorForZonedDateTime.class );
521
522             putBuiltinConstraints( tmpConstraints, FutureOrPresent.class, futureOrPresentValidators );
523         }
524
525         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_MAX ) ) {
526             List<Class<? extends ConstraintValidator<Max, ?>>> maxValidators = new ArrayList<>();
527             maxValidators.add( MaxValidatorForBigDecimal.class );
528             maxValidators.add( MaxValidatorForBigInteger.class );
529             maxValidators.add( MaxValidatorForByte.class );
530             maxValidators.add( MaxValidatorForDouble.class );
531             maxValidators.add( MaxValidatorForFloat.class );
532             maxValidators.add( MaxValidatorForInteger.class );
533             maxValidators.add( MaxValidatorForLong.class );
534             maxValidators.add( MaxValidatorForNumber.class );
535             maxValidators.add( MaxValidatorForShort.class );
536             maxValidators.add( MaxValidatorForCharSequence.class );
537             if ( isJavaMoneyInClasspath() ) {
538                 maxValidators.add( MaxValidatorForMonetaryAmount.class );
539             }
540             putBuiltinConstraints( tmpConstraints, Max.class, maxValidators );
541         }
542         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_MIN ) ) {
543             List<Class<? extends ConstraintValidator<Min, ?>>> minValidators = new ArrayList<>();
544             minValidators.add( MinValidatorForBigDecimal.class );
545             minValidators.add( MinValidatorForBigInteger.class );
546             minValidators.add( MinValidatorForByte.class );
547             minValidators.add( MinValidatorForDouble.class );
548             minValidators.add( MinValidatorForFloat.class );
549             minValidators.add( MinValidatorForInteger.class );
550             minValidators.add( MinValidatorForLong.class );
551             minValidators.add( MinValidatorForNumber.class );
552             minValidators.add( MinValidatorForShort.class );
553             minValidators.add( MinValidatorForCharSequence.class );
554             if ( isJavaMoneyInClasspath() ) {
555                 minValidators.add( MinValidatorForMonetaryAmount.class );
556             }
557             putBuiltinConstraints( tmpConstraints, Min.class, minValidators );
558         }
559
560         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE ) ) {
561             List<Class<? extends ConstraintValidator<Negative, ?>>> negativeValidators = new ArrayList<>();
562             negativeValidators.add( NegativeValidatorForBigDecimal.class );
563             negativeValidators.add( NegativeValidatorForBigInteger.class );
564             negativeValidators.add( NegativeValidatorForDouble.class );
565             negativeValidators.add( NegativeValidatorForFloat.class );
566             negativeValidators.add( NegativeValidatorForLong.class );
567             negativeValidators.add( NegativeValidatorForInteger.class );
568             negativeValidators.add( NegativeValidatorForShort.class );
569             negativeValidators.add( NegativeValidatorForByte.class );
570             negativeValidators.add( NegativeValidatorForNumber.class );
571             negativeValidators.add( NegativeValidatorForCharSequence.class );
572             if ( isJavaMoneyInClasspath() ) {
573                 negativeValidators.add( NegativeValidatorForMonetaryAmount.class );
574             }
575             putBuiltinConstraints( tmpConstraints, Negative.class, negativeValidators );
576         }
577
578         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE_OR_ZERO ) ) {
579             List<Class<? extends ConstraintValidator<NegativeOrZero, ?>>> negativeOrZeroValidators = new ArrayList<>();
580             negativeOrZeroValidators.add( NegativeOrZeroValidatorForBigDecimal.class );
581             negativeOrZeroValidators.add( NegativeOrZeroValidatorForBigInteger.class );
582             negativeOrZeroValidators.add( NegativeOrZeroValidatorForDouble.class );
583             negativeOrZeroValidators.add( NegativeOrZeroValidatorForFloat.class );
584             negativeOrZeroValidators.add( NegativeOrZeroValidatorForLong.class );
585             negativeOrZeroValidators.add( NegativeOrZeroValidatorForInteger.class );
586             negativeOrZeroValidators.add( NegativeOrZeroValidatorForShort.class );
587             negativeOrZeroValidators.add( NegativeOrZeroValidatorForByte.class );
588             negativeOrZeroValidators.add( NegativeOrZeroValidatorForNumber.class );
589             negativeOrZeroValidators.add( NegativeOrZeroValidatorForCharSequence.class );
590             if ( isJavaMoneyInClasspath() ) {
591                 negativeOrZeroValidators.add( NegativeOrZeroValidatorForMonetaryAmount.class );
592             }
593             putBuiltinConstraints( tmpConstraints, NegativeOrZero.class, negativeOrZeroValidators );
594         }
595
596         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NOT_BLANK ) ) {
597             putBuiltinConstraint( tmpConstraints, NotBlank.class, NotBlankValidator.class );
598         }
599
600         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NOT_EMPTY ) ) {
601             List<Class<? extends ConstraintValidator<NotEmpty, ?>>> notEmptyValidators = new ArrayList<>( 11 );
602             notEmptyValidators.add( NotEmptyValidatorForCharSequence.class );
603             notEmptyValidators.add( NotEmptyValidatorForCollection.class );
604             notEmptyValidators.add( NotEmptyValidatorForArray.class );
605             notEmptyValidators.add( NotEmptyValidatorForMap.class );
606             notEmptyValidators.add( NotEmptyValidatorForArraysOfBoolean.class );
607             notEmptyValidators.add( NotEmptyValidatorForArraysOfByte.class );
608             notEmptyValidators.add( NotEmptyValidatorForArraysOfChar.class );
609             notEmptyValidators.add( NotEmptyValidatorForArraysOfDouble.class );
610             notEmptyValidators.add( NotEmptyValidatorForArraysOfFloat.class );
611             notEmptyValidators.add( NotEmptyValidatorForArraysOfInt.class );
612             notEmptyValidators.add( NotEmptyValidatorForArraysOfLong.class );
613             notEmptyValidators.add( NotEmptyValidatorForArraysOfShort.class );
614             putBuiltinConstraints( tmpConstraints, NotEmpty.class, notEmptyValidators );
615         }
616
617         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL ) ) {
618             putBuiltinConstraint( tmpConstraints, NotNull.class, NotNullValidator.class );
619         }
620         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NULL ) ) {
621             putBuiltinConstraint( tmpConstraints, Null.class, NullValidator.class );
622         }
623
624         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_PAST ) ) {
625             List<Class<? extends ConstraintValidator<Past, ?>>> pastValidators = new ArrayList<>( 18 );
626             pastValidators.add( PastValidatorForCalendar.class );
627             pastValidators.add( PastValidatorForDate.class );
628             if ( isJodaTimeInClasspath() ) {
629                 pastValidators.add( PastValidatorForReadableInstant.class );
630                 pastValidators.add( PastValidatorForReadablePartial.class );
631             }
632             // Java 8 date/time API validators
633             pastValidators.add( PastValidatorForHijrahDate.class );
634             pastValidators.add( PastValidatorForInstant.class );
635             pastValidators.add( PastValidatorForJapaneseDate.class );
636             pastValidators.add( PastValidatorForLocalDate.class );
637             pastValidators.add( PastValidatorForLocalDateTime.class );
638             pastValidators.add( PastValidatorForLocalTime.class );
639             pastValidators.add( PastValidatorForMinguoDate.class );
640             pastValidators.add( PastValidatorForMonthDay.class );
641             pastValidators.add( PastValidatorForOffsetDateTime.class );
642             pastValidators.add( PastValidatorForOffsetTime.class );
643             pastValidators.add( PastValidatorForThaiBuddhistDate.class );
644             pastValidators.add( PastValidatorForYear.class );
645             pastValidators.add( PastValidatorForYearMonth.class );
646             pastValidators.add( PastValidatorForZonedDateTime.class );
647
648             putBuiltinConstraints( tmpConstraints, Past.class, pastValidators );
649         }
650
651         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_PAST_OR_PRESENT ) ) {
652             List<Class<? extends ConstraintValidator<PastOrPresent, ?>>> pastOrPresentValidators = new ArrayList<>( 18 );
653             pastOrPresentValidators.add( PastOrPresentValidatorForCalendar.class );
654             pastOrPresentValidators.add( PastOrPresentValidatorForDate.class );
655             if ( isJodaTimeInClasspath() ) {
656                 pastOrPresentValidators.add( PastOrPresentValidatorForReadableInstant.class );
657                 pastOrPresentValidators.add( PastOrPresentValidatorForReadablePartial.class );
658             }
659             // Java 8 date/time API validators
660             pastOrPresentValidators.add( PastOrPresentValidatorForHijrahDate.class );
661             pastOrPresentValidators.add( PastOrPresentValidatorForInstant.class );
662             pastOrPresentValidators.add( PastOrPresentValidatorForJapaneseDate.class );
663             pastOrPresentValidators.add( PastOrPresentValidatorForLocalDate.class );
664             pastOrPresentValidators.add( PastOrPresentValidatorForLocalDateTime.class );
665             pastOrPresentValidators.add( PastOrPresentValidatorForLocalTime.class );
666             pastOrPresentValidators.add( PastOrPresentValidatorForMinguoDate.class );
667             pastOrPresentValidators.add( PastOrPresentValidatorForMonthDay.class );
668             pastOrPresentValidators.add( PastOrPresentValidatorForOffsetDateTime.class );
669             pastOrPresentValidators.add( PastOrPresentValidatorForOffsetTime.class );
670             pastOrPresentValidators.add( PastOrPresentValidatorForThaiBuddhistDate.class );
671             pastOrPresentValidators.add( PastOrPresentValidatorForYear.class );
672             pastOrPresentValidators.add( PastOrPresentValidatorForYearMonth.class );
673             pastOrPresentValidators.add( PastOrPresentValidatorForZonedDateTime.class );
674
675             putBuiltinConstraints( tmpConstraints, PastOrPresent.class, pastOrPresentValidators );
676         }
677
678         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_PATTERN ) ) {
679             putBuiltinConstraint( tmpConstraints, Pattern.class, PatternValidator.class );
680         }
681
682         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_POSITIVE ) ) {
683             List<Class<? extends ConstraintValidator<Positive, ?>>> positiveValidators = new ArrayList<>();
684             positiveValidators.add( PositiveValidatorForBigDecimal.class );
685             positiveValidators.add( PositiveValidatorForBigInteger.class );
686             positiveValidators.add( PositiveValidatorForDouble.class );
687             positiveValidators.add( PositiveValidatorForFloat.class );
688             positiveValidators.add( PositiveValidatorForLong.class );
689             positiveValidators.add( PositiveValidatorForInteger.class );
690             positiveValidators.add( PositiveValidatorForShort.class );
691             positiveValidators.add( PositiveValidatorForByte.class );
692             positiveValidators.add( PositiveValidatorForNumber.class );
693             positiveValidators.add( PositiveValidatorForCharSequence.class );
694             if ( isJavaMoneyInClasspath() ) {
695                 positiveValidators.add( PositiveValidatorForMonetaryAmount.class );
696             }
697             putBuiltinConstraints( tmpConstraints, Positive.class, positiveValidators );
698         }
699
700         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_POSITIVE_OR_ZERO ) ) {
701             List<Class<? extends ConstraintValidator<PositiveOrZero, ?>>> positiveOrZeroValidators = new ArrayList<>();
702             positiveOrZeroValidators.add( PositiveOrZeroValidatorForBigDecimal.class );
703             positiveOrZeroValidators.add( PositiveOrZeroValidatorForBigInteger.class );
704             positiveOrZeroValidators.add( PositiveOrZeroValidatorForDouble.class );
705             positiveOrZeroValidators.add( PositiveOrZeroValidatorForFloat.class );
706             positiveOrZeroValidators.add( PositiveOrZeroValidatorForLong.class );
707             positiveOrZeroValidators.add( PositiveOrZeroValidatorForInteger.class );
708             positiveOrZeroValidators.add( PositiveOrZeroValidatorForShort.class );
709             positiveOrZeroValidators.add( PositiveOrZeroValidatorForByte.class );
710             positiveOrZeroValidators.add( PositiveOrZeroValidatorForNumber.class );
711             positiveOrZeroValidators.add( PositiveOrZeroValidatorForCharSequence.class );
712             if ( isJavaMoneyInClasspath() ) {
713                 positiveOrZeroValidators.add( PositiveOrZeroValidatorForMonetaryAmount.class );
714             }
715             putBuiltinConstraints( tmpConstraints, PositiveOrZero.class, positiveOrZeroValidators );
716         }
717
718         if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_SIZE ) ) {
719             List<Class<? extends ConstraintValidator<Size, ?>>> sizeValidators = new ArrayList<>( 11 );
720             sizeValidators.add( SizeValidatorForCharSequence.class );
721             sizeValidators.add( SizeValidatorForCollection.class );
722             sizeValidators.add( SizeValidatorForArray.class );
723             sizeValidators.add( SizeValidatorForMap.class );
724             sizeValidators.add( SizeValidatorForArraysOfBoolean.class );
725             sizeValidators.add( SizeValidatorForArraysOfByte.class );
726             sizeValidators.add( SizeValidatorForArraysOfChar.class );
727             sizeValidators.add( SizeValidatorForArraysOfDouble.class );
728             sizeValidators.add( SizeValidatorForArraysOfFloat.class );
729             sizeValidators.add( SizeValidatorForArraysOfInt.class );
730             sizeValidators.add( SizeValidatorForArraysOfLong.class );
731             sizeValidators.add( SizeValidatorForArraysOfShort.class );
732             putBuiltinConstraints( tmpConstraints, Size.class, sizeValidators );
733         }
734
735         // Hibernate Validator specific constraints
736
737         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CNPJ ) ) {
738             putBuiltinConstraint( tmpConstraints, CNPJ.class, CNPJValidator.class );
739         }
740         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CPF ) ) {
741             putBuiltinConstraint( tmpConstraints, CPF.class, CPFValidator.class );
742         }
743         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CURRENCY ) && isJavaMoneyInClasspath() ) {
744             putBuiltinConstraint( tmpConstraints, Currency.class, CurrencyValidatorForMonetaryAmount.class );
745         }
746         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CREDIT_CARD_NUMBER ) ) {
747             putBuiltinConstraint( tmpConstraints, CreditCardNumber.class );
748         }
749         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MAX ) ) {
750             putBuiltinConstraint( tmpConstraints, DurationMax.class, DurationMaxValidator.class );
751         }
752         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MIN ) ) {
753             putBuiltinConstraint( tmpConstraints, DurationMin.class, DurationMinValidator.class );
754         }
755         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EAN ) ) {
756             putBuiltinConstraint( tmpConstraints, EAN.class, EANValidator.class );
757         }
758         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EMAIL ) ) {
759             putBuiltinConstraint( tmpConstraints, org.hibernate.validator.constraints.Email.class, org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator.class );
760         }
761         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_ISBN ) ) {
762             putBuiltinConstraint( tmpConstraints, ISBN.class, ISBNValidator.class );
763         }
764         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LENGTH ) ) {
765             putBuiltinConstraint( tmpConstraints, Length.class, LengthValidator.class );
766         }
767         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CODE_POINT_LENGTH ) ) {
768             putBuiltinConstraint( tmpConstraints, CodePointLength.class, CodePointLengthValidator.class );
769         }
770         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LUHN_CHECK ) ) {
771             putBuiltinConstraint( tmpConstraints, LuhnCheck.class, LuhnCheckValidator.class );
772         }
773         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD_CHECK ) ) {
774             putBuiltinConstraint( tmpConstraints, ModCheck.class, ModCheckValidator.class );
775         }
776         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK ) ) {
777             putBuiltinConstraint( tmpConstraints, Mod10Check.class, Mod10CheckValidator.class );
778         }
779         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK ) ) {
780             putBuiltinConstraint( tmpConstraints, Mod11Check.class, Mod11CheckValidator.class );
781         }
782         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NORMALIZED ) ) {
783             putBuiltinConstraint( tmpConstraints, Normalized.class, NormalizedValidator.class );
784         }
785         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_NIP ) ) {
786             putBuiltinConstraint( tmpConstraints, NIP.class, NIPValidator.class );
787         }
788         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_BLANK ) ) {
789             putBuiltinConstraint( tmpConstraints, org.hibernate.validator.constraints.NotBlank.class, org.hibernate.validator.internal.constraintvalidators.hv.NotBlankValidator.class );
790         }
791         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_EMPTY ) ) {
792             putBuiltinConstraint( tmpConstraints, org.hibernate.validator.constraints.NotEmpty.class );
793         }
794         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PARAMETER_SCRIPT_ASSERT ) ) {
795             putBuiltinConstraint( tmpConstraints, ParameterScriptAssert.class, ParameterScriptAssertValidator.class );
796         }
797         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_PESEL ) ) {
798             putBuiltinConstraint( tmpConstraints, PESEL.class, PESELValidator.class );
799         }
800         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_RANGE ) ) {
801             putBuiltinConstraint( tmpConstraints, Range.class );
802         }
803         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_REGON ) ) {
804             putBuiltinConstraint( tmpConstraints, REGON.class, REGONValidator.class );
805         }
806         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SAFE_HTML ) && isJsoupInClasspath() ) {
807             putBuiltinConstraint( tmpConstraints, SafeHtml.class, SafeHtmlValidator.class );
808         }
809         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SCRIPT_ASSERT ) ) {
810             putBuiltinConstraint( tmpConstraints, ScriptAssert.class, ScriptAssertValidator.class );
811         }
812         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_TITULO_ELEITORAL ) ) {
813             putBuiltinConstraint( tmpConstraints, TituloEleitoral.class );
814         }
815         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_UNIQUE_ELEMENTS ) ) {
816             putBuiltinConstraint( tmpConstraints, UniqueElements.class, UniqueElementsValidator.class );
817         }
818         if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_URL ) ) {
819             putBuiltinConstraint( tmpConstraints, URL.class, URLValidator.class );
820         }
821
822         this.enabledBuiltinConstraints = Collections.unmodifiableMap( tmpConstraints );
823     }
824
825     private static <A extends Annotation> void putBuiltinConstraint(Map<Class<? extends Annotation>, List<ConstraintValidatorDescriptor<?>>> validators,
826             Class<A> constraintType) {
827         validators.put( constraintType, Collections.emptyList() );
828     }
829
830     private static <A extends Annotation> void putBuiltinConstraint(Map<Class<? extends Annotation>, List<ConstraintValidatorDescriptor<?>>> validators,
831             Class<A> constraintType, Class<? extends ConstraintValidator<A, ?>> validatorType) {
832         validators.put( constraintType, Collections.singletonList( ConstraintValidatorDescriptor.forBuiltinClass( validatorType, constraintType ) ) );
833     }
834
835     private static <A extends Annotation> void putBuiltinConstraints(Map<Class<? extends Annotation>, List<ConstraintValidatorDescriptor<?>>> validators,
836             Class<A> constraintType, List<Class<? extends ConstraintValidator<A, ?>>> validatorTypes) {
837         List<ConstraintValidatorDescriptor<?>> descriptors = new ArrayList<>( validatorTypes.size() );
838
839         for ( Class<? extends ConstraintValidator<A, ?>> validatorType : validatorTypes ) {
840             descriptors.add( ConstraintValidatorDescriptor.forBuiltinClass( validatorType, constraintType ) );
841         }
842
843         validators.put( constraintType, CollectionHelper.toImmutableList( descriptors ) );
844     }
845
846     private boolean isBuiltinConstraint(Class<? extends Annotation> annotationType) {
847         return BuiltinConstraint.isBuiltin( annotationType.getName() );
848     }
849
850     public static Set<String> getBuiltinConstraints() {
851         return BuiltinConstraint.set();
852     }
853
854     /**
855      * Returns the constraint validator classes for the given constraint
856      * annotation type, as retrieved from
857      *
858      * <ul>
859      * <li>{@link Constraint#validatedBy()},
860      * <li>internally registered validators for built-in constraints</li>
861      * <li>XML configuration and</li>
862      * <li>programmatically registered validators (see
863      * {@link org.hibernate.validator.cfg.ConstraintMapping#constraintDefinition(Class)}).</li>
864      * </ul>
865      *
866      * The result is cached internally.
867      *
868      * @param annotationType The constraint annotation type.
869      * @param <A> the type of the annotation
870      *
871      * @return The validator classes for the given type.
872      */

873     public <A extends Annotation> List<ConstraintValidatorDescriptor<A>> getAllValidatorDescriptors(Class<A> annotationType) {
874         Contracts.assertNotNull( annotationType, MESSAGES.classCannotBeNull() );
875         return validatorDescriptors.computeIfAbsent( annotationType, a -> getDefaultValidatorDescriptors( a ) );
876     }
877
878     /**
879      * Returns those validator descriptors for the given constraint annotation
880      * matching the given target.
881      *
882      * @param annotationType The annotation of interest.
883      * @param validationTarget The target, either annotated element or parameters.
884      * @param <A> the type of the annotation
885      *
886      * @return A list with matching validator descriptors.
887      */

888     public <A extends Annotation> List<ConstraintValidatorDescriptor<A>> findValidatorDescriptors(Class<A> annotationType, ValidationTarget validationTarget) {
889         return getAllValidatorDescriptors( annotationType ).stream()
890             .filter( d -> supportsValidationTarget( d, validationTarget ) )
891             .collect( Collectors.toList() );
892     }
893
894     private boolean supportsValidationTarget(ConstraintValidatorDescriptor<?> validatorDescriptor, ValidationTarget target) {
895         return validatorDescriptor.getValidationTargets().contains( target );
896     }
897
898     /**
899      * Registers the given validator descriptors with the given constraint
900      * annotation type.
901      *
902      * @param annotationType The constraint annotation type
903      * @param validatorDescriptors The validator descriptors to register
904      * @param keepExistingClasses Whether already-registered validators should be kept or not
905      * @param <A> the type of the annotation
906      */

907     public <A extends Annotation> void putValidatorDescriptors(Class<A> annotationType,
908                                                            List<ConstraintValidatorDescriptor<A>> validatorDescriptors,
909                                                            boolean keepExistingClasses) {
910
911         List<ConstraintValidatorDescriptor<A>> validatorDescriptorsToAdd = new ArrayList<>();
912
913         if ( keepExistingClasses ) {
914             List<ConstraintValidatorDescriptor<A>> existingvalidatorDescriptors = getAllValidatorDescriptors( annotationType );
915             if ( existingvalidatorDescriptors != null ) {
916                 validatorDescriptorsToAdd.addAll( 0, existingvalidatorDescriptors );
917             }
918         }
919
920         validatorDescriptorsToAdd.addAll( validatorDescriptors );
921
922         this.validatorDescriptors.put( annotationType, CollectionHelper.toImmutableList( validatorDescriptorsToAdd ) );
923     }
924
925     /**
926      * Checks whether a given annotation is a multi value constraint or not.
927      *
928      * @param annotationType the annotation type to check.
929      *
930      * @return {@code trueif the specified annotation is a multi value constraints, {@code false}
931      *         otherwise.
932      */

933     public boolean isMultiValueConstraint(Class<? extends Annotation> annotationType) {
934         if ( isJdkAnnotation( annotationType ) ) {
935             return false;
936         }
937
938         return multiValueConstraints.computeIfAbsent( annotationType, a -> {
939             boolean isMultiValueConstraint = false;
940             final Method method = run( GetMethod.action( a, "value" ) );
941             if ( method != null ) {
942                 Class<?> returnType = method.getReturnType();
943                 if ( returnType.isArray() && returnType.getComponentType().isAnnotation() ) {
944                     @SuppressWarnings("unchecked")
945                     Class<? extends Annotation> componentType = (Class<? extends Annotation>) returnType.getComponentType();
946                     if ( isConstraintAnnotation( componentType ) ) {
947                         isMultiValueConstraint = Boolean.TRUE;
948                     }
949                     else {
950                         isMultiValueConstraint = Boolean.FALSE;
951                     }
952                 }
953             }
954             return isMultiValueConstraint;
955         } );
956     }
957
958     /**
959      * Returns the constraints which are part of the given multi-value constraint.
960      * <p>
961      * Invoke {@link #isMultiValueConstraint(Class)} prior to calling this method to check whether a given constraint
962      * actually is a multi-value constraint.
963      *
964      * @param multiValueConstraint the multi-value constraint annotation from which to retrieve the contained constraints
965      * @param <A> the type of the annotation
966      *
967      * @return A list of constraint annotations, may be empty but never {@code null}.
968      */

969     public <A extends Annotation> List<Annotation> getConstraintsFromMultiValueConstraint(A multiValueConstraint) {
970         Annotation[] annotations = run(
971                 GetAnnotationAttribute.action(
972                         multiValueConstraint,
973                         "value",
974                         Annotation[].class
975                 )
976         );
977         return Arrays.asList( annotations );
978     }
979
980     /**
981      * Checks whether the specified annotation is a valid constraint annotation. A constraint annotation has to
982      * fulfill the following conditions:
983      * <ul>
984      * <li>Must be annotated with {@link Constraint}
985      * <li>Define a message parameter</li>
986      * <li>Define a group parameter</li>
987      * <li>Define a payload parameter</li>
988      * </ul>
989      *
990      * @param annotationType The annotation type to test.
991      *
992      * @return {@code trueif the annotation fulfills the above conditions, {@code false} otherwise.
993      */

994     public boolean isConstraintAnnotation(Class<? extends Annotation> annotationType) {
995         // Note: we don't use isJdkAnnotation() here as it does more harm than good.
996
997         if ( isBuiltinConstraint( annotationType ) ) {
998             return true;
999         }
1000
1001         if ( annotationType.getAnnotation( Constraint.class ) == null ) {
1002             return false;
1003         }
1004
1005         return externalConstraints.computeIfAbsent( annotationType, a -> {
1006             assertMessageParameterExists( a );
1007             assertGroupsParameterExists( a );
1008             assertPayloadParameterExists( a );
1009             assertValidationAppliesToParameterSetUpCorrectly( a );
1010             assertNoParameterStartsWithValid( a );
1011
1012             return Boolean.TRUE;
1013         } );
1014     }
1015
1016     private void assertNoParameterStartsWithValid(Class<? extends Annotation> annotationType) {
1017         final Method[] methods = run( GetDeclaredMethods.action( annotationType ) );
1018         for ( Method m : methods ) {
1019             if ( m.getName().startsWith( "valid" ) && !SUPPORTED_VALID_METHODS.contains( m.getName() ) ) {
1020                 throw LOG.getConstraintParametersCannotStartWithValidException();
1021             }
1022         }
1023     }
1024
1025     private void assertPayloadParameterExists(Class<? extends Annotation> annotationType) {
1026         try {
1027             final Method method = run( GetMethod.action( annotationType, PAYLOAD ) );
1028             if ( method == null ) {
1029                 throw LOG.getConstraintWithoutMandatoryParameterException( PAYLOAD, annotationType.getName() );
1030             }
1031             Class<?>[] defaultPayload = (Class<?>[]) method.getDefaultValue();
1032             if ( defaultPayload == null || defaultPayload.length != 0 ) {
1033                 throw LOG.getWrongDefaultValueForPayloadParameterException( annotationType.getName() );
1034             }
1035         }
1036         catch (ClassCastException e) {
1037             throw LOG.getWrongTypeForPayloadParameterException( annotationType.getName(), e );
1038         }
1039     }
1040
1041     private void assertGroupsParameterExists(Class<? extends Annotation> annotationType) {
1042         try {
1043             final Method method = run( GetMethod.action( annotationType, GROUPS ) );
1044             if ( method == null ) {
1045                 throw LOG.getConstraintWithoutMandatoryParameterException( GROUPS, annotationType.getName() );
1046             }
1047             Class<?>[] defaultGroups = (Class<?>[]) method.getDefaultValue();
1048             if ( defaultGroups == null || defaultGroups.length != 0 ) {
1049                 throw LOG.getWrongDefaultValueForGroupsParameterException( annotationType.getName() );
1050             }
1051         }
1052         catch (ClassCastException e) {
1053             throw LOG.getWrongTypeForGroupsParameterException( annotationType.getName(), e );
1054         }
1055     }
1056
1057     private void assertMessageParameterExists(Class<? extends Annotation> annotationType) {
1058         final Method method = run( GetMethod.action( annotationType, MESSAGE ) );
1059         if ( method == null ) {
1060             throw LOG.getConstraintWithoutMandatoryParameterException( MESSAGE, annotationType.getName() );
1061         }
1062         if ( method.getReturnType() != String.class ) {
1063             throw LOG.getWrongTypeForMessageParameterException( annotationType.getName() );
1064         }
1065     }
1066
1067     private void assertValidationAppliesToParameterSetUpCorrectly(Class<? extends Annotation> annotationType) {
1068         boolean hasGenericValidators = !findValidatorDescriptors(
1069                 annotationType,
1070                 ValidationTarget.ANNOTATED_ELEMENT
1071         ).isEmpty();
1072         boolean hasCrossParameterValidator = !findValidatorDescriptors(
1073                 annotationType,
1074                 ValidationTarget.PARAMETERS
1075         ).isEmpty();
1076         final Method method = run( GetMethod.action( annotationType, VALIDATION_APPLIES_TO ) );
1077
1078         if ( hasGenericValidators && hasCrossParameterValidator ) {
1079             if ( method == null ) {
1080                 throw LOG.getGenericAndCrossParameterConstraintDoesNotDefineValidationAppliesToParameterException(
1081                         annotationType
1082                 );
1083             }
1084             if ( method.getReturnType() != ConstraintTarget.class ) {
1085                 throw LOG.getValidationAppliesToParameterMustHaveReturnTypeConstraintTargetException( annotationType );
1086             }
1087             ConstraintTarget defaultValue = (ConstraintTarget) method.getDefaultValue();
1088             if ( defaultValue != ConstraintTarget.IMPLICIT ) {
1089                 throw LOG.getValidationAppliesToParameterMustHaveDefaultValueImplicitException( annotationType );
1090             }
1091         }
1092         else if ( method != null ) {
1093             throw LOG.getValidationAppliesToParameterMustNotBeDefinedForNonGenericAndCrossParameterConstraintException(
1094                     annotationType
1095             );
1096         }
1097     }
1098
1099     public boolean isConstraintComposition(Class<? extends Annotation> annotationType) {
1100         return annotationType == ConstraintComposition.class;
1101     }
1102
1103     public boolean isJdkAnnotation(Class<? extends Annotation> annotation) {
1104         Package pakkage = annotation.getPackage();
1105         return pakkage != null && pakkage.getName() != null &&
1106                 ( pakkage.getName().startsWith( "java." ) || pakkage.getName().startsWith( "jdk.internal" ) );
1107     }
1108
1109     public void clear() {
1110         externalConstraints.clear();
1111         multiValueConstraints.clear();
1112     }
1113
1114     private boolean isJodaTimeInClasspath() {
1115         if ( jodaTimeInClassPath == null ) {
1116             jodaTimeInClassPath = isClassPresent( JODA_TIME_CLASS_NAME );
1117         }
1118         return jodaTimeInClassPath.booleanValue();
1119     }
1120
1121     private boolean isJavaMoneyInClasspath() {
1122         if ( javaMoneyInClasspath == null ) {
1123             javaMoneyInClasspath = isClassPresent( JAVA_MONEY_CLASS_NAME );
1124         }
1125         return javaMoneyInClasspath.booleanValue();
1126     }
1127
1128     private boolean isJsoupInClasspath() {
1129         if ( jsoupInClasspath == null ) {
1130             jsoupInClasspath = isClassPresent( JSOUP_CLASS_NAME );
1131         }
1132         return jsoupInClasspath.booleanValue();
1133     }
1134
1135     /**
1136      * Returns the default validators for the given constraint type.
1137      *
1138      * @param annotationType The constraint annotation type.
1139      *
1140      * @return A list with the default validators as retrieved from
1141      *         {@link Constraint#validatedBy()} or the list of validators for
1142      *         built-in constraints.
1143      */

1144     @SuppressWarnings("unchecked")
1145     private <A extends Annotation> List<ConstraintValidatorDescriptor<A>> getDefaultValidatorDescriptors(Class<A> annotationType) {
1146         //safe cause all CV for a given annotation A are CV<A, ?>
1147         final List<ConstraintValidatorDescriptor<A>> builtInValidators = (List<ConstraintValidatorDescriptor<A>>) enabledBuiltinConstraints
1148                 .get( annotationType );
1149
1150         if ( builtInValidators != null ) {
1151             return builtInValidators;
1152         }
1153
1154         Class<? extends ConstraintValidator<A, ?>>[] validatedBy = (Class<? extends ConstraintValidator<A, ?>>[]) annotationType
1155                 .getAnnotation( Constraint.class )
1156                 .validatedBy();
1157
1158         return Stream.of( validatedBy )
1159                 .map( c -> ConstraintValidatorDescriptor.forClass( c, annotationType ) )
1160                 .collect( Collectors.collectingAndThen( Collectors.toList(), CollectionHelper::toImmutableList ) );
1161     }
1162
1163     private static boolean isClassPresent(String className) {
1164         return run( IsClassPresent.action( className, ConstraintHelper.class.getClassLoader() ) ).booleanValue();
1165     }
1166
1167     /**
1168      * Runs the given privileged action, using a privileged block if required.
1169      * <p>
1170      * <b>NOTE:</b> This must never be changed into a publicly available method to avoid execution of arbitrary
1171      * privileged actions within HV's protection domain.
1172      */

1173     private static <T> T run(PrivilegedAction<T> action) {
1174         return System.getSecurityManager() != null ? AccessController.doPrivileged( action ) : action.run();
1175     }
1176
1177     /**
1178      * A type-safe wrapper around a concurrent map from constraint types to
1179      * associated validator classes. The casts are safe as data is added trough
1180      * the typed API only.
1181      *
1182      * @author Gunnar Morling
1183      */

1184     @SuppressWarnings("unchecked")
1185     private static class ValidatorDescriptorMap {
1186
1187         private final ConcurrentMap<Class<? extends Annotation>, List<? extends ConstraintValidatorDescriptor<?>>> constraintValidatorDescriptors = new ConcurrentHashMap<>();
1188
1189         private <A extends Annotation> void put(Class<A> annotationType, List<ConstraintValidatorDescriptor<A>> validatorDescriptors) {
1190             constraintValidatorDescriptors.put( annotationType, validatorDescriptors );
1191         }
1192
1193         private <A extends Annotation> List<ConstraintValidatorDescriptor<A>> computeIfAbsent(Class<A> annotationType,
1194                 Function<? super Class<A>, List<ConstraintValidatorDescriptor<A>>> mappingFunction) {
1195             return (List<ConstraintValidatorDescriptor<A>>) constraintValidatorDescriptors.computeIfAbsent(
1196                     annotationType,
1197                     (Function<? super Class<? extends Annotation>, ? extends List<? extends ConstraintValidatorDescriptor<?>>>) mappingFunction
1198             );
1199         }
1200     }
1201 }
1202