/** * Process the given {@code method} and {@code validationMethod} on given {@code clazz} and determine whether this method * should be validated or not. * * @param clazz class on which the method will be invoked. * @param method method to be examined. * @param validationMethod method used for cache. * @param forceValidation forces validation of a getter if no {@link ValidateOnExecution} annotation is present. */ private void processMethod(final Class<?> clazz, final Method method, final Method validationMethod, final boolean forceValidation) { final Deque<Class<?>> hierarchy = getValidationClassHierarchy(clazz); Boolean validateMethod = processAnnotation(method, hierarchy, checkOverrides); if (validateMethod != null) { validateMethodCache.putIfAbsent(validationMethod, validateMethod); validateGetterCache.putIfAbsent(validationMethod, validateMethod); } // Return value from validation.xml. if (!validateMethodCache.containsKey(validationMethod)) { final Set<ExecutableType> defaultValidatedExecutableTypes = config.getBootstrapConfiguration() .getDefaultValidatedExecutableTypes(); validateMethod = validateMethod(method, false, defaultValidatedExecutableTypes); validateGetterCache.putIfAbsent(validationMethod, validateMethod || forceValidation); // When validateMethod is called and no ValidateOnExecution annotation is present we want to validate getter resource // methods by default (see SPEC). validateMethodCache.putIfAbsent(validationMethod, ReflectionHelper.isGetter(validationMethod) || validateMethod); } }
@Override public void validateResult(final Object resource, final Invocable resourceMethod, final Object result) { if (configuration.getBootstrapConfiguration().isExecutableValidationEnabled()) { final Set<ConstraintViolation<Object>> constraintViolations = new HashSet<>(); final Method handlingMethod = resourceMethod.getHandlingMethod(); final BeanDescriptor beanDescriptor = getConstraintsForClass(resource.getClass()); final MethodDescriptor methodDescriptor = beanDescriptor.getConstraintsForMethod(handlingMethod.getName(), handlingMethod.getParameterTypes()); final Method definitionMethod = resourceMethod.getDefinitionMethod(); if (methodDescriptor != null && methodDescriptor.hasConstrainedReturnValue() && validateOnExecutionHandler.validateMethod(resource.getClass(), definitionMethod, handlingMethod)) { constraintViolations.addAll(forExecutables().validateReturnValue(resource, handlingMethod, result)); if (result instanceof Response) { constraintViolations.addAll(forExecutables().validateReturnValue(resource, handlingMethod, ((Response) result).getEntity())); } } if (!constraintViolations.isEmpty()) { throw new ConstraintViolationException(constraintViolations); } } } }
/** * Create traversable resolver able to process {@link javax.validation.executable.ValidateOnExecution} annotation on * beans. * * @param delegate resolver to be wrapped into the custom traversable resolver. * @param handler handler to create traversable resolver for. * @return custom traversable resolver. */ private ValidateOnExecutionTraversableResolver getTraversableResolver(TraversableResolver delegate, final ValidateOnExecutionHandler handler) { if (delegate == null) { delegate = validationConfig.getDefaultTraversableResolver(); } final boolean validationEnabled = validationConfig.getBootstrapConfiguration().isExecutableValidationEnabled(); final ValidateOnExecutionTraversableResolver traversableResolver = new ValidateOnExecutionTraversableResolver(delegate, handler, validationEnabled); return resourceContext.initResource(traversableResolver); }
@Override public void onValidate(final ValidationInterceptorContext ctx) { final Object resource = ctx.getResource(); final Invocable resourceMethod = ctx.getInvocable(); final Object[] args = ctx.getArgs(); final Set<ConstraintViolation<Object>> constraintViolations = new HashSet<>(); final BeanDescriptor beanDescriptor = getConstraintsForClass(resource.getClass()); // Resource validation. if (beanDescriptor.isBeanConstrained()) { constraintViolations.addAll(validate(resource)); } if (resourceMethod != null && configuration.getBootstrapConfiguration().isExecutableValidationEnabled()) { final Method handlingMethod = resourceMethod.getHandlingMethod(); // Resource method validation - input parameters. final MethodDescriptor methodDescriptor = beanDescriptor.getConstraintsForMethod(handlingMethod.getName(), handlingMethod.getParameterTypes()); if (methodDescriptor != null && methodDescriptor.hasConstrainedParameters() && validateOnExecutionHandler.validateMethod(resource.getClass(), resourceMethod.getDefinitionMethod(), resourceMethod.getHandlingMethod())) { constraintViolations.addAll(forExecutables().validateParameters(resource, handlingMethod, args)); } } if (!constraintViolations.isEmpty()) { throw new ConstraintViolationException(constraintViolations); } }
private Set<ValueExtractorDescriptor> createValidationXmlValueExtractors(Configuration<?> config) { BootstrapConfiguration bootstrapConfiguration = config.getBootstrapConfiguration(); Set<String> valueExtractorFqcns = bootstrapConfiguration.getValueExtractorClassNames(); @SuppressWarnings("unchecked") Set<ValueExtractorDescriptor> valueExtractorDescriptors = valueExtractorFqcns.stream() .map( fqcn -> createInstance( (Class<? extends ValueExtractor<?>>) run( LoadClass.action( fqcn, null ) ) ) ) .map( ve -> new ValueExtractorDescriptor( ve ) ) .collect( Collectors.toSet() ); return valueExtractorDescriptors; }
BootstrapConfiguration getConfig() { BootstrapConfiguration tmpConfig = bootstrapConfiguration; if (tmpConfig == null) { synchronized (RD_LOCK) { tmpConfig = bootstrapConfiguration; if (tmpConfig == null) { config = Validation.byDefaultProvider().configure(); bootstrapConfiguration = tmpConfig = config.getBootstrapConfiguration(); } } } return tmpConfig; }
private TraversableResolver createTraversableResolver(Configuration<?> config) { BootstrapConfiguration bootstrapConfiguration = config.getBootstrapConfiguration(); String traversableResolverFqcn = bootstrapConfiguration.getTraversableResolverClassName(); if ( traversableResolverFqcn == null ) { return config.getDefaultTraversableResolver(); } @SuppressWarnings("unchecked") Class<? extends TraversableResolver> traversableResolverClass = (Class<? extends TraversableResolver>) run( LoadClass.action( traversableResolverFqcn, null ) ); return createInstance( traversableResolverClass ); }
private MessageInterpolator createMessageInterpolator(Configuration<?> config) { BootstrapConfiguration bootstrapConfiguration = config.getBootstrapConfiguration(); String messageInterpolatorFqcn = bootstrapConfiguration.getMessageInterpolatorClassName(); if ( messageInterpolatorFqcn == null ) { return config.getDefaultMessageInterpolator(); } @SuppressWarnings("unchecked") Class<? extends MessageInterpolator> messageInterpolatorClass = (Class<? extends MessageInterpolator>) run( LoadClass.action( messageInterpolatorFqcn, null ) ); return createInstance( messageInterpolatorClass ); }
private ParameterNameProvider createParameterNameProvider(Configuration<?> config) { BootstrapConfiguration bootstrapConfiguration = config.getBootstrapConfiguration(); String parameterNameProviderFqcn = bootstrapConfiguration.getParameterNameProviderClassName(); if ( parameterNameProviderFqcn == null ) { return config.getDefaultParameterNameProvider(); } @SuppressWarnings("unchecked") Class<? extends ParameterNameProvider> parameterNameProviderClass = (Class<? extends ParameterNameProvider>) run( LoadClass.action( parameterNameProviderFqcn, null ) ); return createInstance( parameterNameProviderClass ); }
private ClockProvider createClockProvider(Configuration<?> config) { BootstrapConfiguration bootstrapConfiguration = config.getBootstrapConfiguration(); String clockProviderFqcn = bootstrapConfiguration.getClockProviderClassName(); if ( clockProviderFqcn == null ) { return config.getDefaultClockProvider(); } @SuppressWarnings("unchecked") Class<? extends ClockProvider> clockProviderClass = (Class<? extends ClockProvider>) run( LoadClass.action( clockProviderFqcn, null ) ); return createInstance( clockProviderClass ); }
private ConstraintValidatorFactory createConstraintValidatorFactory(Configuration<?> config) { BootstrapConfiguration configSource = config.getBootstrapConfiguration(); String constraintValidatorFactoryFqcn = configSource.getConstraintValidatorFactoryClassName(); if ( constraintValidatorFactoryFqcn == null ) { // use default return createInstance( InjectingConstraintValidatorFactory.class ); } @SuppressWarnings("unchecked") Class<? extends ConstraintValidatorFactory> constraintValidatorFactoryClass = (Class<? extends ConstraintValidatorFactory>) run( LoadClass.action( constraintValidatorFactoryFqcn, null ) ); return createInstance( constraintValidatorFactoryClass ); }
public ValidationExtension() { Configuration<?> config = Validation.byDefaultProvider().configure(); // we use the default ParameterNameProvider here as we cannot use the injected one // as it hasn't been turned into a managed bean yet and might not be able to // return a parameter name. At this stage, we don't care about the parameter names. config.parameterNameProvider( config.getDefaultParameterNameProvider() ); BootstrapConfiguration bootstrap = config.getBootstrapConfiguration(); globalExecutableTypes = bootstrap.getDefaultValidatedExecutableTypes(); isExecutableValidationEnabled = bootstrap.isExecutableValidationEnabled(); validatorFactory = config.buildValidatorFactory(); validator = validatorFactory.getValidator(); getterPropertySelectionStrategyHelper = GetterPropertySelectionStrategyHelper.forValidationFactory( validatorFactory ); executableHelper = new ExecutableHelper( new TypeResolutionHelper() ); }
@Test @SpecAssertion(section = Sections.XML_CONFIG_XSD, id = "a") public void testValidationXmlVersion10() { Configuration<?> config = TestUtil.getConfigurationUnderTest(); assertEquals( config.getBootstrapConfiguration().getMessageInterpolatorClassName(), "org.hibernate.beanvalidation.tck.tests.xmlconfiguration.versioning.DummyMessageInterpolator", "Wrong message interpolator class name." ); } }
@Test @SpecAssertion(section = Sections.XML_CONFIG_XSD, id = "a") public void testValidationXmlVersion11() { Configuration<?> config = TestUtil.getConfigurationUnderTest(); assertEquals( config.getBootstrapConfiguration().getMessageInterpolatorClassName(), "org.hibernate.beanvalidation.tck.tests.xmlconfiguration.versioning.DummyMessageInterpolator", "Wrong message interpolator class name." ); } }
@Test @SpecAssertion(section = Sections.XML_CONFIG_XSD, id = "a") public void testValidationXmlVersion20() { Configuration<?> config = TestUtil.getConfigurationUnderTest(); assertEquals( config.getBootstrapConfiguration().getClockProviderClassName(), "org.hibernate.beanvalidation.tck.tests.xmlconfiguration.versioning.DummyClockProvider", "Wrong clock provider class name." ); } }
private Set<ValueExtractorDescriptor> createValidationXmlValueExtractors(Configuration<?> config) { BootstrapConfiguration bootstrapConfiguration = config.getBootstrapConfiguration(); Set<String> valueExtractorFqcns = bootstrapConfiguration.getValueExtractorClassNames(); @SuppressWarnings("unchecked") Set<ValueExtractorDescriptor> valueExtractorDescriptors = valueExtractorFqcns.stream() .map( fqcn -> createInstance( (Class<? extends ValueExtractor<?>>) run( LoadClass.action( fqcn, null ) ) ) ) .map( ve -> new ValueExtractorDescriptor( ve ) ) .collect( Collectors.toSet() ); return valueExtractorDescriptors; }
@Test(expectedExceptions = ValidationException.class) @SpecAssertion(section = Sections.VALIDATIONAPI_BOOTSTRAPPING_CONFIGURATION, id = "f") public void testEmptyExecutableTypesCauseValidationException() { BootstrapConfiguration bootstrapConfiguration = TestUtil.getConfigurationUnderTest() .getBootstrapConfiguration(); bootstrapConfiguration.getDefaultValidatedExecutableTypes(); } }
@Test @SpecAssertion(section = Sections.VALIDATIONAPI_BOOTSTRAPPING_CONFIGURATION, id = "f") @SpecAssertion(section = Sections.VALIDATIONAPI_BOOTSTRAPPING_XMLCONFIGURATION, id = "q") @SpecAssertion(section = Sections.INTEGRATION_GENERAL_EXECUTABLE, id = "i") public void testGetDefaultValidatedExecutableTypesStripsNONEIfNONEIsContained() { BootstrapConfiguration bootstrapConfiguration = TestUtil.getConfigurationUnderTest() .getBootstrapConfiguration(); assertNotNull( bootstrapConfiguration ); assertEquals( bootstrapConfiguration.getDefaultValidatedExecutableTypes(), EnumSet.of( ExecutableType.CONSTRUCTORS, ExecutableType.GETTER_METHODS, ExecutableType.NON_GETTER_METHODS ) ); } }
public BValExtension() { // read the config, could be done in a quicker way but this let us get defaults without duplicating code config = Validation.byDefaultProvider().configure(); try { final BootstrapConfiguration bootstrap = config.getBootstrapConfiguration(); globalExecutableTypes = ExecutableTypes.interpret(bootstrap.getDefaultValidatedExecutableTypes()); isExecutableValidationEnabled = bootstrap.isExecutableValidationEnabled(); } catch (final Exception e) { // custom providers can throw an exception LOGGER.log(Level.SEVERE, e.getMessage(), e); globalExecutableTypes = Collections.emptySet(); isExecutableValidationEnabled = false; } }
public BValExtension() { // read the config, could be done in a quicker way but this let us get defaults without duplicating code config = Validation.byDefaultProvider().configure(); try { final BootstrapConfiguration bootstrap = config.getBootstrapConfiguration(); globalExecutableTypes = ExecutableTypes.interpret(bootstrap.getDefaultValidatedExecutableTypes()); isExecutableValidationEnabled = bootstrap.isExecutableValidationEnabled(); } catch (final Exception e) { // custom providers can throw an exception LOGGER.log(Level.SEVERE, e.getMessage(), e); globalExecutableTypes = Collections.emptySet(); isExecutableValidationEnabled = false; } }