From 94364343b598bc37e2bd5d18a486970c86668146 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 15 Apr 2020 20:03:21 +0200 Subject: [PATCH] HV-1767 Reduce the overhead of ConstraintHelper initialization in the predefined scope case --- ...dScopeHibernateValidatorConfiguration.java | 3 + .../PredefinedScopeConfigurationImpl.java | 13 + .../PredefinedScopeValidatorFactoryImpl.java | 2 +- .../internal/engine/ValidatorFactoryImpl.java | 2 +- .../metadata/core/BuiltinConstraint.java | 139 +++ .../metadata/core/ConstraintHelper.java | 853 ++++++++++-------- .../PredefinedScopeAllConstraintsTest.java | 457 ++++++++++ ...ssionLanguageMessageInterpolationTest.java | 4 +- ...ResourceBundleMessageInterpolatorTest.java | 8 +- .../metadata/core/ConstraintHelperTest.java | 2 +- .../metadata/core/MetaConstraintTest.java | 2 +- .../PredefinedScopeValidatorFactoryTest.java | 6 + ...nstraintValidatorInitializationHelper.java | 4 +- 13 files changed, 1092 insertions(+), 403 deletions(-) create mode 100644 engine/src/main/java/org/hibernate/validator/internal/metadata/core/BuiltinConstraint.java create mode 100644 engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/PredefinedScopeAllConstraintsTest.java diff --git a/engine/src/main/java/org/hibernate/validator/PredefinedScopeHibernateValidatorConfiguration.java b/engine/src/main/java/org/hibernate/validator/PredefinedScopeHibernateValidatorConfiguration.java index 1f4a85118d..a295e88430 100644 --- a/engine/src/main/java/org/hibernate/validator/PredefinedScopeHibernateValidatorConfiguration.java +++ b/engine/src/main/java/org/hibernate/validator/PredefinedScopeHibernateValidatorConfiguration.java @@ -20,6 +20,9 @@ @Incubating public interface PredefinedScopeHibernateValidatorConfiguration extends BaseHibernateValidatorConfiguration { + @Incubating + PredefinedScopeHibernateValidatorConfiguration builtinConstraints(Set constraints); + @Incubating PredefinedScopeHibernateValidatorConfiguration initializeBeanMetaData(Set> beanClassesToInitialize); diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeConfigurationImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeConfigurationImpl.java index 3b8aadca30..15b239e627 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeConfigurationImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeConfigurationImpl.java @@ -8,6 +8,7 @@ import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES; +import java.util.Collections; import java.util.Locale; import java.util.Set; @@ -25,6 +26,8 @@ public class PredefinedScopeConfigurationImpl extends AbstractConfigurationImpl implements PredefinedScopeHibernateValidatorConfiguration, ConfigurationState { + private Set builtinConstraints = Collections.emptySet(); + private Set> beanClassesToInitialize; public PredefinedScopeConfigurationImpl(BootstrapState state) { @@ -35,12 +38,22 @@ public PredefinedScopeConfigurationImpl(ValidationProvider validationProvider super( validationProvider ); } + @Override + public PredefinedScopeHibernateValidatorConfiguration builtinConstraints(Set constraints) { + this.builtinConstraints = CollectionHelper.toImmutableSet( constraints ); + return thisAsT(); + } + @Override public PredefinedScopeHibernateValidatorConfiguration initializeBeanMetaData(Set> beanMetaDataToInitialize) { beanClassesToInitialize = CollectionHelper.toImmutableSet( beanMetaDataToInitialize ); return thisAsT(); } + public Set getBuiltinConstraints() { + return builtinConstraints; + } + public Set> getBeanClassesToInitialize() { return beanClassesToInitialize; } diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java index 8785843e17..2eddf9153f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/PredefinedScopeValidatorFactoryImpl.java @@ -132,7 +132,7 @@ public PredefinedScopeValidatorFactoryImpl(ConfigurationState configurationState this.getterPropertySelectionStrategy = ValidatorFactoryConfigurationHelper.determineGetterPropertySelectionStrategy( hibernateSpecificConfig, properties, externalClassLoader ); this.valueExtractorManager = new ValueExtractorManager( configurationState.getValueExtractors() ); - ConstraintHelper constraintHelper = new ConstraintHelper(); + ConstraintHelper constraintHelper = ConstraintHelper.forBuiltinConstraints( hibernateSpecificConfig.getBuiltinConstraints() ); TypeResolutionHelper typeResolutionHelper = new TypeResolutionHelper(); ConstraintCreationContext constraintCreationContext = new ConstraintCreationContext( constraintHelper, diff --git a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java index 581b597443..918177fd46 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java +++ b/engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java @@ -167,7 +167,7 @@ public ValidatorFactoryImpl(ConfigurationState configurationState) { this.validationOrderGenerator = new ValidationOrderGenerator(); ValueExtractorManager valueExtractorManager = new ValueExtractorManager( configurationState.getValueExtractors() ); - ConstraintHelper constraintHelper = new ConstraintHelper(); + ConstraintHelper constraintHelper = ConstraintHelper.forAllBuiltinConstraints(); TypeResolutionHelper typeResolutionHelper = new TypeResolutionHelper(); this.constraintCreationContext = new ConstraintCreationContext( constraintHelper, constraintValidatorManager, typeResolutionHelper, valueExtractorManager ); diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/BuiltinConstraint.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/BuiltinConstraint.java new file mode 100644 index 0000000000..9a7197359b --- /dev/null +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/BuiltinConstraint.java @@ -0,0 +1,139 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.internal.metadata.core; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * The list of built-in constraints. + *

+ * We are not using the class directly to avoid loading the class if possible. + *

+ * In the case of composing constraints, you need to define the dependencies manually. + *

+ * When adding a new built-in constraint, please add a test in {@code MessagePropertiesTest} and + * {@code PredefinedScopeAllConstraintsTest}. + * + * @author Guillaume Smet + */ +enum BuiltinConstraint { + + // Specification constraints + JAVAX_VALIDATION_CONSTRAINTS_ASSERT_FALSE("javax.validation.constraints.AssertFalse"), + JAVAX_VALIDATION_CONSTRAINTS_ASSERT_TRUE("javax.validation.constraints.AssertTrue"), + JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MAX("javax.validation.constraints.DecimalMax"), + JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MIN("javax.validation.constraints.DecimalMin"), + JAVAX_VALIDATION_CONSTRAINTS_DIGITS("javax.validation.constraints.Digits"), + JAVAX_VALIDATION_CONSTRAINTS_EMAIL("javax.validation.constraints.Email"), + JAVAX_VALIDATION_CONSTRAINTS_FUTURE("javax.validation.constraints.Future"), + JAVAX_VALIDATION_CONSTRAINTS_FUTURE_OR_PRESENT("javax.validation.constraints.FutureOrPresent"), + JAVAX_VALIDATION_CONSTRAINTS_MIN("javax.validation.constraints.Min"), + JAVAX_VALIDATION_CONSTRAINTS_MAX("javax.validation.constraints.Max"), + JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE("javax.validation.constraints.Negative"), + JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE_OR_ZERO("javax.validation.constraints.NegativeOrZero"), + JAVAX_VALIDATION_CONSTRAINTS_NOT_BLANK("javax.validation.constraints.NotBlank"), + JAVAX_VALIDATION_CONSTRAINTS_NOT_EMPTY("javax.validation.constraints.NotEmpty"), + JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL("javax.validation.constraints.NotNull"), + JAVAX_VALIDATION_CONSTRAINTS_NULL("javax.validation.constraints.Null"), + JAVAX_VALIDATION_CONSTRAINTS_PAST("javax.validation.constraints.Past"), + JAVAX_VALIDATION_CONSTRAINTS_PAST_OR_PRESENT("javax.validation.constraints.PastOrPresent"), + JAVAX_VALIDATION_CONSTRAINTS_PATTERN("javax.validation.constraints.Pattern"), + JAVAX_VALIDATION_CONSTRAINTS_POSITIVE("javax.validation.constraints.Positive"), + JAVAX_VALIDATION_CONSTRAINTS_POSITIVE_OR_ZERO("javax.validation.constraints.PositiveOrZero"), + JAVAX_VALIDATION_CONSTRAINTS_SIZE("javax.validation.constraints.Size"), + + // Hibernate Validator specific constraints + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CODE_POINT_LENGTH("org.hibernate.validator.constraints.CodePointLength"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CURRENCY("org.hibernate.validator.constraints.Currency"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EMAIL("org.hibernate.validator.constraints.Email", Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_PATTERN ) ), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_ISBN("org.hibernate.validator.constraints.ISBN"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LENGTH("org.hibernate.validator.constraints.Length"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LUHN_CHECK("org.hibernate.validator.constraints.LuhnCheck"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CREDIT_CARD_NUMBER("org.hibernate.validator.constraints.CreditCardNumber", + Arrays.asList( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LUHN_CHECK ) ), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK("org.hibernate.validator.constraints.Mod10Check"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK("org.hibernate.validator.constraints.Mod11Check"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD_CHECK("org.hibernate.validator.constraints.ModCheck"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EAN("org.hibernate.validator.constraints.EAN", Arrays.asList( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK ) ), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_BLANK("org.hibernate.validator.constraints.NotBlank", + Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL ) ), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_EMPTY("org.hibernate.validator.constraints.NotEmpty", + Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL, JAVAX_VALIDATION_CONSTRAINTS_SIZE )), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PARAMETER_SCRIPT_ASSERT("org.hibernate.validator.constraints.ParameterScriptAssert"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_RANGE("org.hibernate.validator.constraints.Range", + Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_MIN, JAVAX_VALIDATION_CONSTRAINTS_MAX )), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SAFE_HTML("org.hibernate.validator.constraints.SafeHtml"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SCRIPT_ASSERT("org.hibernate.validator.constraints.ScriptAssert"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_URL("org.hibernate.validator.constraints.URL", + Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_PATTERN )), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_UNIQUE_ELEMENTS("org.hibernate.validator.constraints.UniqueElements"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CNPJ("org.hibernate.validator.constraints.br.CNPJ", + Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_PATTERN )), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CPF("org.hibernate.validator.constraints.br.CPF", + Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_PATTERN )), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_TITULO_ELEITORAL("org.hibernate.validator.constraints.br.TituloEleitoral", + Arrays.asList( JAVAX_VALIDATION_CONSTRAINTS_PATTERN, ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK ) ), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_NIP("org.hibernate.validator.constraints.pl.NIP"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_PESEL("org.hibernate.validator.constraints.pl.PESEL"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_REGON("org.hibernate.validator.constraints.pl.REGON"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MAX("org.hibernate.validator.constraints.time.DurationMax"), + ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MIN("org.hibernate.validator.constraints.time.DurationMin"); + + private static final Map> CONSTRAINT_MAPPING; + + static { + CONSTRAINT_MAPPING = new HashMap<>(); + for ( BuiltinConstraint constraint : values() ) { + if ( constraint.constraintDependencies.isEmpty() ) { + CONSTRAINT_MAPPING.put( constraint.annotationClassName, Collections.singleton( constraint ) ); + } + else { + Set constraints = new HashSet<>(); + constraints.add( constraint ); + constraints.addAll( constraint.constraintDependencies ); + CONSTRAINT_MAPPING.put( constraint.annotationClassName, constraints ); + } + } + } + + private String annotationClassName; + private List constraintDependencies; + + BuiltinConstraint(String constraint) { + this( constraint, Collections.emptyList() ); + } + + BuiltinConstraint(String constraint, List composingConstraints) { + this.annotationClassName = constraint; + this.constraintDependencies = composingConstraints; + } + + static Set resolve(Set constraints) { + Set resolvedConstraints = new HashSet<>(); + for ( String constraint : constraints ) { + Set builtinConstraints = CONSTRAINT_MAPPING.get( constraint ); + if ( builtinConstraints != null ) { + resolvedConstraints.addAll( builtinConstraints ); + } + } + return resolvedConstraints; + } + + static boolean isBuiltin(String constraint) { + return CONSTRAINT_MAPPING.containsKey( constraint ); + } + + static Set set() { + return CONSTRAINT_MAPPING.keySet(); + } +} diff --git a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/ConstraintHelper.java b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/ConstraintHelper.java index b38a5543b3..d912d9481f 100644 --- a/engine/src/main/java/org/hibernate/validator/internal/metadata/core/ConstraintHelper.java +++ b/engine/src/main/java/org/hibernate/validator/internal/metadata/core/ConstraintHelper.java @@ -6,6 +6,55 @@ */ package org.hibernate.validator.internal.metadata.core; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_ASSERT_FALSE; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_ASSERT_TRUE; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MAX; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MIN; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_DIGITS; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_EMAIL; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_FUTURE; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_FUTURE_OR_PRESENT; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_MAX; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_MIN; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE_OR_ZERO; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NOT_BLANK; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NOT_EMPTY; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_NULL; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_PAST; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_PAST_OR_PRESENT; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_PATTERN; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_POSITIVE; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_POSITIVE_OR_ZERO; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.JAVAX_VALIDATION_CONSTRAINTS_SIZE; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CNPJ; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CPF; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_TITULO_ELEITORAL; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CODE_POINT_LENGTH; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CREDIT_CARD_NUMBER; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CURRENCY; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EAN; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EMAIL; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_ISBN; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LENGTH; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LUHN_CHECK; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD_CHECK; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_BLANK; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_EMPTY; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PARAMETER_SCRIPT_ASSERT; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_NIP; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_PESEL; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_REGON; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_RANGE; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SAFE_HTML; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SCRIPT_ASSERT; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MAX; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MIN; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_UNIQUE_ELEMENTS; +import static org.hibernate.validator.internal.metadata.core.BuiltinConstraint.ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_URL; import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES; import java.lang.annotation.Annotation; @@ -17,6 +66,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -310,6 +360,7 @@ * @author Guillaume Smet */ public class ConstraintHelper { + public static final String GROUPS = "groups"; public static final String PAYLOAD = "payload"; public static final String MESSAGE = "message"; @@ -323,7 +374,7 @@ public class ConstraintHelper { private static final String JSOUP_CLASS_NAME = "org.jsoup.Jsoup"; @Immutable - private final Map, List>> builtinConstraints; + private final Map, List>> enabledBuiltinConstraints; private final ConcurrentMap, Boolean> externalConstraints = new ConcurrentHashMap<>(); @@ -331,405 +382,425 @@ public class ConstraintHelper { private final ValidatorDescriptorMap validatorDescriptors = new ValidatorDescriptorMap(); + public static ConstraintHelper forAllBuiltinConstraints() { + return new ConstraintHelper( new HashSet<>( Arrays.asList( BuiltinConstraint.values() ) ) ); + } + + public static ConstraintHelper forBuiltinConstraints(Set enabledConstraints) { + return new ConstraintHelper( BuiltinConstraint.resolve( enabledConstraints ) ); + } + @SuppressWarnings("deprecation") - public ConstraintHelper() { + private ConstraintHelper(Set enabledBuiltinConstraints) { + if ( enabledBuiltinConstraints.isEmpty() ) { + this.enabledBuiltinConstraints = Collections.emptyMap(); + return; + } + Map, List>> tmpConstraints = new HashMap<>(); // Bean Validation constraints - putConstraint( tmpConstraints, AssertFalse.class, AssertFalseValidator.class ); - putConstraint( tmpConstraints, AssertTrue.class, AssertTrueValidator.class ); - - if ( isJavaMoneyInClasspath() ) { - putConstraints( tmpConstraints, DecimalMax.class, Arrays.asList( - DecimalMaxValidatorForBigDecimal.class, - DecimalMaxValidatorForBigInteger.class, - DecimalMaxValidatorForByte.class, - DecimalMaxValidatorForDouble.class, - DecimalMaxValidatorForFloat.class, - DecimalMaxValidatorForLong.class, - DecimalMaxValidatorForInteger.class, - DecimalMaxValidatorForNumber.class, - DecimalMaxValidatorForShort.class, - DecimalMaxValidatorForCharSequence.class, - DecimalMaxValidatorForMonetaryAmount.class - ) ); - putConstraints( tmpConstraints, DecimalMin.class, Arrays.asList( - DecimalMinValidatorForBigDecimal.class, - DecimalMinValidatorForBigInteger.class, - DecimalMinValidatorForByte.class, - DecimalMinValidatorForDouble.class, - DecimalMinValidatorForFloat.class, - DecimalMinValidatorForLong.class, - DecimalMinValidatorForInteger.class, - DecimalMinValidatorForNumber.class, - DecimalMinValidatorForShort.class, - DecimalMinValidatorForCharSequence.class, - DecimalMinValidatorForMonetaryAmount.class - ) ); - putConstraints( tmpConstraints, Digits.class, Arrays.asList( - DigitsValidatorForCharSequence.class, - DigitsValidatorForNumber.class, - DigitsValidatorForMonetaryAmount.class - ) ); - } - else { - putConstraints( tmpConstraints, DecimalMax.class, Arrays.asList( - DecimalMaxValidatorForBigDecimal.class, - DecimalMaxValidatorForBigInteger.class, - DecimalMaxValidatorForByte.class, - DecimalMaxValidatorForDouble.class, - DecimalMaxValidatorForFloat.class, - DecimalMaxValidatorForLong.class, - DecimalMaxValidatorForInteger.class, - DecimalMaxValidatorForNumber.class, - DecimalMaxValidatorForShort.class, - DecimalMaxValidatorForCharSequence.class - ) ); - putConstraints( tmpConstraints, DecimalMin.class, Arrays.asList( - DecimalMinValidatorForBigDecimal.class, - DecimalMinValidatorForBigInteger.class, - DecimalMinValidatorForByte.class, - DecimalMinValidatorForDouble.class, - DecimalMinValidatorForFloat.class, - DecimalMinValidatorForLong.class, - DecimalMinValidatorForInteger.class, - DecimalMinValidatorForNumber.class, - DecimalMinValidatorForShort.class, - DecimalMinValidatorForCharSequence.class - ) ); - putConstraints( tmpConstraints, Digits.class, Arrays.asList( - DigitsValidatorForCharSequence.class, - DigitsValidatorForNumber.class - ) ); - } - - putConstraint( tmpConstraints, Email.class, EmailValidator.class ); - - List>> futureValidators = new ArrayList<>( 18 ); - futureValidators.add( FutureValidatorForCalendar.class ); - futureValidators.add( FutureValidatorForDate.class ); - if ( isJodaTimeInClasspath() ) { - futureValidators.add( FutureValidatorForReadableInstant.class ); - futureValidators.add( FutureValidatorForReadablePartial.class ); - } - // Java 8 date/time API validators - futureValidators.add( FutureValidatorForHijrahDate.class ); - futureValidators.add( FutureValidatorForInstant.class ); - futureValidators.add( FutureValidatorForJapaneseDate.class ); - futureValidators.add( FutureValidatorForLocalDate.class ); - futureValidators.add( FutureValidatorForLocalDateTime.class ); - futureValidators.add( FutureValidatorForLocalTime.class ); - futureValidators.add( FutureValidatorForMinguoDate.class ); - futureValidators.add( FutureValidatorForMonthDay.class ); - futureValidators.add( FutureValidatorForOffsetDateTime.class ); - futureValidators.add( FutureValidatorForOffsetTime.class ); - futureValidators.add( FutureValidatorForThaiBuddhistDate.class ); - futureValidators.add( FutureValidatorForYear.class ); - futureValidators.add( FutureValidatorForYearMonth.class ); - futureValidators.add( FutureValidatorForZonedDateTime.class ); - - putConstraints( tmpConstraints, Future.class, futureValidators ); - - List>> futureOrPresentValidators = new ArrayList<>( 18 ); - futureOrPresentValidators.add( FutureOrPresentValidatorForCalendar.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForDate.class ); - if ( isJodaTimeInClasspath() ) { - futureOrPresentValidators.add( FutureOrPresentValidatorForReadableInstant.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForReadablePartial.class ); - } - // Java 8 date/time API validators - futureOrPresentValidators.add( FutureOrPresentValidatorForHijrahDate.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForInstant.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForJapaneseDate.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForLocalDate.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForLocalDateTime.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForLocalTime.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForMinguoDate.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForMonthDay.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForOffsetDateTime.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForOffsetTime.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForThaiBuddhistDate.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForYear.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForYearMonth.class ); - futureOrPresentValidators.add( FutureOrPresentValidatorForZonedDateTime.class ); - - putConstraints( tmpConstraints, FutureOrPresent.class, futureOrPresentValidators ); - - if ( isJavaMoneyInClasspath() ) { - putConstraints( tmpConstraints, Max.class, Arrays.asList( - MaxValidatorForBigDecimal.class, - MaxValidatorForBigInteger.class, - MaxValidatorForByte.class, - MaxValidatorForDouble.class, - MaxValidatorForFloat.class, - MaxValidatorForInteger.class, - MaxValidatorForLong.class, - MaxValidatorForNumber.class, - MaxValidatorForShort.class, - MaxValidatorForCharSequence.class, - MaxValidatorForMonetaryAmount.class - ) ); - putConstraints( tmpConstraints, Min.class, Arrays.asList( - MinValidatorForBigDecimal.class, - MinValidatorForBigInteger.class, - MinValidatorForByte.class, - MinValidatorForDouble.class, - MinValidatorForFloat.class, - MinValidatorForInteger.class, - MinValidatorForLong.class, - MinValidatorForNumber.class, - MinValidatorForShort.class, - MinValidatorForCharSequence.class, - MinValidatorForMonetaryAmount.class - ) ); - } - else { - putConstraints( tmpConstraints, Max.class, Arrays.asList( - MaxValidatorForBigDecimal.class, - MaxValidatorForBigInteger.class, - MaxValidatorForDouble.class, - MaxValidatorForFloat.class, - MaxValidatorForLong.class, - MaxValidatorForNumber.class, - MaxValidatorForCharSequence.class - ) ); - putConstraints( tmpConstraints, Min.class, Arrays.asList( - MinValidatorForBigDecimal.class, - MinValidatorForBigInteger.class, - MinValidatorForByte.class, - MinValidatorForDouble.class, - MinValidatorForFloat.class, - MinValidatorForInteger.class, - MinValidatorForLong.class, - MinValidatorForNumber.class, - MinValidatorForShort.class, - MinValidatorForCharSequence.class - ) ); - } - - if ( isJavaMoneyInClasspath() ) { - putConstraints( tmpConstraints, Negative.class, Arrays.asList( - NegativeValidatorForBigDecimal.class, - NegativeValidatorForBigInteger.class, - NegativeValidatorForDouble.class, - NegativeValidatorForFloat.class, - NegativeValidatorForLong.class, - NegativeValidatorForInteger.class, - NegativeValidatorForShort.class, - NegativeValidatorForByte.class, - NegativeValidatorForNumber.class, - NegativeValidatorForMonetaryAmount.class ) ); - - putConstraints( tmpConstraints, NegativeOrZero.class, Arrays.asList( - NegativeOrZeroValidatorForBigDecimal.class, - NegativeOrZeroValidatorForBigInteger.class, - NegativeOrZeroValidatorForDouble.class, - NegativeOrZeroValidatorForFloat.class, - NegativeOrZeroValidatorForLong.class, - NegativeOrZeroValidatorForInteger.class, - NegativeOrZeroValidatorForShort.class, - NegativeOrZeroValidatorForByte.class, - NegativeOrZeroValidatorForNumber.class, - NegativeOrZeroValidatorForMonetaryAmount.class ) ); - } - else { - putConstraints( tmpConstraints, Negative.class, Arrays.asList( - NegativeValidatorForBigDecimal.class, - NegativeValidatorForBigInteger.class, - NegativeValidatorForDouble.class, - NegativeValidatorForFloat.class, - NegativeValidatorForLong.class, - NegativeValidatorForInteger.class, - NegativeValidatorForShort.class, - NegativeValidatorForByte.class, - NegativeValidatorForNumber.class - ) ); - - putConstraints( tmpConstraints, NegativeOrZero.class, Arrays.asList( - NegativeOrZeroValidatorForBigDecimal.class, - NegativeOrZeroValidatorForBigInteger.class, - NegativeOrZeroValidatorForDouble.class, - NegativeOrZeroValidatorForFloat.class, - NegativeOrZeroValidatorForLong.class, - NegativeOrZeroValidatorForInteger.class, - NegativeOrZeroValidatorForShort.class, - NegativeOrZeroValidatorForByte.class, - NegativeOrZeroValidatorForNumber.class - ) ); - } - putConstraint( tmpConstraints, NotBlank.class, NotBlankValidator.class ); - - List>> notEmptyValidators = new ArrayList<>( 11 ); - notEmptyValidators.add( NotEmptyValidatorForCharSequence.class ); - notEmptyValidators.add( NotEmptyValidatorForCollection.class ); - notEmptyValidators.add( NotEmptyValidatorForArray.class ); - notEmptyValidators.add( NotEmptyValidatorForMap.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfBoolean.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfByte.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfChar.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfDouble.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfFloat.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfInt.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfLong.class ); - notEmptyValidators.add( NotEmptyValidatorForArraysOfShort.class ); - putConstraints( tmpConstraints, NotEmpty.class, notEmptyValidators ); - - putConstraint( tmpConstraints, NotNull.class, NotNullValidator.class ); - putConstraint( tmpConstraints, Null.class, NullValidator.class ); - - List>> pastValidators = new ArrayList<>( 18 ); - pastValidators.add( PastValidatorForCalendar.class ); - pastValidators.add( PastValidatorForDate.class ); - if ( isJodaTimeInClasspath() ) { - pastValidators.add( PastValidatorForReadableInstant.class ); - pastValidators.add( PastValidatorForReadablePartial.class ); - } - // Java 8 date/time API validators - pastValidators.add( PastValidatorForHijrahDate.class ); - pastValidators.add( PastValidatorForInstant.class ); - pastValidators.add( PastValidatorForJapaneseDate.class ); - pastValidators.add( PastValidatorForLocalDate.class ); - pastValidators.add( PastValidatorForLocalDateTime.class ); - pastValidators.add( PastValidatorForLocalTime.class ); - pastValidators.add( PastValidatorForMinguoDate.class ); - pastValidators.add( PastValidatorForMonthDay.class ); - pastValidators.add( PastValidatorForOffsetDateTime.class ); - pastValidators.add( PastValidatorForOffsetTime.class ); - pastValidators.add( PastValidatorForThaiBuddhistDate.class ); - pastValidators.add( PastValidatorForYear.class ); - pastValidators.add( PastValidatorForYearMonth.class ); - pastValidators.add( PastValidatorForZonedDateTime.class ); - - putConstraints( tmpConstraints, Past.class, pastValidators ); - - List>> pastOrPresentValidators = new ArrayList<>( 18 ); - pastOrPresentValidators.add( PastOrPresentValidatorForCalendar.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForDate.class ); - if ( isJodaTimeInClasspath() ) { - pastOrPresentValidators.add( PastOrPresentValidatorForReadableInstant.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForReadablePartial.class ); - } - // Java 8 date/time API validators - pastOrPresentValidators.add( PastOrPresentValidatorForHijrahDate.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForInstant.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForJapaneseDate.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForLocalDate.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForLocalDateTime.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForLocalTime.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForMinguoDate.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForMonthDay.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForOffsetDateTime.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForOffsetTime.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForThaiBuddhistDate.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForYear.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForYearMonth.class ); - pastOrPresentValidators.add( PastOrPresentValidatorForZonedDateTime.class ); - - putConstraints( tmpConstraints, PastOrPresent.class, pastOrPresentValidators ); - - putConstraint( tmpConstraints, Pattern.class, PatternValidator.class ); - if ( isJavaMoneyInClasspath() ) { - putConstraints( tmpConstraints, Positive.class, Arrays.asList( - PositiveValidatorForBigDecimal.class, - PositiveValidatorForBigInteger.class, - PositiveValidatorForDouble.class, - PositiveValidatorForFloat.class, - PositiveValidatorForLong.class, - PositiveValidatorForInteger.class, - PositiveValidatorForShort.class, - PositiveValidatorForByte.class, - PositiveValidatorForNumber.class, - PositiveValidatorForMonetaryAmount.class ) ); - - putConstraints( tmpConstraints, PositiveOrZero.class, Arrays.asList( - PositiveOrZeroValidatorForBigDecimal.class, - PositiveOrZeroValidatorForBigInteger.class, - PositiveOrZeroValidatorForDouble.class, - PositiveOrZeroValidatorForFloat.class, - PositiveOrZeroValidatorForLong.class, - PositiveOrZeroValidatorForInteger.class, - PositiveOrZeroValidatorForShort.class, - PositiveOrZeroValidatorForByte.class, - PositiveOrZeroValidatorForNumber.class, - PositiveOrZeroValidatorForMonetaryAmount.class ) ); - } - else { - putConstraints( tmpConstraints, Positive.class, Arrays.asList( - PositiveValidatorForBigDecimal.class, - PositiveValidatorForBigInteger.class, - PositiveValidatorForDouble.class, - PositiveValidatorForFloat.class, - PositiveValidatorForLong.class, - PositiveValidatorForInteger.class, - PositiveValidatorForShort.class, - PositiveValidatorForByte.class, - PositiveValidatorForNumber.class - ) ); - - putConstraints( tmpConstraints, PositiveOrZero.class, Arrays.asList( - PositiveOrZeroValidatorForBigDecimal.class, - PositiveOrZeroValidatorForBigInteger.class, - PositiveOrZeroValidatorForDouble.class, - PositiveOrZeroValidatorForFloat.class, - PositiveOrZeroValidatorForLong.class, - PositiveOrZeroValidatorForInteger.class, - PositiveOrZeroValidatorForShort.class, - PositiveOrZeroValidatorForByte.class, - PositiveOrZeroValidatorForNumber.class - ) ); - } - - List>> sizeValidators = new ArrayList<>( 11 ); - sizeValidators.add( SizeValidatorForCharSequence.class ); - sizeValidators.add( SizeValidatorForCollection.class ); - sizeValidators.add( SizeValidatorForArray.class ); - sizeValidators.add( SizeValidatorForMap.class ); - sizeValidators.add( SizeValidatorForArraysOfBoolean.class ); - sizeValidators.add( SizeValidatorForArraysOfByte.class ); - sizeValidators.add( SizeValidatorForArraysOfChar.class ); - sizeValidators.add( SizeValidatorForArraysOfDouble.class ); - sizeValidators.add( SizeValidatorForArraysOfFloat.class ); - sizeValidators.add( SizeValidatorForArraysOfInt.class ); - sizeValidators.add( SizeValidatorForArraysOfLong.class ); - sizeValidators.add( SizeValidatorForArraysOfShort.class ); - putConstraints( tmpConstraints, Size.class, sizeValidators ); + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_ASSERT_FALSE ) ) { + putConstraint( tmpConstraints, AssertFalse.class, AssertFalseValidator.class ); + } + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_ASSERT_TRUE ) ) { + putConstraint( tmpConstraints, AssertTrue.class, AssertTrueValidator.class ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MAX ) ) { + List>> decimalMaxValidators = new ArrayList<>(); + decimalMaxValidators.add( DecimalMaxValidatorForBigDecimal.class ); + decimalMaxValidators.add( DecimalMaxValidatorForBigInteger.class ); + decimalMaxValidators.add( DecimalMaxValidatorForByte.class ); + decimalMaxValidators.add( DecimalMaxValidatorForDouble.class ); + decimalMaxValidators.add( DecimalMaxValidatorForFloat.class ); + decimalMaxValidators.add( DecimalMaxValidatorForLong.class ); + decimalMaxValidators.add( DecimalMaxValidatorForInteger.class ); + decimalMaxValidators.add( DecimalMaxValidatorForNumber.class ); + decimalMaxValidators.add( DecimalMaxValidatorForShort.class ); + decimalMaxValidators.add( DecimalMaxValidatorForCharSequence.class ); + if ( isJavaMoneyInClasspath() ) { + decimalMaxValidators.add( DecimalMaxValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, DecimalMax.class, decimalMaxValidators ); + } + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_DECIMAL_MIN ) ) { + List>> decimalMinValidators = new ArrayList<>(); + decimalMinValidators.add( DecimalMinValidatorForBigDecimal.class ); + decimalMinValidators.add( DecimalMinValidatorForBigInteger.class ); + decimalMinValidators.add( DecimalMinValidatorForByte.class ); + decimalMinValidators.add( DecimalMinValidatorForDouble.class ); + decimalMinValidators.add( DecimalMinValidatorForFloat.class ); + decimalMinValidators.add( DecimalMinValidatorForLong.class ); + decimalMinValidators.add( DecimalMinValidatorForInteger.class ); + decimalMinValidators.add( DecimalMinValidatorForNumber.class ); + decimalMinValidators.add( DecimalMinValidatorForShort.class ); + decimalMinValidators.add( DecimalMinValidatorForCharSequence.class ); + if ( isJavaMoneyInClasspath() ) { + decimalMinValidators.add( DecimalMinValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, DecimalMin.class, decimalMinValidators ); + } + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_DIGITS ) ) { + List>> digitsValidators = new ArrayList<>(); + digitsValidators.add( DigitsValidatorForCharSequence.class ); + digitsValidators.add( DigitsValidatorForNumber.class ); + if ( isJavaMoneyInClasspath() ) { + digitsValidators.add( DigitsValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, Digits.class, digitsValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_EMAIL ) ) { + putConstraint( tmpConstraints, Email.class, EmailValidator.class ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_FUTURE ) ) { + List>> futureValidators = new ArrayList<>( 18 ); + futureValidators.add( FutureValidatorForCalendar.class ); + futureValidators.add( FutureValidatorForDate.class ); + if ( isJodaTimeInClasspath() ) { + futureValidators.add( FutureValidatorForReadableInstant.class ); + futureValidators.add( FutureValidatorForReadablePartial.class ); + } + // Java 8 date/time API validators + futureValidators.add( FutureValidatorForHijrahDate.class ); + futureValidators.add( FutureValidatorForInstant.class ); + futureValidators.add( FutureValidatorForJapaneseDate.class ); + futureValidators.add( FutureValidatorForLocalDate.class ); + futureValidators.add( FutureValidatorForLocalDateTime.class ); + futureValidators.add( FutureValidatorForLocalTime.class ); + futureValidators.add( FutureValidatorForMinguoDate.class ); + futureValidators.add( FutureValidatorForMonthDay.class ); + futureValidators.add( FutureValidatorForOffsetDateTime.class ); + futureValidators.add( FutureValidatorForOffsetTime.class ); + futureValidators.add( FutureValidatorForThaiBuddhistDate.class ); + futureValidators.add( FutureValidatorForYear.class ); + futureValidators.add( FutureValidatorForYearMonth.class ); + futureValidators.add( FutureValidatorForZonedDateTime.class ); + + putConstraints( tmpConstraints, Future.class, futureValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_FUTURE_OR_PRESENT ) ) { + List>> futureOrPresentValidators = new ArrayList<>( 18 ); + futureOrPresentValidators.add( FutureOrPresentValidatorForCalendar.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForDate.class ); + if ( isJodaTimeInClasspath() ) { + futureOrPresentValidators.add( FutureOrPresentValidatorForReadableInstant.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForReadablePartial.class ); + } + // Java 8 date/time API validators + futureOrPresentValidators.add( FutureOrPresentValidatorForHijrahDate.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForInstant.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForJapaneseDate.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForLocalDate.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForLocalDateTime.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForLocalTime.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForMinguoDate.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForMonthDay.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForOffsetDateTime.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForOffsetTime.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForThaiBuddhistDate.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForYear.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForYearMonth.class ); + futureOrPresentValidators.add( FutureOrPresentValidatorForZonedDateTime.class ); + + putConstraints( tmpConstraints, FutureOrPresent.class, futureOrPresentValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_MAX ) ) { + List>> maxValidators = new ArrayList<>(); + maxValidators.add( MaxValidatorForBigDecimal.class ); + maxValidators.add( MaxValidatorForBigInteger.class ); + maxValidators.add( MaxValidatorForByte.class ); + maxValidators.add( MaxValidatorForDouble.class ); + maxValidators.add( MaxValidatorForFloat.class ); + maxValidators.add( MaxValidatorForInteger.class ); + maxValidators.add( MaxValidatorForLong.class ); + maxValidators.add( MaxValidatorForNumber.class ); + maxValidators.add( MaxValidatorForShort.class ); + maxValidators.add( MaxValidatorForCharSequence.class ); + if ( isJavaMoneyInClasspath() ) { + maxValidators.add( MaxValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, Max.class, maxValidators ); + } + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_MIN ) ) { + List>> minValidators = new ArrayList<>(); + minValidators.add( MinValidatorForBigDecimal.class ); + minValidators.add( MinValidatorForBigInteger.class ); + minValidators.add( MinValidatorForByte.class ); + minValidators.add( MinValidatorForDouble.class ); + minValidators.add( MinValidatorForFloat.class ); + minValidators.add( MinValidatorForInteger.class ); + minValidators.add( MinValidatorForLong.class ); + minValidators.add( MinValidatorForNumber.class ); + minValidators.add( MinValidatorForShort.class ); + minValidators.add( MinValidatorForCharSequence.class ); + if ( isJavaMoneyInClasspath() ) { + minValidators.add( MinValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, Min.class, minValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE ) ) { + List>> negativeValidators = new ArrayList<>(); + negativeValidators.add( NegativeValidatorForBigDecimal.class ); + negativeValidators.add( NegativeValidatorForBigInteger.class ); + negativeValidators.add( NegativeValidatorForDouble.class ); + negativeValidators.add( NegativeValidatorForFloat.class ); + negativeValidators.add( NegativeValidatorForLong.class ); + negativeValidators.add( NegativeValidatorForInteger.class ); + negativeValidators.add( NegativeValidatorForShort.class ); + negativeValidators.add( NegativeValidatorForByte.class ); + negativeValidators.add( NegativeValidatorForNumber.class ); + if ( isJavaMoneyInClasspath() ) { + negativeValidators.add( NegativeValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, Negative.class, negativeValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NEGATIVE_OR_ZERO ) ) { + List>> negativeOrZeroValidators = new ArrayList<>(); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForBigDecimal.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForBigInteger.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForDouble.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForFloat.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForLong.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForInteger.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForShort.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForByte.class ); + negativeOrZeroValidators.add( NegativeOrZeroValidatorForNumber.class ); + if ( isJavaMoneyInClasspath() ) { + negativeOrZeroValidators.add( NegativeOrZeroValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, NegativeOrZero.class, negativeOrZeroValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NOT_BLANK ) ) { + putConstraint( tmpConstraints, NotBlank.class, NotBlankValidator.class ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NOT_EMPTY ) ) { + List>> notEmptyValidators = new ArrayList<>( 11 ); + notEmptyValidators.add( NotEmptyValidatorForCharSequence.class ); + notEmptyValidators.add( NotEmptyValidatorForCollection.class ); + notEmptyValidators.add( NotEmptyValidatorForArray.class ); + notEmptyValidators.add( NotEmptyValidatorForMap.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfBoolean.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfByte.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfChar.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfDouble.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfFloat.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfInt.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfLong.class ); + notEmptyValidators.add( NotEmptyValidatorForArraysOfShort.class ); + putConstraints( tmpConstraints, NotEmpty.class, notEmptyValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NOT_NULL ) ) { + putConstraint( tmpConstraints, NotNull.class, NotNullValidator.class ); + } + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_NULL ) ) { + putConstraint( tmpConstraints, Null.class, NullValidator.class ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_PAST ) ) { + List>> pastValidators = new ArrayList<>( 18 ); + pastValidators.add( PastValidatorForCalendar.class ); + pastValidators.add( PastValidatorForDate.class ); + if ( isJodaTimeInClasspath() ) { + pastValidators.add( PastValidatorForReadableInstant.class ); + pastValidators.add( PastValidatorForReadablePartial.class ); + } + // Java 8 date/time API validators + pastValidators.add( PastValidatorForHijrahDate.class ); + pastValidators.add( PastValidatorForInstant.class ); + pastValidators.add( PastValidatorForJapaneseDate.class ); + pastValidators.add( PastValidatorForLocalDate.class ); + pastValidators.add( PastValidatorForLocalDateTime.class ); + pastValidators.add( PastValidatorForLocalTime.class ); + pastValidators.add( PastValidatorForMinguoDate.class ); + pastValidators.add( PastValidatorForMonthDay.class ); + pastValidators.add( PastValidatorForOffsetDateTime.class ); + pastValidators.add( PastValidatorForOffsetTime.class ); + pastValidators.add( PastValidatorForThaiBuddhistDate.class ); + pastValidators.add( PastValidatorForYear.class ); + pastValidators.add( PastValidatorForYearMonth.class ); + pastValidators.add( PastValidatorForZonedDateTime.class ); + + putConstraints( tmpConstraints, Past.class, pastValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_PAST_OR_PRESENT ) ) { + List>> pastOrPresentValidators = new ArrayList<>( 18 ); + pastOrPresentValidators.add( PastOrPresentValidatorForCalendar.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForDate.class ); + if ( isJodaTimeInClasspath() ) { + pastOrPresentValidators.add( PastOrPresentValidatorForReadableInstant.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForReadablePartial.class ); + } + // Java 8 date/time API validators + pastOrPresentValidators.add( PastOrPresentValidatorForHijrahDate.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForInstant.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForJapaneseDate.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForLocalDate.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForLocalDateTime.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForLocalTime.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForMinguoDate.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForMonthDay.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForOffsetDateTime.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForOffsetTime.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForThaiBuddhistDate.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForYear.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForYearMonth.class ); + pastOrPresentValidators.add( PastOrPresentValidatorForZonedDateTime.class ); + + putConstraints( tmpConstraints, PastOrPresent.class, pastOrPresentValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_PATTERN ) ) { + putConstraint( tmpConstraints, Pattern.class, PatternValidator.class ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_POSITIVE ) ) { + List>> positiveValidators = new ArrayList<>(); + positiveValidators.add( PositiveValidatorForBigDecimal.class ); + positiveValidators.add( PositiveValidatorForBigInteger.class ); + positiveValidators.add( PositiveValidatorForDouble.class ); + positiveValidators.add( PositiveValidatorForFloat.class ); + positiveValidators.add( PositiveValidatorForLong.class ); + positiveValidators.add( PositiveValidatorForInteger.class ); + positiveValidators.add( PositiveValidatorForShort.class ); + positiveValidators.add( PositiveValidatorForByte.class ); + positiveValidators.add( PositiveValidatorForNumber.class ); + if ( isJavaMoneyInClasspath() ) { + positiveValidators.add( PositiveValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, Positive.class, positiveValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_POSITIVE_OR_ZERO ) ) { + List>> positiveOrZeroValidators = new ArrayList<>(); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForBigDecimal.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForBigInteger.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForDouble.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForFloat.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForLong.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForInteger.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForShort.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForByte.class ); + positiveOrZeroValidators.add( PositiveOrZeroValidatorForNumber.class ); + if ( isJavaMoneyInClasspath() ) { + positiveOrZeroValidators.add( PositiveOrZeroValidatorForMonetaryAmount.class ); + } + putConstraints( tmpConstraints, PositiveOrZero.class, positiveOrZeroValidators ); + } + + if ( enabledBuiltinConstraints.contains( JAVAX_VALIDATION_CONSTRAINTS_SIZE ) ) { + List>> sizeValidators = new ArrayList<>( 11 ); + sizeValidators.add( SizeValidatorForCharSequence.class ); + sizeValidators.add( SizeValidatorForCollection.class ); + sizeValidators.add( SizeValidatorForArray.class ); + sizeValidators.add( SizeValidatorForMap.class ); + sizeValidators.add( SizeValidatorForArraysOfBoolean.class ); + sizeValidators.add( SizeValidatorForArraysOfByte.class ); + sizeValidators.add( SizeValidatorForArraysOfChar.class ); + sizeValidators.add( SizeValidatorForArraysOfDouble.class ); + sizeValidators.add( SizeValidatorForArraysOfFloat.class ); + sizeValidators.add( SizeValidatorForArraysOfInt.class ); + sizeValidators.add( SizeValidatorForArraysOfLong.class ); + sizeValidators.add( SizeValidatorForArraysOfShort.class ); + putConstraints( tmpConstraints, Size.class, sizeValidators ); + } // Hibernate Validator specific constraints - putConstraint( tmpConstraints, CNPJ.class, CNPJValidator.class ); - putConstraint( tmpConstraints, CPF.class, CPFValidator.class ); - if ( isJavaMoneyInClasspath() ) { + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CNPJ ) ) { + putConstraint( tmpConstraints, CNPJ.class, CNPJValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_CPF ) ) { + putConstraint( tmpConstraints, CPF.class, CPFValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CURRENCY ) && isJavaMoneyInClasspath() ) { putConstraint( tmpConstraints, Currency.class, CurrencyValidatorForMonetaryAmount.class ); } - putConstraint( tmpConstraints, CreditCardNumber.class ); - putConstraint( tmpConstraints, DurationMax.class, DurationMaxValidator.class ); - putConstraint( tmpConstraints, DurationMin.class, DurationMinValidator.class ); - putConstraint( tmpConstraints, EAN.class, EANValidator.class ); - putConstraint( tmpConstraints, org.hibernate.validator.constraints.Email.class, org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator.class ); - putConstraint( tmpConstraints, ISBN.class, ISBNValidator.class ); - putConstraint( tmpConstraints, Length.class, LengthValidator.class ); - putConstraint( tmpConstraints, CodePointLength.class, CodePointLengthValidator.class ); - putConstraint( tmpConstraints, LuhnCheck.class, LuhnCheckValidator.class ); - putConstraint( tmpConstraints, ModCheck.class, ModCheckValidator.class ); - putConstraint( tmpConstraints, Mod10Check.class, Mod10CheckValidator.class ); - putConstraint( tmpConstraints, Mod11Check.class, Mod11CheckValidator.class ); - putConstraint( tmpConstraints, NIP.class, NIPValidator.class ); - putConstraint( tmpConstraints, org.hibernate.validator.constraints.NotBlank.class, org.hibernate.validator.internal.constraintvalidators.hv.NotBlankValidator.class ); - putConstraint( tmpConstraints, org.hibernate.validator.constraints.NotEmpty.class ); - putConstraint( tmpConstraints, ParameterScriptAssert.class, ParameterScriptAssertValidator.class ); - putConstraint( tmpConstraints, PESEL.class, PESELValidator.class ); - putConstraint( tmpConstraints, Range.class ); - putConstraint( tmpConstraints, REGON.class, REGONValidator.class ); - if ( isJsoupInClasspath() ) { + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CREDIT_CARD_NUMBER ) ) { + putConstraint( tmpConstraints, CreditCardNumber.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MAX ) ) { + putConstraint( tmpConstraints, DurationMax.class, DurationMaxValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_TIME_DURATION_MIN ) ) { + putConstraint( tmpConstraints, DurationMin.class, DurationMinValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EAN ) ) { + putConstraint( tmpConstraints, EAN.class, EANValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_EMAIL ) ) { + putConstraint( tmpConstraints, org.hibernate.validator.constraints.Email.class, org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_ISBN ) ) { + putConstraint( tmpConstraints, ISBN.class, ISBNValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LENGTH ) ) { + putConstraint( tmpConstraints, Length.class, LengthValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_CODE_POINT_LENGTH ) ) { + putConstraint( tmpConstraints, CodePointLength.class, CodePointLengthValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_LUHN_CHECK ) ) { + putConstraint( tmpConstraints, LuhnCheck.class, LuhnCheckValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD_CHECK ) ) { + putConstraint( tmpConstraints, ModCheck.class, ModCheckValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD10_CHECK ) ) { + putConstraint( tmpConstraints, Mod10Check.class, Mod10CheckValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_MOD11_CHECK ) ) { + putConstraint( tmpConstraints, Mod11Check.class, Mod11CheckValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_NIP ) ) { + putConstraint( tmpConstraints, NIP.class, NIPValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_BLANK ) ) { + putConstraint( tmpConstraints, org.hibernate.validator.constraints.NotBlank.class, org.hibernate.validator.internal.constraintvalidators.hv.NotBlankValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_NOT_EMPTY ) ) { + putConstraint( tmpConstraints, org.hibernate.validator.constraints.NotEmpty.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PARAMETER_SCRIPT_ASSERT ) ) { + putConstraint( tmpConstraints, ParameterScriptAssert.class, ParameterScriptAssertValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_PESEL ) ) { + putConstraint( tmpConstraints, PESEL.class, PESELValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_RANGE ) ) { + putConstraint( tmpConstraints, Range.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_PL_REGON ) ) { + putConstraint( tmpConstraints, REGON.class, REGONValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SAFE_HTML ) && isJsoupInClasspath() ) { putConstraint( tmpConstraints, SafeHtml.class, SafeHtmlValidator.class ); } - putConstraint( tmpConstraints, ScriptAssert.class, ScriptAssertValidator.class ); - putConstraint( tmpConstraints, TituloEleitoral.class ); - putConstraint( tmpConstraints, UniqueElements.class, UniqueElementsValidator.class ); - putConstraint( tmpConstraints, URL.class, URLValidator.class ); + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_SCRIPT_ASSERT ) ) { + putConstraint( tmpConstraints, ScriptAssert.class, ScriptAssertValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_BR_TITULO_ELEITORAL ) ) { + putConstraint( tmpConstraints, TituloEleitoral.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_UNIQUE_ELEMENTS ) ) { + putConstraint( tmpConstraints, UniqueElements.class, UniqueElementsValidator.class ); + } + if ( enabledBuiltinConstraints.contains( ORG_HIBERNATE_VALIDATOR_CONSTRAINTS_URL ) ) { + putConstraint( tmpConstraints, URL.class, URLValidator.class ); + } - this.builtinConstraints = Collections.unmodifiableMap( tmpConstraints ); + this.enabledBuiltinConstraints = Collections.unmodifiableMap( tmpConstraints ); } private static void putConstraint(Map, List>> validators, @@ -764,11 +835,11 @@ private static void putConstraints(Map annotationType) { - return builtinConstraints.containsKey( annotationType ); + return BuiltinConstraint.isBuiltin( annotationType.getName() ); } - public Set> getBuiltinConstraints() { - return CollectionHelper.toImmutableSet( builtinConstraints.keySet() ); + public static Set getBuiltinConstraints() { + return BuiltinConstraint.set(); } /** @@ -1055,7 +1126,7 @@ private static boolean isJsoupInClasspath() { @SuppressWarnings("unchecked") private List> getDefaultValidatorDescriptors(Class annotationType) { //safe cause all CV for a given annotation A are CV - final List> builtInValidators = (List>) builtinConstraints + final List> builtInValidators = (List>) enabledBuiltinConstraints .get( annotationType ); if ( builtInValidators != null ) { diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/PredefinedScopeAllConstraintsTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/PredefinedScopeAllConstraintsTest.java new file mode 100644 index 0000000000..a157dbc051 --- /dev/null +++ b/engine/src/test/java/org/hibernate/validator/test/internal/constraintvalidators/PredefinedScopeAllConstraintsTest.java @@ -0,0 +1,457 @@ +/* + * Hibernate Validator, declare and validate application constraints + * + * License: Apache License, Version 2.0 + * See the license.txt file in the root directory or . + */ +package org.hibernate.validator.test.internal.constraintvalidators; + +import static org.hibernate.validator.testutil.ConstraintViolationAssert.violationOf; + +import java.lang.annotation.Annotation; +import java.math.BigDecimal; +import java.time.Duration; +import java.time.LocalDate; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import javax.money.MonetaryAmount; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.constraints.AssertFalse; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.DecimalMax; +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.Digits; +import javax.validation.constraints.Email; +import javax.validation.constraints.Future; +import javax.validation.constraints.FutureOrPresent; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Negative; +import javax.validation.constraints.NegativeOrZero; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Null; +import javax.validation.constraints.Past; +import javax.validation.constraints.PastOrPresent; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Positive; +import javax.validation.constraints.PositiveOrZero; +import javax.validation.constraints.Size; + +import org.hibernate.validator.PredefinedScopeHibernateValidator; +import org.hibernate.validator.constraints.CodePointLength; +import org.hibernate.validator.constraints.CreditCardNumber; +import org.hibernate.validator.constraints.Currency; +import org.hibernate.validator.constraints.EAN; +import org.hibernate.validator.constraints.ISBN; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.LuhnCheck; +import org.hibernate.validator.constraints.Mod10Check; +import org.hibernate.validator.constraints.Mod11Check; +import org.hibernate.validator.constraints.ModCheck; +import org.hibernate.validator.constraints.ParameterScriptAssert; +import org.hibernate.validator.constraints.Range; +import org.hibernate.validator.constraints.SafeHtml; +import org.hibernate.validator.constraints.ScriptAssert; +import org.hibernate.validator.constraints.URL; +import org.hibernate.validator.constraints.UniqueElements; +import org.hibernate.validator.constraints.br.CNPJ; +import org.hibernate.validator.constraints.br.CPF; +import org.hibernate.validator.constraints.br.TituloEleitoral; +import org.hibernate.validator.constraints.pl.NIP; +import org.hibernate.validator.constraints.pl.PESEL; +import org.hibernate.validator.constraints.pl.REGON; +import org.hibernate.validator.constraints.time.DurationMax; +import org.hibernate.validator.constraints.time.DurationMin; +import org.hibernate.validator.testutil.ConstraintViolationAssert; +import org.javamoney.moneta.Money; +import org.testng.annotations.Test; + +/** + * Test that all the messages of all the constraints are properly interpolated for all the supported locales. + * + * @author Guillaume Smet + */ +@SuppressWarnings("deprecation") +public class PredefinedScopeAllConstraintsTest { + + @Test + public void testConstraints() throws NoSuchMethodException, SecurityException { + testConstraint( AssertFalse.class, new AssertFalseBean() ); + testConstraint( AssertTrue.class, new AssertTrueBean() ); + testConstraint( DecimalMax.class, new DecimalMaxBean() ); + testConstraint( DecimalMin.class, new DecimalMinBean() ); + testConstraint( Digits.class, new DigitsBean() ); + testConstraint( Email.class, new EmailBean() ); + testConstraint( Future.class, new FutureBean() ); + testConstraint( FutureOrPresent.class, new FutureOrPresentBean() ); + testConstraint( Max.class, new MaxBean() ); + testConstraint( Min.class, new MinBean() ); + testConstraint( Negative.class, new NegativeBean() ); + testConstraint( NegativeOrZero.class, new NegativeOrZeroBean() ); + testConstraint( NotBlank.class, new NotBlankBean() ); + testConstraint( NotEmpty.class, new NotEmptyBean() ); + testConstraint( NotNull.class, new NotNullBean() ); + testConstraint( Null.class, new NullBean() ); + testConstraint( Past.class, new PastBean() ); + testConstraint( PastOrPresent.class, new PastOrPresentBean() ); + testConstraint( Pattern.class, new PatternBean() ); + testConstraint( Positive.class, new PositiveBean() ); + testConstraint( PositiveOrZero.class, new PositiveOrZeroBean() ); + testConstraint( Size.class, new SizeBean() ); + testConstraint( CreditCardNumber.class, new CreditCardNumberBean() ); + testConstraint( Currency.class, new CurrencyBean() ); + testConstraint( EAN.class, new EANBean() ); + testConstraint( org.hibernate.validator.constraints.Email.class, new HvEmailBean() ); + testConstraint( ISBN.class, new ISBNBean() ); + testConstraint( Length.class, new LengthBean() ); + testConstraint( CodePointLength.class, new CodePointLengthBean() ); + testConstraint( LuhnCheck.class, new LuhnCheckBean() ); + testConstraint( Mod10Check.class, new Mod10CheckBean() ); + testConstraint( Mod11Check.class, new Mod11CheckBean() ); + testConstraint( ModCheck.class, new ModCheckBean() ); + testConstraint( org.hibernate.validator.constraints.NotBlank.class, new HvNotBlankBean() ); + testConstraint( org.hibernate.validator.constraints.NotEmpty.class, new HvNotEmptyBean() ); + testConstraint( Range.class, new RangeBean() ); + testConstraint( SafeHtml.class, new SafeHtmlBean() ); + testConstraint( UniqueElements.class, new UniqueElementsBean() ); + testConstraint( URL.class, new URLBean() ); + testConstraint( CNPJ.class, new CNPJBean() ); + testConstraint( CPF.class, new CPFBean() ); + testConstraint( TituloEleitoral.class, new TituloEleitoralBean() ); + testConstraint( REGON.class, new REGONBean() ); + testConstraint( NIP.class, new NIPBean() ); + testConstraint( PESEL.class, new PESELBean() ); + testConstraint( DurationMax.class, new DurationMaxBean() ); + testConstraint( DurationMin.class, new DurationMinBean() ); + testConstraint( ScriptAssert.class, new ScriptAssertBean() ); + + Set> parameterScriptAssertBeanViolations = getValidator( ParameterScriptAssert.class, + ParameterScriptAssertBean.class ).forExecutables().validateParameters( + new ParameterScriptAssertBean(), ParameterScriptAssertBean.class.getDeclaredMethod( "doTest", boolean.class ), new Object[]{ false } ); + + ConstraintViolationAssert.assertThat( parameterScriptAssertBeanViolations ) + .containsOnlyViolations( + violationOf( ParameterScriptAssert.class ) ); + } + + private void testConstraint(Class constraint, T bean) { + Set> violations = getValidator( constraint, bean.getClass() ) + .validate( bean ); + ConstraintViolationAssert.assertThat( violations ) + .containsOnlyViolations( + violationOf( constraint ) ); + } + + private static Validator getValidator(Class constraint, Class beanClass) { + return Validation.byProvider( PredefinedScopeHibernateValidator.class ) + .configure() + .builtinConstraints( Collections.singleton( constraint.getName() ) ) + .initializeBeanMetaData( Collections.singleton( beanClass ) ) + .buildValidatorFactory() + .getValidator(); + } + + private static class AssertFalseBean { + + @AssertFalse + private boolean assertFalse = true; + } + + private static class AssertTrueBean { + + @AssertTrue + private boolean assertTrue = false; + } + + private static class DecimalMaxBean { + + @DecimalMax("3") + private double decimalMax = 4; + } + + private static class DecimalMinBean { + + @DecimalMin("3") + private double decimalMin = 2; + } + + private static class DigitsBean { + + @Digits(integer = 1, fraction = 3) + private BigDecimal digits = BigDecimal.valueOf( 13333.3333f ); + } + + private static class EmailBean { + + @Email + private String email = "invalid"; + } + + private static class FutureBean { + + @Future + private LocalDate future = LocalDate.of( 2010, 10, 4 ); + } + + private static class FutureOrPresentBean { + + @FutureOrPresent + private LocalDate futureOrPresent = LocalDate.of( 2010, 10, 4 ); + } + + private static class MaxBean { + + @Max(4) + private int max = 6; + } + + private static class MinBean { + + @Min(4) + private int min = 2; + } + + private static class NegativeBean { + + @Negative + private int negative = 4; + } + + private static class NegativeOrZeroBean { + + @NegativeOrZero + private int negativeOrZero = 4; + } + + private static class NotBlankBean { + + @NotBlank + private String notBlank = ""; + } + + private static class NotEmptyBean { + + @NotEmpty + private List notEmpty = Collections.emptyList(); + } + + private static class NotNullBean { + + @NotNull + private String notNull = null; + } + + private static class NullBean { + + @Null + private String nullConstraint = "not null"; + } + + private static class PastBean { + + @Past + private LocalDate past = LocalDate.of( 2890, 10, 4 ); + } + + private static class PastOrPresentBean { + + @PastOrPresent + private LocalDate pastOrPresent = LocalDate.of( 2890, 10, 4 ); + } + + private static class PatternBean { + + @Pattern(regexp = "[0-9]+") + private String pattern = "invalid"; + } + + private static class PositiveBean { + + @Positive + private int positive = -4; + } + + private static class PositiveOrZeroBean { + + @PositiveOrZero + private int positiveOrZero = -4; + } + + private static class SizeBean { + + @Size(min = 2, max = 4) + private String size = "666666"; + } + + private static class CreditCardNumberBean { + + @CreditCardNumber + private String creditCardNumber = "invalid"; + } + + private static class CurrencyBean { + + @Currency("EUR") + private MonetaryAmount currency = Money.of( 1000f, "USD" ); + } + + private static class EANBean { + + @EAN + private String ean = "invalid"; + } + + private static class HvEmailBean { + + @org.hibernate.validator.constraints.Email + private String hvEmail = "invalid"; + } + + private static class ISBNBean { + + @ISBN + private String isbn = "invalid"; + } + + private static class LengthBean { + + @Length(min = 2, max = 4) + private String length = "666666"; + } + + private static class CodePointLengthBean { + + @CodePointLength(min = 2, max = 4) + private String codePointLength = "666666"; + } + + private static class LuhnCheckBean { + + @LuhnCheck + private String luhnCheck = "4"; + } + + private static class Mod10CheckBean { + + @Mod10Check + private String mod10Check = "4"; + } + + private static class Mod11CheckBean { + + @Mod11Check + private String mod11Check = "4"; + } + + private static class ModCheckBean { + + @ModCheck(multiplier = 2, modType = ModCheck.ModType.MOD10) + private String modCheck = "4"; + } + + private static class HvNotBlankBean { + + @org.hibernate.validator.constraints.NotBlank + private String hvNotBlank = ""; + } + + private static class HvNotEmptyBean { + + @org.hibernate.validator.constraints.NotEmpty + private List hvNotEmpty = Collections.emptyList(); + } + + private static class RangeBean { + + @Range(min = 2, max = 4) + private int range = 6; + } + + private static class SafeHtmlBean { + + @SafeHtml + private String safeHtml = ""; + } + + private static class UniqueElementsBean { + + @UniqueElements + private List uniqueElements = Arrays.asList( "a", "a" ); + } + + private static class URLBean { + + @URL + private String url = "invalid"; + } + + private static class CNPJBean { + + @CNPJ + private String cnpj = "invalid"; + } + + private static class CPFBean { + + @CPF + private String cpf = "invalid"; + } + + private static class TituloEleitoralBean { + + @TituloEleitoral + private String tituloEleitoral = "invalid"; + } + + private static class REGONBean { + + @REGON + private String regon = "invalid"; + } + + private static class NIPBean { + + @NIP + private String nip = "invalid"; + } + + private static class PESELBean { + + @PESEL + private String pesel = "invalid"; + } + + private static class DurationMaxBean { + + @DurationMax(days = 4, hours = 4, minutes = 4, millis = 4, nanos = 4) + private Duration durationMax = Duration.ofDays( 8 ); + } + + private static class DurationMinBean { + + @DurationMin(days = 4, hours = 4, minutes = 4, millis = 4, nanos = 4) + private Duration durationMin = Duration.ofDays( 2 ); + } + + @ScriptAssert(lang = "groovy", script = "_this.scriptAssert") + private static class ScriptAssertBean { + + @SuppressWarnings("unused") + private boolean scriptAssert = false; + } + + private static class ParameterScriptAssertBean { + + @ParameterScriptAssert(lang = "groovy", script = "test") + public boolean doTest(boolean test) { + return test; + } + } +} diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java index b80ccd14f1..4f4b986847 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ExpressionLanguageMessageInterpolationTest.java @@ -42,7 +42,7 @@ public void setUp() { // Create some annotations for testing using AnnotationProxies ConstraintAnnotationDescriptor.Builder notNullAnnotationDescriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( NotNull.class ); notNullDescriptor = new ConstraintDescriptorImpl<>( - new ConstraintHelper(), + ConstraintHelper.forAllBuiltinConstraints(), null, notNullAnnotationDescriptorBuilder.build(), ConstraintLocationKind.FIELD @@ -50,7 +50,7 @@ public void setUp() { ConstraintAnnotationDescriptor.Builder sizeAnnotationDescriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( Size.class ); sizeDescriptor = new ConstraintDescriptorImpl<>( - new ConstraintHelper(), + ConstraintHelper.forAllBuiltinConstraints(), null, sizeAnnotationDescriptorBuilder.build(), ConstraintLocationKind.FIELD diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java index 5636bafda4..09bbbd198b 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/engine/messageinterpolation/ResourceBundleMessageInterpolatorTest.java @@ -52,7 +52,7 @@ public void setUp() { // Create some annotations for testing using AnnotationProxies ConstraintAnnotationDescriptor.Builder descriptorBuilder = new ConstraintAnnotationDescriptor.Builder<>( NotNull.class ); notNullDescriptor = new ConstraintDescriptorImpl<>( - new ConstraintHelper(), + ConstraintHelper.forAllBuiltinConstraints(), null, descriptorBuilder.build(), ConstraintLocationKind.FIELD @@ -60,7 +60,7 @@ public void setUp() { ConstraintAnnotationDescriptor.Builder sizeAnnotationDescriptorBuilder = new ConstraintAnnotationDescriptor.Builder( Size.class ); sizeDescriptor = new ConstraintDescriptorImpl<>( - new ConstraintHelper(), + ConstraintHelper.forAllBuiltinConstraints(), null, sizeAnnotationDescriptorBuilder.build(), ConstraintLocationKind.FIELD @@ -214,7 +214,7 @@ public void testRecursiveMessageInterpolation() { ConstraintAnnotationDescriptor descriptor = descriptorBuilder.build(); ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl( - new ConstraintHelper(), + ConstraintHelper.forAllBuiltinConstraints(), null, descriptorBuilder.build(), ConstraintLocationKind.FIELD @@ -243,7 +243,7 @@ public void testCorrectMessageInterpolationIfParameterCannotBeReplaced() { ConstraintAnnotationDescriptor maxDescriptor = descriptorBuilder.build(); ConstraintDescriptorImpl constraintDescriptor = new ConstraintDescriptorImpl( - new ConstraintHelper(), + ConstraintHelper.forAllBuiltinConstraints(), null, maxDescriptor, ConstraintLocationKind.FIELD diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/ConstraintHelperTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/ConstraintHelperTest.java index 2eb7604455..4708fae57b 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/ConstraintHelperTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/ConstraintHelperTest.java @@ -31,7 +31,7 @@ public class ConstraintHelperTest { @BeforeClass public static void init() { - constraintHelper = new ConstraintHelper(); + constraintHelper = ConstraintHelper.forAllBuiltinConstraints(); } @Test diff --git a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java index cb8a4a04b2..11f91dc1b5 100644 --- a/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/internal/metadata/core/MetaConstraintTest.java @@ -45,7 +45,7 @@ public class MetaConstraintTest { @BeforeClass public void setUp() throws Exception { - constraintHelper = new ConstraintHelper(); + constraintHelper = ConstraintHelper.forAllBuiltinConstraints(); typeResolutionHelper = new TypeResolutionHelper(); valueExtractorManager = new ValueExtractorManager( Collections.emptySet() ); constraintValidatorManager = new ConstraintValidatorManagerImpl( new ConstraintValidatorFactoryImpl(), getDummyConstraintValidatorInitializationContext() ); diff --git a/engine/src/test/java/org/hibernate/validator/test/predefinedscope/PredefinedScopeValidatorFactoryTest.java b/engine/src/test/java/org/hibernate/validator/test/predefinedscope/PredefinedScopeValidatorFactoryTest.java index 2e94a98448..d92a8362d5 100644 --- a/engine/src/test/java/org/hibernate/validator/test/predefinedscope/PredefinedScopeValidatorFactoryTest.java +++ b/engine/src/test/java/org/hibernate/validator/test/predefinedscope/PredefinedScopeValidatorFactoryTest.java @@ -14,6 +14,7 @@ import java.lang.annotation.ElementType; import java.util.AbstractCollection; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -245,6 +246,7 @@ public void testBeanMetaDataClassNormalizer() { ValidatorFactory validatorFactory = Validation.byProvider( PredefinedScopeHibernateValidator.class ) .configure() + .builtinConstraints( new HashSet<>( Arrays.asList( Email.class.getName(), NotNull.class.getName() ) ) ) .initializeBeanMetaData( beanMetaDataToInitialize ) .locales( Collections.singleton( Locale.getDefault() ) ) .beanMetaDataClassNormalizer( new MyProxyInterfaceBeanMetaDataClassNormalizer() ) @@ -266,6 +268,7 @@ public void validatorSpecificTraversableResolver() { ValidatorFactory validatorFactory = Validation.byProvider( PredefinedScopeHibernateValidator.class ) .configure() + .builtinConstraints( new HashSet<>( Arrays.asList( Email.class.getName(), NotNull.class.getName() ) ) ) .initializeBeanMetaData( beanMetaDataToInitialize ) .buildValidatorFactory(); @@ -290,6 +293,7 @@ public void variousObjectTypes() { ValidatorFactory validatorFactory = Validation.byProvider( PredefinedScopeHibernateValidator.class ) .configure() + .builtinConstraints( new HashSet<>( Arrays.asList( Email.class.getName(), NotNull.class.getName() ) ) ) .initializeBeanMetaData( beanMetaDataToInitialize ) .buildValidatorFactory(); @@ -330,6 +334,7 @@ private static ValidatorFactory getValidatorFactory() { return Validation.byProvider( PredefinedScopeHibernateValidator.class ) .configure() + .builtinConstraints( new HashSet<>( Arrays.asList( Email.class.getName(), NotNull.class.getName() ) ) ) .initializeBeanMetaData( beanMetaDataToInitialize ) .buildValidatorFactory(); } @@ -344,6 +349,7 @@ private static ValidatorFactory getValidatorFactoryWithInitializedLocale(Locale return Validation.byProvider( PredefinedScopeHibernateValidator.class ) .configure() + .builtinConstraints( new HashSet<>( Arrays.asList( Email.class.getName(), NotNull.class.getName() ) ) ) .initializeBeanMetaData( beanMetaDataToInitialize ) .locales( Collections.singleton( locale ) ) .buildValidatorFactory(); diff --git a/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java b/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java index 1978dc0c6b..86ab72ad86 100644 --- a/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java +++ b/engine/src/test/java/org/hibernate/validator/testutils/ConstraintValidatorInitializationHelper.java @@ -34,7 +34,7 @@ */ public class ConstraintValidatorInitializationHelper { - private static final ConstraintHelper CONSTRAINT_HELPER = new ConstraintHelper(); + private static final ConstraintHelper CONSTRAINT_HELPER = ConstraintHelper.forAllBuiltinConstraints(); private static final HibernateConstraintValidatorInitializationContext DUMMY_CONSTRAINT_VALIDATOR_INITIALIZATION_CONTEXT = getConstraintValidatorInitializationContext( new DefaultScriptEvaluatorFactory( null ), DefaultClockProvider.INSTANCE, Duration.ZERO ); @@ -73,7 +73,7 @@ public static HibernateConstraintValidatorInitializationContext getDummyConstrai } public static ConstraintCreationContext getDummyConstraintCreationContext() { - return new ConstraintCreationContext( new ConstraintHelper(), + return new ConstraintCreationContext( ConstraintHelper.forAllBuiltinConstraints(), new ConstraintValidatorManagerImpl( new ConstraintValidatorFactoryImpl(), getDummyConstraintValidatorInitializationContext() ), new TypeResolutionHelper(), new ValueExtractorManager( Collections.emptySet() ) );