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 {
+    }
 }