You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2019/05/13 11:34:01 UTC
svn commit: r1859181 [1/2] - in /tomee/deps/branches/bval-2: bundle/src/
bval-jsr/src/main/appended-resources/
bval-jsr/src/main/java/org/apache/bval/cdi/
bval-jsr/src/main/java/org/apache/bval/el/
bval-jsr/src/main/java/org/apache/bval/jsr/ bval-jsr/s...
Author: dblevins
Date: Mon May 13 11:34:00 2019
New Revision: 1859181
URL: http://svn.apache.org/viewvc?rev=1859181&view=rev
Log:
Bring up to date with bval 2.0.3-SNAPSHOT
git hash: 1691eef8ce78df9d1b5d7467132e1cb66b556637
Added:
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CollectionSet.java
Removed:
tomee/deps/branches/bval-2/bundle/src/
tomee/deps/branches/bval-2/bval-jsr/src/main/appended-resources/
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LRUCache.java
Modified:
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/BeanD.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/CascadableContainerD.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ExecutableD.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/PropertyD.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupStrategy.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/HierarchyBuilder.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxy.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxyBuilder.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathNavigation.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java
tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java
tomee/deps/branches/bval-2/bval-jsr/src/test/java/org/apache/bval/jsr/LiskovTest.java
tomee/deps/branches/bval-2/bval-jsr/src/test/java/org/apache/bval/jsr/example/Book.java
tomee/deps/branches/bval-2/src/site/site.xml
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java Mon May 13 11:34:00 2019
@@ -18,18 +18,22 @@
*/
package org.apache.bval.cdi;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.stream.Stream;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
-import javax.enterprise.inject.spi.AnnotatedCallable;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
@@ -41,14 +45,14 @@ import javax.enterprise.inject.spi.Proce
import javax.enterprise.inject.spi.ProcessBean;
import javax.validation.BootstrapConfiguration;
import javax.validation.Configuration;
+import javax.validation.Constraint;
+import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.executable.ExecutableType;
import javax.validation.executable.ValidateOnExecution;
-import javax.validation.metadata.BeanDescriptor;
-import javax.validation.metadata.MethodType;
import org.apache.bval.jsr.ConfigurationImpl;
import org.apache.bval.jsr.util.ExecutableTypes;
@@ -75,11 +79,13 @@ public class BValExtension implements Ex
private final Configuration<?> config;
private Lazy<ValidatorFactory> factory;
- private Lazy<Validator> validator;
private Set<ExecutableType> globalExecutableTypes;
private boolean isExecutableValidationEnabled;
+ private final Collection<Class<?>> potentiallyBValAnnotation = new HashSet<>();
+ private final Collection<Class<?>> notBValAnnotation = new HashSet<>();
+
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 {
@@ -97,21 +103,6 @@ public class BValExtension implements Ex
}
}
- // lazily to get a small luck to have CDI in place
- private void ensureFactoryValidator() {
- if (validator != null) {
- return;
- }
- if (config instanceof ConfigurationImpl) {
- // ignore parts of the config relying on CDI since we didn't start yet
- ((ConfigurationImpl) config).deferBootstrapOverrides();
- }
- if (factory == null) {
- factory = new Lazy<>(config::buildValidatorFactory);
- }
- validator = new Lazy<>(() -> factory.get().getValidator());
- }
-
public Set<ExecutableType> getGlobalExecutableTypes() {
return globalExecutableTypes;
}
@@ -133,43 +124,27 @@ public class BValExtension implements Ex
}
final Class<A> javaClass = annotatedType.getJavaClass();
final int modifiers = javaClass.getModifiers();
- if (!javaClass.isInterface() && !Modifier.isFinal(modifiers) && !Modifier.isAbstract(modifiers)) {
+ if (!javaClass.isInterface() && !javaClass.isAnonymousClass() && !Modifier.isFinal(modifiers) && !Modifier.isAbstract(modifiers)) {
try {
- ensureFactoryValidator();
- try {
- final BeanDescriptor classConstraints = validator.get().getConstraintsForClass(javaClass);
-
- final boolean validConstructors = globalExecutableTypes.contains(ExecutableType.CONSTRUCTORS)
- && !classConstraints.getConstrainedConstructors().isEmpty();
- final boolean validBusinessMethods =
- globalExecutableTypes.contains(ExecutableType.NON_GETTER_METHODS)
- && !classConstraints.getConstrainedMethods(MethodType.NON_GETTER).isEmpty();
- final boolean validGetterMethods = globalExecutableTypes.contains(ExecutableType.GETTER_METHODS)
- && !classConstraints.getConstrainedMethods(MethodType.GETTER).isEmpty();
-
- if (annotatedType.isAnnotationPresent(ValidateOnExecution.class)
- || hasValidationAnnotation(annotatedType.getMethods())
- || hasValidationAnnotation(annotatedType.getConstructors()) || validConstructors
- || validBusinessMethods || validGetterMethods) {
- pat.setAnnotatedType(new BValAnnotatedType<>(annotatedType));
- }
- } catch (final NoClassDefFoundError ncdfe) {
- // skip
+ if (hasValidation(annotatedType)
+ || hasValidationAnnotation(annotatedType.getMethods())
+ || hasValidationAnnotation(annotatedType.getConstructors())
+ || Stream.concat(annotatedType.getMethods().stream(), annotatedType.getConstructors().stream())
+ .flatMap(it -> it.getParameters().stream())
+ .anyMatch(this::hasValidation)) {
+ pat.setAnnotatedType(new BValAnnotatedType<>(annotatedType));
}
} catch (final Exception e) {
if (e instanceof ValidationException) {
throw e;
}
LOGGER.log(Level.INFO, e.getMessage());
+ } catch (final NoClassDefFoundError ncdfe) {
+ // skip
}
}
}
- private static <A> boolean hasValidationAnnotation(
- final Collection<? extends AnnotatedCallable<? super A>> methods) {
- return methods.stream().anyMatch(m -> m.isAnnotationPresent(ValidateOnExecution.class));
- }
-
public <A> void processBean(final @Observes ProcessBean<A> processBeanEvent) {
if (validatorFound && validatorFactoryFound) {
return;
@@ -219,6 +194,73 @@ public class BValExtension implements Ex
}
}
+ public void afterStart(@Observes final AfterDeploymentValidation clearEvent) {
+ potentiallyBValAnnotation.clear();
+ notBValAnnotation.clear();
+ }
+
+ private boolean hasValidationAnnotation(final Collection<? extends Annotated> annotateds) {
+ return annotateds.stream().anyMatch(this::hasValidation);
+ }
+
+ private boolean hasValidation(final Annotated m) {
+ return m.getAnnotations().stream()
+ .anyMatch(it -> {
+ final Class<? extends Annotation> type = it.annotationType();
+ if (type == ValidateOnExecution.class || type == Valid.class) {
+ return true;
+ }
+ if (isSkippedAnnotation(type)) {
+ return false;
+ }
+ if (type.getName().startsWith("javax.validation.constraints")) {
+ return true;
+ }
+ if (notBValAnnotation.contains(type)) { // more likely so faster first
+ return false;
+ }
+ if (potentiallyBValAnnotation.contains(type)) {
+ return true;
+ }
+ cacheIsBvalAnnotation(type);
+ return potentiallyBValAnnotation.contains(type);
+ });
+ }
+
+ private boolean isSkippedAnnotation(final Class<? extends Annotation> type) {
+ if (type.getName().startsWith("java.")) {
+ return true;
+ }
+ if (type.getName().startsWith("javax.enterprise.")) {
+ return true;
+ }
+ if (type.getName().startsWith("javax.inject.")) {
+ return true;
+ }
+ return false;
+ }
+
+ private void cacheIsBvalAnnotation(final Class<? extends Annotation> type) {
+ if (flattenAnnotations(type, new HashSet<>()).anyMatch(it -> it == Constraint.class)) {
+ potentiallyBValAnnotation.add(type);
+ } else {
+ notBValAnnotation.add(type);
+ }
+ }
+
+ private Stream<Class<?>> flattenAnnotations(final Class<? extends Annotation> type, final Set<Class<?>> seen) {
+ seen.add(type);
+ return Stream.of(type)
+ .flatMap(it -> Stream.concat(
+ Stream.of(it),
+ Stream.of(it.getAnnotations())
+ .map(Annotation::annotationType)
+ .distinct()
+ .filter(a -> !isSkippedAnnotation(a))
+ .filter(seen::add)
+ .flatMap(a -> flattenAnnotations(a, seen))));
+ }
+
/**
* Request that an instance of the specified type be provided by the container.
* @param clazz
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java Mon May 13 11:34:00 2019
@@ -31,6 +31,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.function.BiPredicate;
import javax.annotation.Priority;
@@ -96,6 +97,7 @@ public class BValInterceptor implements
private BValExtension globalConfiguration;
private transient volatile ExecutableValidator executableValidator;
+ private transient volatile ConcurrentMap<Class<?>, Class<?>> classMapping;
@SuppressWarnings({ "unchecked", "rawtypes" })
@AroundConstruct // TODO: see previous one
@@ -134,7 +136,7 @@ public class BValInterceptor implements
@AroundInvoke
public Object invoke(final InvocationContext context) throws Exception {
final Method method = context.getMethod();
- final Class<?> targetClass = Proxies.classFor(context.getTarget().getClass());
+ final Class<?> targetClass = getTargetClass(context);
if (!isExecutableValidated(targetClass, method, this::computeIsMethodValidated)) {
return context.proceed();
@@ -157,7 +159,7 @@ public class BValInterceptor implements
}
final Object result = context.proceed();
- if (constraintsForMethod.hasConstrainedReturnValue()) {
+ if (!method.getReturnType().equals(Void.TYPE) && constraintsForMethod.hasConstrainedReturnValue()) {
final Set<ConstraintViolation<Object>> violations =
executableValidator.validateReturnValue(context.getTarget(), method, result);
if (!violations.isEmpty()) {
@@ -167,8 +169,24 @@ public class BValInterceptor implements
return result;
}
- private <T> boolean isConstructorValidated(final Constructor<T> constructor)
- {
+ private Class<?> getTargetClass(final InvocationContext context) {
+ final Class<?> key = context.getTarget().getClass();
+ if (classMapping == null) {
+ synchronized (this) {
+ if (classMapping == null) {
+ classMapping = new ConcurrentHashMap<>();
+ }
+ }
+ }
+ Class<?> mapped = classMapping.get(key);
+ if (mapped == null) {
+ mapped = Proxies.classFor(key);
+ classMapping.putIfAbsent(key, mapped);
+ }
+ return mapped;
+ }
+
+ private <T> boolean isConstructorValidated(final Constructor<T> constructor) {
return isExecutableValidated(constructor.getDeclaringClass(), constructor, this::computeIsConstructorValidated);
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java Mon May 13 11:34:00 2019
@@ -61,8 +61,9 @@ public final class ELFacade implements M
@Override
public String interpolate(final String message, final Map<String, Object> annotationParameters,
final Object validatedValue) {
- try {
- if (EvaluationType.IMMEDIATE.regex.matcher(message).find()) {
+ // BVAL-170: simple pre-check to improve performance
+ if (message.contains("${")) {
+ try {
final BValELContext context = new BValELContext();
final VariableMapper variables = context.getVariableMapper();
annotationParameters.forEach(
@@ -75,11 +76,10 @@ public final class ELFacade implements M
return expressionFactory.createValueExpression(context,
EvaluationType.DEFERRED.regex.matcher(message).replaceAll("\\$0"), String.class).getValue(context)
.toString();
+ } catch (final Exception e) {
+ // no-op
}
- } catch (final Exception e) {
- // no-op
}
-
return message;
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java Mon May 13 11:34:00 2019
@@ -18,7 +18,11 @@
*/
package org.apache.bval.jsr;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Supplier;
+
import javax.validation.ClockProvider;
+import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
@@ -27,6 +31,7 @@ import javax.validation.Validator;
import javax.validation.ValidatorContext;
import javax.validation.valueextraction.ValueExtractor;
+import org.apache.bval.jsr.descriptor.ConstraintD;
import org.apache.bval.jsr.descriptor.DescriptorManager;
import org.apache.bval.jsr.groups.GroupsComputer;
import org.apache.bval.jsr.valueextraction.ValueExtractors;
@@ -185,4 +190,18 @@ public class ApacheFactoryContext implem
public ApacheValidatorFactory getFactory() {
return factory;
}
+
+ public ConstraintValidator getOrComputeConstraintValidator(final ConstraintD<?> constraint, final Supplier<ConstraintValidator> computer) {
+ final ConcurrentMap<ConstraintD<?>, ConstraintValidator<?, ?>> constraintsCache = factory.getConstraintsCache().getValidators();
+ final ConstraintValidator<?, ?> validator = constraintsCache.get(constraint); // constraints are cached so we can query per instance
+ if (validator != null) {
+ return validator;
+ }
+ ConstraintValidator<?, ?> instance = computer.get();
+ final ConstraintValidator<?, ?> existing = constraintsCache.putIfAbsent(constraint, instance);
+ if (existing != null) {
+ instance = existing;
+ }
+ return instance;
+ }
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java Mon May 13 11:34:00 2019
@@ -46,11 +46,6 @@ public interface ApacheValidatorConfigur
String VALIDATOR_FACTORY_CLASSNAME = "apache.bval.validator-factory-classname";
/**
- * Size to use for caching of constraint-related information. Default is {@code 50}.
- */
- String CONSTRAINTS_CACHE_SIZE = "apache.bval.constraints-cache-size";
-
- /**
* Specifies whether EL evaluation is permitted in non-default message
* templates. By default this feature is disabled; if you enable it you
* should ensure that no constraint validator builds violations using
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java Mon May 13 11:34:00 2019
@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import javax.validation.ClockProvider;
@@ -100,6 +101,7 @@ public class ApacheValidatorFactory impl
private final DescriptorManager descriptorManager = new DescriptorManager(this);
private final MetadataBuilders metadataBuilders = new MetadataBuilders();
private final ConstraintCached constraintsCache = new ConstraintCached();
+ private final Map<Class<?>, Class<?>> unwrappedClassCache = new ConcurrentHashMap<>();
private final Collection<Closeable> toClose = new ArrayList<>();
private final GroupsComputer groupsComputer = new GroupsComputer();
private final ParticipantFactory participantFactory;
@@ -137,6 +139,10 @@ public class ApacheValidatorFactory impl
loadAndVerifyUserCustomizations(configuration);
}
+ public Map<Class<?>, Class<?>> getUnwrappedClassCache() {
+ return unwrappedClassCache;
+ }
+
/**
* Get the property map of this {@link ApacheValidatorFactory}.
*
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java Mon May 13 11:34:00 2019
@@ -179,7 +179,6 @@ public class ConfigurationImpl implement
this.provider = aProvider;
this.providerResolver = null;
}
- initializePropertyDefaults();
}
/**
@@ -466,10 +465,6 @@ public class ConfigurationImpl implement
}
}
- private void initializePropertyDefaults() {
- properties.put(Properties.CONSTRAINTS_CACHE_SIZE, Integer.toString(50));
- }
-
private ValidationProvider<?> findProvider() {
if (providerClass == null) {
return providerResolver.getValidationProviders().get(0);
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java Mon May 13 11:34:00 2019
@@ -23,11 +23,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import javax.validation.ConstraintDefinitionException;
@@ -35,6 +35,7 @@ import javax.validation.ConstraintValida
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
+import org.apache.bval.jsr.descriptor.ConstraintD;
import org.apache.bval.jsr.metadata.AnnotationDeclaredValidatorMappingProvider;
import org.apache.bval.jsr.metadata.CompositeValidatorMappingProvider;
import org.apache.bval.jsr.metadata.DualValidationMappingProvider;
@@ -96,13 +97,19 @@ public class ConstraintCached {
}
}
- private final Map<Class<? extends Annotation>, Set<ConstraintValidatorInfo<?>>> constraintValidatorInfo =
- new HashMap<>();
+ private final ConcurrentMap<Class<? extends Annotation>, Set<ConstraintValidatorInfo<?>>> constraintValidatorInfo =
+ new ConcurrentHashMap<>();
+ private final ConcurrentMap<ConstraintD<?>, ConstraintValidator<?, ?>> validators =
+ new ConcurrentHashMap<>();
private final List<ValidatorMappingProvider> customValidatorMappingProviders = new ArrayList<>();
private final Lazy<ValidatorMappingProvider> validatorMappingProvider =
new Lazy<>(this::createValidatorMappingProvider);
+ public ConcurrentMap<ConstraintD<?>, ConstraintValidator<?, ?>> getValidators() {
+ return validators;
+ }
+
public void add(ValidatorMappingProvider validatorMappingProvider) {
customValidatorMappingProviders.add(validatorMappingProvider);
this.validatorMappingProvider.reset(this::createValidatorMappingProvider);
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java Mon May 13 11:34:00 2019
@@ -16,8 +16,14 @@
*/
package org.apache.bval.jsr;
+import static java.util.Collections.emptyEnumeration;
+import static java.util.Optional.empty;
+import static java.util.Optional.of;
+
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.Arrays;
+import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
@@ -25,6 +31,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -56,6 +63,18 @@ public class DefaultMessageInterpolator
private static final LookBehindRegexHolder MESSAGE_PARAMETER = new LookBehindRegexHolder(
"(?<!(?:^|[^\\\\])(?:\\\\\\\\){0,%1$d}\\\\)\\{((?:[\\w\\.]|\\\\[\\{\\$\\}\\\\])+)\\}", n -> (n - 4) / 2);
+ private static final ResourceBundle EMPTY_BUNDLE = new ResourceBundle() {
+ @Override
+ protected Object handleGetObject(final String key) {
+ return null;
+ }
+
+ @Override
+ public Enumeration<String> getKeys() {
+ return emptyEnumeration();
+ }
+ };
+
/** The default locale for the current user. */
private Locale defaultLocale;
@@ -65,6 +84,10 @@ public class DefaultMessageInterpolator
/** Builtin resource bundles hashed against their locale. */
private final Map<Locale, ResourceBundle> defaultBundlesMap = new ConcurrentHashMap<>();
+ private final ConcurrentMap<ComputedMessageKey, String> interpolatedMessages = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Class<?>, Method> toStringMethods = new ConcurrentHashMap<>();
+ private final ConcurrentMap<MessageWithParamsKey, String> interpolations = new ConcurrentHashMap<>();
+
private final MessageEvaluator evaluator;
/**
@@ -111,28 +134,14 @@ public class DefaultMessageInterpolator
/** {@inheritDoc} */
@Override
public String interpolate(final String message, final Context context, final Locale locale) {
- final ResourceBundle userResourceBundle = findUserResourceBundle(locale);
- final ResourceBundle defaultResourceBundle = findDefaultResourceBundle(locale);
-
- final Map<String, Object> annotationParameters = context.getConstraintDescriptor().getAttributes();
- String userBundleResolvedMessage;
- String resolvedMessage = message;
- boolean evaluatedDefaultBundleOnce = false;
- do {
- // search the user bundle recursive (step1)
- userBundleResolvedMessage = replaceVariables(resolvedMessage, userResourceBundle, locale, true);
+ if (!message.contains("{")) {
+ return resolveEscapeSequences(message);
+ }
- // exit condition - we have at least tried to validate against the default bundle and there were no
- // further replacements
- if (evaluatedDefaultBundleOnce && !hasReplacementTakenPlace(userBundleResolvedMessage, resolvedMessage)) {
- break;
- }
- // search the default bundle non recursive (step2)
- resolvedMessage = replaceVariables(userBundleResolvedMessage, defaultResourceBundle, locale, false);
- evaluatedDefaultBundleOnce = true;
- } while (true);
+ String resolvedMessage = getSharedInterpolatedMessage(message, locale);
// resolve annotation attributes (step 4)
+ final Map<String, Object> annotationParameters = context.getConstraintDescriptor().getAttributes();
resolvedMessage = replaceAnnotationAttributes(resolvedMessage, annotationParameters);
// EL handling
@@ -142,6 +151,35 @@ public class DefaultMessageInterpolator
return resolveEscapeSequences(resolvedMessage);
}
+ private String getSharedInterpolatedMessage(final String message, final Locale locale) {
+ final ComputedMessageKey key = new ComputedMessageKey(locale, message);
+ String value = interpolatedMessages.get(key);
+ if (value == null) {
+ final ResourceBundle userResourceBundle = findUserResourceBundle(locale);
+ final ResourceBundle defaultResourceBundle = findDefaultResourceBundle(locale);
+
+ String userBundleResolvedMessage;
+ String resolvedMessage = message;
+ boolean evaluatedDefaultBundleOnce = false;
+ do {
+ // search the user bundle recursive (step1)
+ userBundleResolvedMessage = doReplaceVariables(resolvedMessage, userResourceBundle, locale, true);
+
+ // exit condition - we have at least tried to validate against the default bundle and there were no
+ // further replacements
+ if (evaluatedDefaultBundleOnce && !hasReplacementTakenPlace(userBundleResolvedMessage, resolvedMessage)) {
+ break;
+ }
+ // search the default bundle non recursive (step2)
+ resolvedMessage = doReplaceVariables(userBundleResolvedMessage, defaultResourceBundle, locale, false);
+ evaluatedDefaultBundleOnce = true;
+ } while (true);
+ value = resolvedMessage;
+ interpolatedMessages.putIfAbsent(key, value);
+ }
+ return value;
+ }
+
private boolean evaluateExpressionLanguage(String template, Context context) {
if (evaluator != null) {
if (Objects.equals(template, context.getConstraintDescriptor().getMessageTemplate())) {
@@ -208,7 +246,7 @@ public class DefaultMessageInterpolator
log.log(Level.FINEST, String.format("%s found", USER_VALIDATION_MESSAGES));
}
}
- return rb;
+ return rb == null ? EMPTY_BUNDLE : rb;
}
private ResourceBundle loadBundle(ClassLoader classLoader, Locale locale, String message) {
@@ -220,7 +258,7 @@ public class DefaultMessageInterpolator
}
}
- private String replaceVariables(String message, ResourceBundle bundle, Locale locale, boolean recurse) {
+ private String doReplaceVariables(String message, ResourceBundle bundle, Locale locale, boolean recurse) {
final Matcher matcher = MESSAGE_PARAMETER.matcher(message);
final StringBuilder sb = new StringBuilder(64);
int prev = 0;
@@ -239,49 +277,72 @@ public class DefaultMessageInterpolator
}
private String replaceAnnotationAttributes(final String message, final Map<String, Object> annotationParameters) {
- final Matcher matcher = MESSAGE_PARAMETER.matcher(message);
- final StringBuilder sb = new StringBuilder(64);
- int prev = 0;
- while (matcher.find()) {
- int start = matcher.start();
- String resolvedParameterValue;
- String parameter = matcher.group(1);
- Object variable = annotationParameters.get(parameter);
- if (variable == null) {
- resolvedParameterValue = matcher.group();
- } else if (Object[].class.isInstance(variable)) {
- resolvedParameterValue = Arrays.toString((Object[]) variable);
- } else if (variable.getClass().isArray()) {
- try {
- resolvedParameterValue = (String) Reflection
- .getDeclaredMethod(Arrays.class, "toString", variable.getClass()).invoke(null, variable);
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new IllegalStateException("Could not expand array " + variable);
- }
+ final MessageWithParamsKey key = new MessageWithParamsKey(message, annotationParameters);
+ String result = interpolations.get(key);
+ if (result == null) {
+ final Matcher matcher = MESSAGE_PARAMETER.matcher(message);
+ if (!matcher.find()) {
+ result = message;
} else {
- resolvedParameterValue = variable.toString();
- }
- if (start > prev) {
- sb.append(message, prev, start);
+ final StringBuilder sb = new StringBuilder(64);
+ int prev = 0;
+ do {
+ int start = matcher.start();
+ String resolvedParameterValue;
+ String parameter = matcher.group(1);
+ Object variable = annotationParameters.get(parameter);
+ if (variable == null) {
+ resolvedParameterValue = matcher.group();
+ } else if (Object[].class.isInstance(variable)) {
+ resolvedParameterValue = Arrays.toString((Object[]) variable);
+ } else if (variable.getClass().isArray()) {
+ try {
+ resolvedParameterValue = (String) getToStringMethod(variable).invoke(null, variable);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ throw new IllegalStateException("Could not expand array " + variable);
+ }
+ } else {
+ resolvedParameterValue = variable.toString();
+ }
+ if (start > prev) {
+ sb.append(message, prev, start);
+ }
+ sb.append(resolvedParameterValue);
+ prev = matcher.end();
+ } while (matcher.find());
+ if (prev < message.length()) {
+ sb.append(message, prev, message.length());
+ }
+ result = sb.toString();
}
- sb.append(resolvedParameterValue);
- prev = matcher.end();
+ interpolations.putIfAbsent(key, result);
}
- if (prev < message.length()) {
- sb.append(message, prev, message.length());
+ return result;
+ }
+
+ public void clearCache() {
+ interpolatedMessages.clear();
+ interpolations.clear();
+ }
+
+ private Method getToStringMethod(final Object variable) {
+ final Class<?> variableClass = variable.getClass();
+ Method method = toStringMethods.get(variableClass);
+ if (method == null) {
+ method = Reflection.getDeclaredMethod(Arrays.class, "toString", variableClass);
+ toStringMethods.putIfAbsent(variableClass, method);
}
- return sb.toString();
+ return method;
}
private Optional<String> resolveParameter(String parameterName, ResourceBundle bundle, Locale locale,
boolean recurse) {
- return Optional.ofNullable(bundle).map(b -> {
- try {
- return b.getString(parameterName);
- } catch (final MissingResourceException e) {
- return null;
- }
- }).map(v -> recurse ? replaceVariables(v, bundle, locale, recurse) : v);
+ try {
+ final String string = bundle.getString(parameterName);
+ return of(recurse ? doReplaceVariables(string, bundle, locale, recurse) : string);
+ } catch (final MissingResourceException e) {
+ return empty();
+ }
}
private ResourceBundle findDefaultResourceBundle(Locale locale) {
@@ -299,5 +360,64 @@ public class DefaultMessageInterpolator
*/
public void setLocale(Locale locale) {
defaultLocale = locale;
+ clearCache(); // cause there is a probability of 50% the old cache will be replaced by the new locale
+ }
+
+ private static class ComputedMessageKey {
+ private final Locale locale;
+ private final String key;
+ private final int hash;
+
+ private ComputedMessageKey(final Locale locale, final String key) {
+ this.locale = locale;
+ this.key = key;
+ this.hash = Objects.hash(locale, key);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final ComputedMessageKey that = ComputedMessageKey.class.cast(o);
+ return locale.equals(that.locale) && key.equals(that.key);
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
+ }
+
+ private static class MessageWithParamsKey {
+ private final String message;
+ private final Map<String, Object> annotationParameters;
+ private final int hash;
+
+ private MessageWithParamsKey(final String message, final Map<String, Object> annotationParameters) {
+ this.message = message;
+ this.annotationParameters = annotationParameters;
+ this.hash = Objects.hash(message, annotationParameters);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ final MessageWithParamsKey that = MessageWithParamsKey.class.cast(o);
+ return message.equals(that.message) && annotationParameters.equals(that.annotationParameters);
+ }
+
+ @Override
+ public int hashCode() {
+ return hash;
+ }
}
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java Mon May 13 11:34:00 2019
@@ -30,7 +30,6 @@ import org.apache.bval.jsr.metadata.Cont
import org.apache.bval.jsr.util.NodeImpl;
import org.apache.bval.jsr.util.PathImpl;
import org.apache.bval.util.Exceptions;
-import org.apache.bval.util.Validate;
import org.apache.bval.util.reflection.TypeUtils;
public class GraphContext {
@@ -46,8 +45,8 @@ public class GraphContext {
private GraphContext(ApacheFactoryContext validatorContext, PathImpl path, Object value, GraphContext parent) {
super();
- this.validatorContext = Validate.notNull(validatorContext, "validatorContext");
- this.path = Validate.notNull(path, "path");
+ this.validatorContext = validatorContext;
+ this.path = path;
this.value = value;
this.parent = parent;
}
@@ -65,16 +64,16 @@ public class GraphContext {
}
public GraphContext child(NodeImpl node, Object value) {
- Validate.notNull(node, "node");
+ // Validate.notNull(node, "node");
final PathImpl p = PathImpl.copy(path);
p.addNode(node);
return new GraphContext(validatorContext, p, value, this);
}
public GraphContext child(Path p, Object value) {
- Validate.notNull(p, "Path");
+ // Validate.notNull(p, "Path");
final PathImpl impl = PathImpl.of(p);
- Validate.isTrue(impl.isSubPathOf(path), "%s is not a subpath of %s", p, path);
+ // Validate.isTrue(impl.isSubPathOf(path), "%s is not a subpath of %s", p, path);
return new GraphContext(validatorContext, impl == p ? PathImpl.copy(impl) : impl, value, this);
}
@@ -120,7 +119,6 @@ public class GraphContext {
}
public ContainerElementKey runtimeKey(ContainerElementKey key) {
- Validate.notNull(key);
if (value != null) {
final Class<?> containerClass = key.getContainerClass();
final Class<? extends Object> runtimeType = value.getClass();
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/BeanD.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/BeanD.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/BeanD.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/BeanD.java Mon May 13 11:34:00 2019
@@ -19,7 +19,9 @@
package org.apache.bval.jsr.descriptor;
import java.lang.reflect.Type;
+import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -33,6 +35,7 @@ import javax.validation.metadata.Propert
import org.apache.bval.jsr.groups.GroupStrategy;
import org.apache.bval.jsr.metadata.Signature;
import org.apache.bval.jsr.util.ToUnmodifiable;
+import org.apache.bval.util.CollectionSet;
import org.apache.bval.util.Exceptions;
import org.apache.bval.util.StringUtils;
@@ -44,6 +47,9 @@ public class BeanD<T> extends ElementD<C
private final Map<Signature, ConstructorD<T>> constructors;
private final Map<Signature, MethodD> methods;
private final GroupStrategy groupStrategy;
+
+ private final Set<ConstructorDescriptor> constrainedConstructors;
+ private final Map<Set<MethodType>, Set<MethodDescriptor>> methodCache = new HashMap<>();
BeanD(MetadataReader.ForBean<T> reader) {
super(reader);
@@ -51,9 +57,13 @@ public class BeanD<T> extends ElementD<C
groupStrategy = reader.getGroupStrategy();
propertiesMap = reader.getProperties(this);
- properties = propertiesMap.values().stream().filter(DescriptorManager::isConstrained).collect(ToUnmodifiable.set());
+ properties =
+ propertiesMap.values().stream().filter(DescriptorManager::isConstrained).collect(ToUnmodifiable.set());
constructors = reader.getConstructors(this);
methods = reader.getMethods(this);
+
+ constrainedConstructors =
+ constructors.isEmpty() ? Collections.emptySet() : new CollectionSet<>(constructors.values());
}
@Override
@@ -63,12 +73,12 @@ public class BeanD<T> extends ElementD<C
@Override
public boolean isBeanConstrained() {
- return hasConstraints() || properties.stream().anyMatch(DescriptorManager::isConstrained);
+ return hasConstraints() || !properties.isEmpty();
}
@Override
public PropertyDescriptor getConstraintsForProperty(String propertyName) {
- return Optional.ofNullable(getProperty(propertyName)).filter(DescriptorManager::isConstrained).orElse(null);
+ return Optional.ofNullable(getProperty(propertyName)).filter(properties::contains).orElse(null);
}
@Override
@@ -85,8 +95,15 @@ public class BeanD<T> extends ElementD<C
@Override
public Set<MethodDescriptor> getConstrainedMethods(MethodType methodType, MethodType... methodTypes) {
- final EnumSet<MethodType> filter = EnumSet.of(methodType, methodTypes);
- return methods.values().stream().filter(m -> filter.contains(m.getMethodType())).collect(ToUnmodifiable.set());
+ return methodCache.computeIfAbsent(EnumSet.of(methodType, methodTypes), k -> {
+ if (methods.isEmpty() || k.isEmpty()) {
+ return Collections.emptySet();
+ }
+ if (k.size() == MethodType.values().length) {
+ return new CollectionSet<>(methods.values());
+ }
+ return methods.values().stream().filter(m -> k.contains(m.getMethodType())).collect(ToUnmodifiable.set());
+ });
}
@Override
@@ -96,7 +113,7 @@ public class BeanD<T> extends ElementD<C
@Override
public Set<ConstructorDescriptor> getConstrainedConstructors() {
- return constructors.values().stream().collect(ToUnmodifiable.set());
+ return constrainedConstructors;
}
public PropertyDescriptor getProperty(String propertyName) {
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/CascadableContainerD.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/CascadableContainerD.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/CascadableContainerD.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/CascadableContainerD.java Mon May 13 11:34:00 2019
@@ -35,13 +35,16 @@ public abstract class CascadableContaine
private final boolean cascaded;
private final Set<GroupConversion> groupConversions;
- private final Set<ContainerElementTypeD> containerElementTypes;
+ private final Set<ContainerElementTypeDescriptor> containerElementTypes;
protected CascadableContainerD(MetadataReader.ForContainer<E> reader, P parent) {
super(reader, parent);
cascaded = reader.isCascaded();
groupConversions = reader.getGroupConversions();
- containerElementTypes = reader.getContainerElementTypes(this);
+ containerElementTypes = reader.getContainerElementTypes(this)
+ .stream()
+ .filter(DescriptorManager::isConstrained)
+ .collect(ToUnmodifiable.set());
}
@Override
@@ -62,7 +65,6 @@ public abstract class CascadableContaine
@Override
public Set<ContainerElementTypeDescriptor> getConstrainedContainerElementTypes() {
- return containerElementTypes.stream().filter(DescriptorManager::isConstrained)
- .collect(ToUnmodifiable.set());
+ return containerElementTypes;
}
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ContainerElementTypeD.java Mon May 13 11:34:00 2019
@@ -43,7 +43,7 @@ public class ContainerElementTypeD exten
@Override
public Integer getTypeArgumentIndex() {
- return Integer.valueOf(key.getTypeArgumentIndex());
+ return key.getTypeArgumentIndex();
}
public ContainerElementKey getKey() {
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ExecutableD.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ExecutableD.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ExecutableD.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ExecutableD.java Mon May 13 11:34:00 2019
@@ -33,6 +33,8 @@ public abstract class ExecutableD<E exte
private final ReturnValueD<SELF, E> returnValue;
private final List<ParameterD<SELF>> parameters;
private final CrossParameterD<SELF, E> crossParameter;
+ private final boolean parametersAreConstrained;
+ private final boolean returnValueIsConstrained;
@SuppressWarnings("unchecked")
protected ExecutableD(R reader, BeanD<?> parent) {
@@ -43,6 +45,8 @@ public abstract class ExecutableD<E exte
returnValue = reader.getReturnValueDescriptor((SELF) this);
parameters = reader.getParameterDescriptors((SELF) this);
crossParameter = reader.getCrossParameterDescriptor((SELF) this);
+ parametersAreConstrained = parameters.stream().anyMatch(DescriptorManager::isConstrained) || crossParameter.hasConstraints();
+ returnValueIsConstrained = DescriptorManager.isConstrained(returnValue);
}
@Override
@@ -68,11 +72,11 @@ public abstract class ExecutableD<E exte
@Override
public final boolean hasConstrainedParameters() {
- return parameters.stream().anyMatch(DescriptorManager::isConstrained) || getCrossParameterDescriptor().hasConstraints();
+ return parametersAreConstrained;
}
@Override
public final boolean hasConstrainedReturnValue() {
- return DescriptorManager.isConstrained(returnValue);
+ return returnValueIsConstrained;
}
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/PropertyD.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/PropertyD.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/PropertyD.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/PropertyD.java Mon May 13 11:34:00 2019
@@ -28,7 +28,6 @@ import javax.validation.metadata.Propert
import org.apache.bval.jsr.GraphContext;
import org.apache.bval.jsr.util.Methods;
import org.apache.bval.jsr.util.PathImpl;
-import org.apache.bval.util.Validate;
import org.apache.bval.util.reflection.Reflection;
import org.apache.commons.weaver.privilizer.Privilizing;
import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
@@ -94,7 +93,6 @@ public abstract class PropertyD<E extend
}
public final Stream<GraphContext> read(GraphContext context) {
- Validate.notNull(context);
if (context.getValue() == null) {
return Stream.empty();
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java Mon May 13 11:34:00 2019
@@ -34,7 +34,6 @@ import javax.validation.groups.Default;
import org.apache.bval.util.Exceptions;
import org.apache.bval.util.ObjectWrapper;
-import org.apache.bval.util.Validate;
/**
* Immutable object that wraps an interface representing a single group.
@@ -128,7 +127,7 @@ public final class Group implements Grou
* @param group
*/
public Group(Class<?> group) {
- this.group = Validate.notNull(group);
+ this.group = group;
}
/**
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupStrategy.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupStrategy.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupStrategy.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupStrategy.java Mon May 13 11:34:00 2019
@@ -29,7 +29,6 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.bval.jsr.util.ToUnmodifiable;
-import org.apache.bval.util.Validate;
/**
* Group strategy interface.
@@ -78,8 +77,6 @@ public interface GroupStrategy {
protected final boolean ordered;
public Composite(Collection<? extends GroupStrategy> components, boolean ordered) {
- Validate.isTrue(Validate.notNull(components).stream().noneMatch(Objects::isNull),
- "null component not permitted");
this.components = new LinkedHashSet<>(components);
this.ordered = ordered;
}
@@ -155,8 +152,6 @@ public interface GroupStrategy {
};
public static GroupStrategy redefining(GroupStrategy source, Map<Group, ? extends GroupStrategy> redefinitions) {
- Validate.notNull(source, "source");
-
if (!(redefinitions == null || redefinitions.isEmpty())) {
if (redefinitions.containsValue(null)) {
redefinitions = redefinitions.entrySet().stream().filter(e -> e.getValue() != null)
@@ -174,7 +169,6 @@ public interface GroupStrategy {
}
public static GroupStrategy simple(Collection<? extends Group> coll) {
- Validate.notNull(coll);
if (coll.size() == 1) {
return coll.iterator().next();
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java Mon May 13 11:34:00 2019
@@ -125,4 +125,4 @@ public class Groups {
components.addAll(sequences);
return GroupStrategy.composite(components);
}
-}
+}
\ No newline at end of file
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java Mon May 13 11:34:00 2019
@@ -70,6 +70,10 @@ public class GroupsComputer {
@SafeVarargs
public final Groups computeGroups(Class<?>... groups) {
Exceptions.raiseIf(groups == null, IllegalArgumentException::new, "null validation groups specified");
+
+ if (groups.length == 0 || (groups.length == 1 && groups[0] == Default.class)) {
+ return DEFAULT_GROUPS;
+ }
return computeGroups(Arrays.asList(groups));
}
@@ -131,7 +135,7 @@ public class GroupsComputer {
public Groups computeGroups(Collection<Class<?>> groups) {
Validate.notNull(groups, "groups");
- if (groups.isEmpty() || Arrays.asList(DEFAULT_GROUP).equals(new ArrayList<>(groups))) {
+ if (groups.isEmpty() || (groups.size() == 1 && groups.contains(Default.class))) {
return DEFAULT_GROUPS;
}
return computeGroups(groups.stream());
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java Mon May 13 11:34:00 2019
@@ -79,6 +79,7 @@ import org.apache.bval.util.Validate;
import org.apache.bval.util.reflection.TypeUtils;
public abstract class ValidationJob<T> {
+ private static final ConstraintValidator NOOP_VALIDATOR = (o, ctx) -> true;
public abstract class Frame<D extends ElementD<?, ?>> {
protected final Frame<?> parent;
@@ -195,30 +196,32 @@ public abstract class ValidationJob<T> {
@SuppressWarnings({ "rawtypes" })
private ConstraintValidator getConstraintValidator(ConstraintD<?> constraint) {
- final Class<? extends ConstraintValidator> constraintValidatorClass =
- new ComputeConstraintValidatorClass<>(validatorContext.getConstraintsCache(), constraint,
- getValidationTarget(), computeValidatedType(constraint)).get();
-
- if (constraintValidatorClass == null) {
- if (constraint.getComposingConstraints().isEmpty()) {
- Exceptions.raise(UnexpectedTypeException::new, "No %s type located for non-composed constraint %s",
- ConstraintValidator.class.getSimpleName(), constraint);
+ return validatorContext.getOrComputeConstraintValidator(constraint, () -> {
+ final Class<? extends ConstraintValidator> constraintValidatorClass =
+ new ComputeConstraintValidatorClass<>(validatorContext.getConstraintsCache(), constraint,
+ getValidationTarget(), computeValidatedType(constraint)).get();
+
+ if (constraintValidatorClass == null) {
+ if (constraint.getComposingConstraints().isEmpty()) {
+ Exceptions.raise(UnexpectedTypeException::new, "No %s type located for non-composed constraint %s",
+ ConstraintValidator.class.getSimpleName(), constraint);
+ }
+ return NOOP_VALIDATOR;
}
- return null;
- }
- ConstraintValidator constraintValidator = null;
- Exception cause = null;
- try {
- constraintValidator =
- validatorContext.getConstraintValidatorFactory().getInstance(constraintValidatorClass);
- } catch (Exception e) {
- cause = e;
- }
- if (constraintValidator == null) {
- Exceptions.raise(ValidationException::new, cause, "Unable to get %s instance from %s",
- constraintValidatorClass.getName(), validatorContext.getConstraintValidatorFactory());
- }
- return constraintValidator;
+ ConstraintValidator constraintValidator = null;
+ Exception cause = null;
+ try {
+ constraintValidator =
+ validatorContext.getConstraintValidatorFactory().getInstance(constraintValidatorClass);
+ } catch (Exception e) {
+ cause = e;
+ }
+ if (constraintValidator == null) {
+ Exceptions.raise(ValidationException::new, cause, "Unable to get %s instance from %s",
+ constraintValidatorClass.getName(), validatorContext.getConstraintValidatorFactory());
+ }
+ return constraintValidator;
+ });
}
private Class<?> computeValidatedType(ConstraintD<?> constraint) {
@@ -573,8 +576,14 @@ public abstract class ValidationJob<T> {
@SuppressWarnings("unchecked")
private <O> BeanD<O> getBeanDescriptor(Object bean) {
- final Class<? extends Object> t = Proxies.classFor(Validate.notNull(bean, "bean").getClass());
- return (BeanD<O>) validatorContext.getDescriptorManager().getBeanDescriptor(t);
+ final Class<?> beanClass = Validate.notNull(bean, "bean").getClass();
+ final Map<Class<?>, Class<?>> classCache = validatorContext.getFactory().getUnwrappedClassCache();
+ Class<?> unwrappedClass = classCache.get(beanClass);
+ if (unwrappedClass == null) {
+ unwrappedClass = Proxies.classFor(beanClass);
+ classCache.putIfAbsent(beanClass, unwrappedClass);
+ }
+ return (BeanD<O>) validatorContext.getDescriptorManager().getBeanDescriptor(unwrappedClass);
}
final ConstraintViolationImpl<T> createViolation(String messageTemplate, ConstraintValidatorContextImpl<T> context,
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/HierarchyBuilder.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/HierarchyBuilder.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/HierarchyBuilder.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/HierarchyBuilder.java Mon May 13 11:34:00 2019
@@ -334,8 +334,10 @@ public class HierarchyBuilder extends Co
return (MetadataBuilder.ForBean<T>) delegates.get(0);
}
// pretend:
- return delegates.stream().<MetadataBuilder.ForBean<T>> map(MetadataBuilder.ForBean.class::cast)
- .collect(compose());
+ // note: stream split for java 11 compilation
+ final Stream<MetadataBuilder.ForBean<T>> forBeanStream = delegates.stream()
+ .map(MetadataBuilder.ForBean.class::cast);
+ return forBeanStream.collect(compose());
}
@Override
@@ -345,7 +347,7 @@ public class HierarchyBuilder extends Co
@SuppressWarnings("unchecked")
final Function<MetadataBuilder.ForElement<E>, Meta<E>> keyMapper =
d -> Optional.of(d).filter(HierarchyDelegate.class::isInstance).map(HierarchyDelegate.class::cast)
- .map(HierarchyDelegate::getHierarchyElement).orElse(meta);
+ .map(HierarchyDelegate::getHierarchyElement).map(Meta.class::cast).orElse(meta);
return composite.delegates.stream().collect(Collectors.toMap(keyMapper, d -> d.getDeclaredConstraints(meta),
(u, v) -> Stream.of(u, v).flatMap(Stream::of).toArray(Annotation[]::new), LinkedHashMap::new));
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Liskov.java Mon May 13 11:34:00 2019
@@ -52,13 +52,19 @@ class Liskov {
@Override
public boolean test(Map<Meta<?>, Set<ValidationElement>> detectedValidationElements) {
- boolean lowestFound = false;
+ Class<?> declaringType = null;
- for (Set<ValidationElement> validated : detectedValidationElements.values()) {
- if (lowestFound) {
+ for (Map.Entry<Meta<?>, Set<ValidationElement>> e : detectedValidationElements.entrySet()){
+ final Class<?> t = e.getKey().getDeclaringClass();
+ if (declaringType != null) {
+ if (declaringType.isAssignableFrom(t)) {
+ continue;
+ }
return false;
}
- lowestFound = !validated.isEmpty();
+ if (!e.getValue().isEmpty()){
+ declaringType = t;
+ }
}
return true;
}
@@ -67,16 +73,34 @@ class Liskov {
@Override
public boolean test(Map<Meta<?>, Set<ValidationElement>> detectedValidationElements) {
- final Set<Class<?>> interfaces = detectedValidationElements.keySet().stream().map(Meta::getDeclaringClass)
- .filter(Class::isInterface).collect(Collectors.toSet());
- if (interfaces.isEmpty()) {
+ if (detectedValidationElements.size() < 2) {
+ // no unrelated hierarchy possible
return true;
}
- final boolean allRelated =
- detectedValidationElements.keySet().stream().map(Meta::getDeclaringClass).allMatch(ifc -> interfaces
- .stream().filter(Predicate.isEqual(ifc).negate()).allMatch(ifc2 -> related(ifc, ifc2)));
-
- return allRelated;
+ final Map<Class<?>, Set<ValidationElement>> interfaceValidation = new LinkedHashMap<>();
+ detectedValidationElements.forEach((k,v)->{
+ final Class<?> t = k.getDeclaringClass();
+ if (t.isInterface()){
+ interfaceValidation.put(t, v);
+ }
+ });
+ if (interfaceValidation.isEmpty()) {
+ // if all are classes, there can be no unrelated types in the hierarchy:
+ return true;
+ }
+ // verify that all types can be assigned to the constrained interfaces:
+ for (Meta<?> meta : detectedValidationElements.keySet()) {
+ final Class<?> t = meta.getDeclaringClass();
+ for (Map.Entry<Class<?>, Set<ValidationElement>> e : interfaceValidation.entrySet()) {
+ if (t.equals(e.getKey()) || e.getValue().isEmpty()) {
+ continue;
+ }
+ if (!e.getKey().isAssignableFrom(t)) {
+ return false;
+ }
+ }
+ }
+ return true;
}
};
//@formatter:on
@@ -122,7 +146,7 @@ class Liskov {
// pre-check return value overridden hierarchy:
Stream.of(StrengtheningIssue.values())
- .filter((Predicate<? super StrengtheningIssue>) si -> !(si == StrengtheningIssue.overriddenHierarchy
+ .filter(si -> !(si == StrengtheningIssue.overriddenHierarchy
&& detectedValidationElements.values().stream().filter(s -> !s.isEmpty()).count() < 2))
.forEach(si -> si.check(detectedValidationElements));
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java Mon May 13 11:34:00 2019
@@ -231,6 +231,7 @@ public abstract class Meta<E extends Ann
return getHost().getAnnotatedType();
}
+ @Override
public String getName() {
return name;
}
@@ -290,7 +291,7 @@ public abstract class Meta<E extends Ann
}
public Integer getTypeArgumentIndex() {
- return Integer.valueOf(key.getTypeArgumentIndex());
+ return key.getTypeArgumentIndex();
}
@Override
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java Mon May 13 11:34:00 2019
@@ -38,9 +38,9 @@ public abstract class ValidatorMappingPr
final Type constraintParameter = TypeUtils.getTypeArguments(t, ConstraintValidator.class)
.get(ConstraintValidator.class.getTypeParameters()[0]);
- if (!constraintType.equals(constraintParameter)) {
+ if (!TypeUtils.isAssignable(constraintType, constraintParameter)) {
Exceptions.raise(ConstraintDefinitionException::new,
- "%s %s expected first type parameter of %s, %s; source %s", ConstraintValidator.class, t,
+ "%s %s expected first type parameter assignable from %s, %s; source %s", ConstraintValidator.class, t,
constraintType, constraintParameter, result.get().getSource());
}
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxy.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxy.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxy.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxy.java Mon May 13 11:34:00 2019
@@ -43,8 +43,6 @@ class AnnotationProxy implements Annotat
/** Serialization version */
private static final long serialVersionUID = 1L;
-
- private Signature EQUALS = new Signature("equals", Object.class);
private final Class<? extends Annotation> annotationType;
private final SortedMap<String, Object> values;
@@ -80,10 +78,11 @@ class AnnotationProxy implements Annotat
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if (values.containsKey(method.getName())) {
- return values.get(method.getName());
+ final Object value = values.get(method.getName());
+ if (value != null) {
+ return value;
}
- if (EQUALS.equals(Signature.of(method))) {
+ if (method.getName().equals("equals")) { // this is an annotation, no need to be more fancy (and slower)
return equalTo(args[0]);
}
return method.invoke(this, args);
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxyBuilder.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxyBuilder.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxyBuilder.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationProxyBuilder.java Mon May 13 11:34:00 2019
@@ -24,6 +24,7 @@ import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ConcurrentMap;
import javax.enterprise.util.AnnotationLiteral;
import javax.validation.ConstraintTarget;
@@ -57,7 +58,7 @@ public final class AnnotationProxyBuilde
* @param annotationType
* @param cache
*/
- AnnotationProxyBuilder(final Class<A> annotationType, Map<Class<?>, Method[]> cache) {
+ AnnotationProxyBuilder(final Class<A> annotationType, ConcurrentMap<Class<?>, Method[]> cache) {
this.type = Validate.notNull(annotationType, "annotationType");
this.methods = Validate.notNull(cache, "cache").computeIfAbsent(annotationType, Reflection::getDeclaredMethods);
}
@@ -71,7 +72,7 @@ public final class AnnotationProxyBuilde
* @param cache
*/
@SuppressWarnings("unchecked")
- AnnotationProxyBuilder(A annot, Map<Class<?>, Method[]> cache) {
+ AnnotationProxyBuilder(A annot, ConcurrentMap<Class<?>, Method[]> cache) {
this((Class<A>) annot.annotationType(), cache);
elements.putAll(AnnotationsManager.readAttributes(annot));
}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java Mon May 13 11:34:00 2019
@@ -36,6 +36,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -51,7 +53,6 @@ import javax.validation.ValidationExcept
import javax.validation.constraintvalidation.ValidationTarget;
import org.apache.bval.jsr.ApacheValidatorFactory;
-import org.apache.bval.jsr.ConfigurationImpl;
import org.apache.bval.jsr.ConstraintAnnotationAttributes;
import org.apache.bval.jsr.ConstraintAnnotationAttributes.Worker;
import org.apache.bval.jsr.ConstraintCached.ConstraintValidatorInfo;
@@ -307,24 +308,14 @@ public class AnnotationsManager {
}
private final ApacheValidatorFactory validatorFactory;
- private final LRUCache<Class<? extends Annotation>, Composition> compositions;
- private final LRUCache<Class<? extends Annotation>, Method[]> constraintAttributes;
+ private final ConcurrentMap<Class<?>, Composition> compositions;
+ private final ConcurrentMap<Class<?>, Method[]> constraintAttributes;
public AnnotationsManager(ApacheValidatorFactory validatorFactory) {
super();
this.validatorFactory = Validate.notNull(validatorFactory);
- final String cacheSize =
- validatorFactory.getProperties().get(ConfigurationImpl.Properties.CONSTRAINTS_CACHE_SIZE);
- final int sz;
- try {
- sz = Integer.parseInt(cacheSize);
- } catch (NumberFormatException e) {
- throw Exceptions.create(IllegalStateException::new, e,
- "Cannot parse value %s for configuration property %s", cacheSize,
- ConfigurationImpl.Properties.CONSTRAINTS_CACHE_SIZE);
- }
- compositions = new LRUCache<>(sz);
- constraintAttributes = new LRUCache<>(sz);
+ compositions = new ConcurrentHashMap<>();
+ constraintAttributes = new ConcurrentHashMap<>();
}
public void validateConstraintDefinition(Class<? extends Annotation> type) {
@@ -418,12 +409,12 @@ public class AnnotationsManager {
@SuppressWarnings({ "unchecked", "rawtypes" })
public <A extends Annotation> AnnotationProxyBuilder<A> buildProxyFor(Class<A> type) {
- return new AnnotationProxyBuilder<>(type, (Map) constraintAttributes);
+ return new AnnotationProxyBuilder<>(type, constraintAttributes);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public <A extends Annotation> AnnotationProxyBuilder<A> buildProxyFor(A instance) {
- return new AnnotationProxyBuilder<>(instance, (Map) constraintAttributes);
+ return new AnnotationProxyBuilder<>(instance, constraintAttributes);
}
private Composition getComposition(Class<? extends Annotation> annotationType) {
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathNavigation.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathNavigation.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathNavigation.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/PathNavigation.java Mon May 13 11:34:00 2019
@@ -94,7 +94,7 @@ public class PathNavigation {
private final List<Callback<?>> delegates;
public CompositeCallbackProcedure(Callback<?>... delegates) {
- this(new ArrayList<>(Arrays.asList(delegates)));
+ this(Arrays.asList(delegates.clone()));
}
public CompositeCallbackProcedure(List<Callback<?>> delegates) {
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Proxies.java Mon May 13 11:34:00 2019
@@ -31,8 +31,8 @@ public final class Proxies {
KNOWN_PROXY_CLASSNAMES = Collections.unmodifiableSet(s);
}
- // get rid of proxies which probably contains wrong annotation metamodel
- public static <T> Class<?> classFor(final Class<?> clazz) { // TODO: do we want a SPI with impl for guice, owb, openejb, ...?
+ // get rid of proxies which probably contains wrong annotation metamodel - note: it is "slow", cache the result!
+ public static Class<?> classFor(final Class<?> clazz) { // TODO: do we want a SPI with impl for guice, owb, openejb, ...?
if (isProxyClass(clazz)) {
final Class<?> parent = clazz.getSuperclass();
if (parent != null) {
Modified: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/valueextraction/ValueExtractors.java Mon May 13 11:34:00 2019
@@ -257,7 +257,6 @@ public class ValueExtractors {
}
public void add(ValueExtractor<?> extractor) {
- Validate.notNull(extractor);
final ContainerElementKey key = ContainerElementKey.forValueExtractor(extractor);
if (key == null) {
Exceptions.raise(IllegalStateException::new, "Computed null %s for %s",
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CollectionSet.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CollectionSet.java?rev=1859181&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CollectionSet.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CollectionSet.java Mon May 13 11:34:00 2019
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.util;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Unmodifiable {@link Set} backed by a {@link Collection} obeying {@link Set} semantics.
+ *
+ * @param <E>
+ */
+public class CollectionSet<E> implements Set<E> {
+ private final Collection<E> wrapped;
+
+ public CollectionSet(Collection<? extends E> wrapped) {
+ super();
+ this.wrapped = Collections.unmodifiableCollection(Validate.notNull(wrapped));
+ Validate.isTrue(wrapped.stream().distinct().count() == wrapped.size(), "Collection values are not distinct");
+ }
+
+ @Override
+ public int size() {
+ return wrapped.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return wrapped.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return wrapped.contains(o);
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return wrapped.iterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return wrapped.toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return wrapped.toArray(a);
+ }
+
+ @Override
+ public boolean add(E e) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return wrapped.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends E> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+}
Modified: tomee/deps/branches/bval-2/bval-jsr/src/test/java/org/apache/bval/jsr/LiskovTest.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/test/java/org/apache/bval/jsr/LiskovTest.java?rev=1859181&r1=1859180&r2=1859181&view=diff
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/test/java/org/apache/bval/jsr/LiskovTest.java (original)
+++ tomee/deps/branches/bval-2/bval-jsr/src/test/java/org/apache/bval/jsr/LiskovTest.java Mon May 13 11:34:00 2019
@@ -18,25 +18,17 @@
*/
package org.apache.bval.jsr;
-import java.lang.reflect.Method;
-
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotNull;
-import javax.validation.executable.ExecutableValidator;
-import org.junit.Ignore;
import org.junit.Test;
-@Ignore("requires some revisiting of Liskov impl - discuss in progress")
public class LiskovTest {
- @Test // this test was throwing a Liskov exception, here to ensure it is not the case
- public void validateParams() throws NoSuchMethodException {
- final Api service = new Impl();
+ @Test
+ public void testBVal167() {
try (final ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
- final ExecutableValidator validator = factory.getValidator().forExecutables();
- final Method method = Api.class.getMethod("read", String.class);
- validator.validateParameters(service, method, new Object[]{""});
+ factory.getValidator().getConstraintsForClass(Impl.class);
}
}
@@ -44,16 +36,18 @@ public class LiskovTest {
String read(@NotNull String key);
}
- public static abstract class Base {
- public String read(final String key) {
- return null;
- }
+ public interface Api2 extends Api {
+ @Override
+ String read(String key);
}
- public static class Impl extends Base implements Api {
+ public static abstract class Base implements Api {
@Override
public String read(final String key) {
- return super.read(key);
+ return null;
}
}
+
+ public static class Impl extends Base implements Api2 {
+ }
}