Skip to content
Permalink
Browse files
lazily load the validator factory and validator for the cdi extension…
… - note: we can surely lazy load the config as well if needed
  • Loading branch information
rmannibucau authored and mbenson committed Oct 16, 2018
1 parent e5e22d3 commit 2f193bc31133dba16af2174bede156970ea647fa
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 42 deletions.
@@ -52,6 +52,7 @@

import org.apache.bval.jsr.ConfigurationImpl;
import org.apache.bval.jsr.util.ExecutableTypes;
import org.apache.bval.util.Lazy;
import org.apache.bval.util.Validate;

/**
@@ -73,8 +74,8 @@ public static void setAnnotatedTypeFilter(AnnotatedTypeFilter annotatedTypeFilte
private boolean validatorFactoryFound = Boolean.getBoolean("bval.in-container");

private final Configuration<?> config;
private ValidatorFactory factory;
private Validator validator;
private Lazy<ValidatorFactory> factory;
private Lazy<Validator> validator;

private Set<ExecutableType> globalExecutableTypes;
private boolean isExecutableValidationEnabled;
@@ -106,9 +107,9 @@ private void ensureFactoryValidator() {
((ConfigurationImpl) config).deferBootstrapOverrides();
}
if (factory == null) {
factory = config.buildValidatorFactory();
factory = new Lazy<>(config::buildValidatorFactory);
}
validator = factory.getValidator();
validator = new Lazy<>(() -> factory.get().getValidator());
}

public Set<ExecutableType> getGlobalExecutableTypes() {
@@ -136,7 +137,7 @@ public <A> void processAnnotatedType(final @Observes ProcessAnnotatedType<A> pat
try {
ensureFactoryValidator();
try {
final BeanDescriptor classConstraints = validator.getConstraintsForClass(javaClass);
final BeanDescriptor classConstraints = validator.get().getConstraintsForClass(javaClass);

final boolean validConstructors = globalExecutableTypes.contains(ExecutableType.CONSTRUCTORS)
&& !classConstraints.getConstrainedConstructors().isEmpty();
@@ -189,37 +190,30 @@ public <A> void processBean(final @Observes ProcessBean<A> processBeanEvent) {
}

public void addBValBeans(final @Observes AfterBeanDiscovery afterBeanDiscovery, final BeanManager beanManager) {
if (factory != null) { // cleanup cache used to discover ValidateOnException before factory is recreated
factory.close();
if (factory != null && factory.optional().isPresent()) { // cleanup cache used to discover ValidateOnException before factory is recreated
factory.get().close();
}
if (config instanceof ConfigurationImpl) {
((ConfigurationImpl) config).releaseDeferredBootstrapOverrides();
}
if (!validatorFactoryFound) {
try { // recreate the factory
afterBeanDiscovery.addBean(new ValidatorFactoryBean(factory = config.buildValidatorFactory()));
factory = new Lazy<>(config::buildValidatorFactory);
afterBeanDiscovery.addBean(new ValidatorFactoryBean(factory));
validatorFactoryFound = true;
} catch (final ValidationException ve) {
//throw ve;
} catch (final Exception e) { // can throw an exception with custom providers
if (e instanceof ValidationException) {
throw e;
}
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
}
if (!validatorFound) {
if (!validatorFound && validatorFactoryFound) {
try {
if (validatorFactoryFound) {
factory = config.buildValidatorFactory();
} // else fresh factory already created in previous if
if (factory != null) { // happens in TCKS
afterBeanDiscovery.addBean(new ValidatorBean(factory, factory.getValidator()));
validatorFound = true;
}
} catch (final Exception e) { // getValidator can throw an exception with custom providers
if (e instanceof ValidationException) {
throw e;
}
afterBeanDiscovery.addBean(new ValidatorBean(factory, null));
afterBeanDiscovery.addBean(new ValidatorBean(() -> CDI.current().select(ValidatorFactory.class).get().getValidator()));
validatorFound = true;
} catch (final ValidationException ve) {
throw ve;
} catch (final Exception e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
}
@@ -243,7 +237,7 @@ public static <T> Releasable<T> inject(final Class<T> clazz) {
it.inject(instance, context);
it.postConstruct(instance);

return new Releasable<T>(context, it, instance);
return new Releasable<>(context, it, instance);
} catch (final Exception | NoClassDefFoundError error) {
// no-op
}
@@ -24,24 +24,22 @@
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.PassivationCapable;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;

/**
* {@link Validator} CDI {@link Bean}.
*/
public class ValidatorBean implements Bean<Validator>, PassivationCapable {
private final Set<Type> types;
private final Set<Annotation> qualifiers;
private final ValidatorFactory factory;
private volatile Validator instance;
private final Supplier<Validator> instance;

public ValidatorBean(final ValidatorFactory factory, final Validator validator) {
this.factory = factory;
public ValidatorBean(final Supplier<Validator> validator) {
this.instance = validator;

final Set<Type> t = new HashSet<>();
@@ -102,14 +100,7 @@ public boolean isAlternative() {

@Override
public Validator create(final CreationalContext<Validator> context) {
if (instance == null) {
synchronized (this) {
if (instance == null) {
instance = factory.getValidator();
}
}
}
return instance;
return instance == null ? null : instance.get();
}

@Override
@@ -29,16 +29,17 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;

/**
* {@link ValidatorFactory} CDI {@link Bean}.
*/
public class ValidatorFactoryBean implements Bean<ValidatorFactory>, PassivationCapable {
private final Set<Type> types;
private final Set<Annotation> qualifiers;
private final ValidatorFactory instance;
private final Supplier<ValidatorFactory> instance;

public ValidatorFactoryBean(final ValidatorFactory validatorFactory) {
public ValidatorFactoryBean(final Supplier<ValidatorFactory> validatorFactory) {
this.instance = validatorFactory;

final Set<Type> t = new HashSet<>();
@@ -99,7 +100,7 @@ public boolean isAlternative() {

@Override
public ValidatorFactory create(final CreationalContext<ValidatorFactory> context) {
return instance;
return instance.get();
}

@Override
@@ -22,7 +22,7 @@ think to add -Dvalidation.provider=org.apache.bval.jsr.ApacheValidationProvider
<test name="tmp">
<classes>
<!-- <class name="org.hibernate.beanvalidation.tck.tests.xmlconfiguration.groupconversion.containerelement.XmlBasedContainerElementGroupConversionValidationTest"/> -->
<class name="org.hibernate.beanvalidation.tck.tests.validation.CustomPropertyPathTest"/>
<class name="org.hibernate.beanvalidation.tck.tests.bootstrap.BootstrapConfigurationTest"/>
<!--
<class name="org.hibernate.beanvalidation.tck.tests.util.ConstraintViolationAssertTest"/>
-->

0 comments on commit 2f193bc

Please sign in to comment.