You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by ra...@apache.org on 2018/10/12 15:00:51 UTC

svn commit: r1843674 [12/22] - in /tomee/deps/branches/bval-2: ./ bundle/ bundle/src/ bundle/src/main/ bundle/src/main/appended-resources/ bundle/src/main/appended-resources/META-INF/ bval-extras/ bval-extras/src/ bval-extras/src/main/ bval-extras/src/...

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingRelevant.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingRelevant.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingRelevant.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingRelevant.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,33 @@
+/*
+ * 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.jsr.resolver;
+
+import javax.validation.TraversableResolver;
+
+/**
+ * Description: indicator interface to let the implementation choose
+ * whether results of traversable resolver should be cached.<br/>
+ */
+public interface CachingRelevant {
+    /**
+     * Learn whether the results of the {@link TraversableResolver} should be cached.
+     * @return boolean
+     */
+    boolean needsCaching();
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingTraversableResolver.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingTraversableResolver.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingTraversableResolver.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/CachingTraversableResolver.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,181 @@
+/*
+ * 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.jsr.resolver;
+
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+import java.lang.annotation.ElementType;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Cache results of a delegated traversable resovler to optimize calls
+ * It works only for a single validate* call and should not be used if
+ * the TraversableResolver is accessed concurrently
+ * <p/>
+ * Date: 25.11.2009 <br/>
+ * Time: 13:56:18 <br/>
+ *
+ * @author Roman Stumm (based on the code of Emmanuel Bernard)
+ */
+public class CachingTraversableResolver implements TraversableResolver, CachingRelevant {
+    private TraversableResolver delegate;
+    private Map<CacheEntry, CacheEntry> cache = new HashMap<>();
+
+    /**
+     * Convenience method to check whether caching is necessary on a given {@link TraversableResolver}.
+     * @param resolver to check
+     * @return true when a CachingTraversableResolver is to be used during validation
+     */
+    public static boolean needsCaching(TraversableResolver resolver) {
+        // caching, if we do not know exactly
+        return !(resolver instanceof CachingRelevant) || ((CachingRelevant) resolver).needsCaching();
+    }
+
+    /**
+     * Create a new CachingTraversableResolver instance.
+     * @param delegate
+     */
+    public CachingTraversableResolver(TraversableResolver delegate) {
+        this.delegate = delegate;
+    }
+
+    /**
+     * If necessary, return a caching wrapper for the specified {@link TraversableResolver}.
+     * @param traversableResolver
+     * @return {@link TraversableResolver}
+     * @see #needsCaching(TraversableResolver)
+     */
+    public static TraversableResolver cacheFor(TraversableResolver traversableResolver) {
+        return needsCaching(traversableResolver) ? new CachingTraversableResolver(traversableResolver)
+            : traversableResolver;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, ElementType elementType) {
+        CacheEntry currentLH =
+            new CacheEntry(traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType);
+        CacheEntry cachedLH = cache.get(currentLH);
+        if (cachedLH == null) {
+            currentLH.reachable = delegate.isReachable(traversableObject, traversableProperty, rootBeanType,
+                pathToTraversableObject, elementType);
+            cache.put(currentLH, currentLH);
+            cachedLH = currentLH;
+        } else if (cachedLH.reachable == null) {
+            cachedLH.reachable = delegate.isReachable(traversableObject, traversableProperty, rootBeanType,
+                pathToTraversableObject, elementType);
+        }
+        return cachedLH.reachable;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, ElementType elementType) {
+        CacheEntry currentLH =
+            new CacheEntry(traversableObject, traversableProperty, rootBeanType, pathToTraversableObject, elementType);
+        CacheEntry cachedLH = cache.get(currentLH);
+        if (cachedLH == null) {
+            currentLH.cascadable = delegate.isCascadable(traversableObject, traversableProperty, rootBeanType,
+                pathToTraversableObject, elementType);
+            cache.put(currentLH, currentLH);
+            cachedLH = currentLH;
+        } else if (cachedLH.cascadable == null) {
+            cachedLH.cascadable = delegate.isCascadable(traversableObject, traversableProperty, rootBeanType,
+                pathToTraversableObject, elementType);
+        }
+        return cachedLH.cascadable;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean needsCaching() {
+        return false; // I am the cache. Do not need cache for cache
+    }
+
+    /**
+     * Entry in the cache.
+     */
+    private static class CacheEntry {
+        private final Object object;
+        private final Path.Node node;
+        private final Class<?> type;
+        private final Path path;
+        private final ElementType elementType;
+        private final int hashCode;
+
+        private Boolean reachable;
+        private Boolean cascadable;
+
+        /**
+         * Create a new CacheEntry instance.
+         * @param traversableObject
+         * @param traversableProperty
+         * @param rootBeanType
+         * @param pathToTraversableObject
+         * @param elementType
+         */
+        private CacheEntry(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+            Path pathToTraversableObject, ElementType elementType) {
+            this.object = traversableObject;
+            this.node = traversableProperty;
+            this.type = rootBeanType;
+            this.path = pathToTraversableObject;
+            this.elementType = elementType;
+            this.hashCode = buildHashCode();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || !getClass().equals(o.getClass())) {
+                return false;
+            }
+
+            CacheEntry that = (CacheEntry) o;
+
+            return elementType == that.elementType && Objects.equals(path, that.path) && Objects.equals(type, that.type)
+                && Objects.equals(object, that.object) && Objects.equals(node, that.node);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            return hashCode;
+        }
+
+        private int buildHashCode() {
+            return Objects.hash(object, node, type, path, elementType);
+        }
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/DefaultTraversableResolver.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/DefaultTraversableResolver.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/DefaultTraversableResolver.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/DefaultTraversableResolver.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,113 @@
+/*
+ * 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.jsr.resolver;
+
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+
+import java.lang.annotation.ElementType;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** @see javax.validation.TraversableResolver */
+@Privilizing(@CallTo(Reflection.class))
+public class DefaultTraversableResolver implements TraversableResolver, CachingRelevant {
+    private static final Logger log = Logger.getLogger(DefaultTraversableResolver.class.getName());
+    private static final boolean LOG_FINEST = log.isLoggable(Level.FINEST);
+
+    /** Class to load to check whether JPA 2 is on the classpath. */
+    private static final String PERSISTENCE_UTIL_CLASSNAME = "javax.persistence.PersistenceUtil";
+
+    /** Class to instantiate in case JPA 2 is on the classpath. */
+    private static final String JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME =
+        "org.apache.bval.jsr.resolver.JPATraversableResolver";
+
+    private TraversableResolver jpaTR;
+
+    /**
+     * Create a new DefaultTraversableResolver instance.
+     */
+    public DefaultTraversableResolver() {
+        initJpa();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, ElementType elementType) {
+        return jpaTR == null || jpaTR.isReachable(traversableObject, traversableProperty, rootBeanType,
+            pathToTraversableObject, elementType);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, ElementType elementType) {
+        return jpaTR == null || jpaTR.isCascadable(traversableObject, traversableProperty, rootBeanType,
+            pathToTraversableObject, elementType);
+    }
+
+    /** Tries to load detect and load JPA. */
+    @SuppressWarnings("unchecked")
+    private void initJpa() {
+        final ClassLoader classLoader = Reflection.getClassLoader(DefaultTraversableResolver.class);
+        try {
+            Reflection.toClass(PERSISTENCE_UTIL_CLASSNAME, classLoader);
+            if (LOG_FINEST) {
+                log.log(Level.FINEST, String.format("Found %s on classpath.", PERSISTENCE_UTIL_CLASSNAME));
+            }
+        } catch (final Exception e) {
+            log.log(Level.FINEST,
+                String.format("Cannot find %s on classpath. All properties will per default be traversable.",
+                    PERSISTENCE_UTIL_CLASSNAME));
+            return;
+        }
+
+        try {
+            Class<? extends TraversableResolver> jpaAwareResolverClass =
+                (Class<? extends TraversableResolver>) Reflection.toClass(JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME,
+                    classLoader);
+            jpaTR = jpaAwareResolverClass.getConstructor().newInstance();
+            if (LOG_FINEST) {
+                log.log(Level.FINEST,
+                    String.format("Instantiated an instance of %s.", JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME));
+            }
+        } catch (final Exception e) {
+            log.log(Level.WARNING,
+                String.format(
+                    "Unable to load or instantiate JPA aware resolver %s. All properties will per default be traversable.",
+                    JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME),
+                e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean needsCaching() {
+        return jpaTR != null && CachingTraversableResolver.needsCaching(jpaTR);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/JPATraversableResolver.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/JPATraversableResolver.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/JPATraversableResolver.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/JPATraversableResolver.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,53 @@
+/*
+ * 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.jsr.resolver;
+
+import javax.persistence.Persistence;
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+import java.lang.annotation.ElementType;
+
+/** @see javax.validation.TraversableResolver */
+public class JPATraversableResolver implements TraversableResolver, CachingRelevant {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, ElementType elementType) {
+        return traversableObject == null
+            || Persistence.getPersistenceUtil().isLoaded(traversableObject, traversableProperty.getName());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, ElementType elementType) {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean needsCaching() {
+        return true; // yes
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/SimpleTraversableResolver.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/SimpleTraversableResolver.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/SimpleTraversableResolver.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/resolver/SimpleTraversableResolver.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,57 @@
+/*
+ * 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.jsr.resolver;
+
+import javax.validation.Path;
+import javax.validation.TraversableResolver;
+import java.lang.annotation.ElementType;
+
+/**
+ * Description: traversable resolver that does always resolve.<br/>
+ */
+public class SimpleTraversableResolver implements TraversableResolver, CachingRelevant {
+    /**
+     * {@inheritDoc}
+     *  @return <code>true</code>
+     */
+    @Override
+    public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, java.lang.annotation.ElementType elementType) {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return <code>true</code>
+     */
+    @Override
+    public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
+        Path pathToTraversableObject, ElementType elementType) {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return <code>false</code>
+     */
+    @Override
+    public boolean needsCaching() {
+        return false; // no
+    }
+}

Added: 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=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/AnnotationsManager.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,432 @@
+/*
+ * 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.jsr.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Repeatable;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintDeclarationException;
+import javax.validation.ConstraintDefinitionException;
+import javax.validation.ConstraintTarget;
+import javax.validation.OverridesAttribute;
+import javax.validation.Payload;
+import javax.validation.ValidationException;
+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;
+import org.apache.bval.jsr.metadata.Meta;
+import org.apache.bval.jsr.xml.AnnotationProxyBuilder;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.ObjectUtils;
+import org.apache.bval.util.StringUtils;
+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;
+
+/**
+ * Manages (constraint) annotations according to the BV spec.
+ * 
+ * @since 2.0
+ */
+@Privilizing(@CallTo(Reflection.class))
+public class AnnotationsManager {
+    private static final class OverriddenAnnotationSpecifier {
+        final Class<? extends Annotation> annotationType;
+        final boolean impliesSingleComposingConstraint;
+        final int constraintIndex;
+
+        OverriddenAnnotationSpecifier(OverridesAttribute annotation) {
+            this(annotation.constraint(), annotation.constraintIndex());
+        }
+
+        OverriddenAnnotationSpecifier(Class<? extends Annotation> annotationType, int constraintIndex) {
+            super();
+            this.annotationType = annotationType;
+            this.impliesSingleComposingConstraint = constraintIndex < 0;
+            this.constraintIndex = Math.max(constraintIndex, 0);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj == null || !obj.getClass().equals(getClass())) {
+                return false;
+            }
+            final OverriddenAnnotationSpecifier other = (OverriddenAnnotationSpecifier) obj;
+            return Objects.equals(annotationType, other.annotationType) && constraintIndex == other.constraintIndex;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(annotationType, constraintIndex);
+        }
+    }
+
+    private static class Composition {
+        static <A extends Annotation> Optional<ConstraintAnnotationAttributes.Worker<A>> validWorker(
+            ConstraintAnnotationAttributes attr, Class<A> type) {
+            return Optional.of(type).map(attr::analyze).filter(Worker::isValid);
+        }
+
+        final Lazy<Map<OverriddenAnnotationSpecifier, Map<String, String>>> overrides = new Lazy<>(HashMap::new);
+        final Annotation[] components;
+
+        Composition(Class<? extends Annotation> annotationType) {
+            // TODO detect recursion
+            components = getDeclaredConstraints(annotationType);
+
+            if (!isComposed()) {
+                return;
+            }
+            final Map<Class<? extends Annotation>, AtomicInteger> constraintCounts = new HashMap<>();
+            for (Annotation a : components) {
+                constraintCounts.computeIfAbsent(a.annotationType(), k -> new AtomicInteger()).incrementAndGet();
+            }
+            // create a map of overridden constraints to overridden attributes:
+            for (Method m : Reflection.getDeclaredMethods(annotationType)) {
+                final String from = m.getName();
+                for (OverridesAttribute overridesAttribute : m.getDeclaredAnnotationsByType(OverridesAttribute.class)) {
+                    final String to =
+                        Optional.of(overridesAttribute.name()).filter(StringUtils::isNotBlank).orElse(from);
+
+                    final OverriddenAnnotationSpecifier spec = new OverriddenAnnotationSpecifier(overridesAttribute);
+                    final int count = constraintCounts.get(spec.annotationType).get();
+
+                    if (spec.impliesSingleComposingConstraint) {
+                        Exceptions.raiseUnless(count == 1, ConstraintDefinitionException::new,
+                            "Expected a single composing %s constraint", spec.annotationType);
+                    } else if (count <= spec.constraintIndex) {
+                        Exceptions.raise(ConstraintDefinitionException::new,
+                            "Expected at least %s composing %s constraints", spec.constraintIndex + 1,
+                            spec.annotationType);
+                    }
+                    final Map<String, String> attributeMapping =
+                        overrides.get().computeIfAbsent(spec, k -> new HashMap<>());
+
+                    if (attributeMapping.containsKey(to)) {
+                        Exceptions.raise(ConstraintDefinitionException::new,
+                            "Attempt to override %s#%s() index %d from multiple sources",
+                            overridesAttribute.constraint(), to, overridesAttribute.constraintIndex());
+                    }
+                    attributeMapping.put(to, from);
+                }
+            }
+        }
+
+        boolean isComposed() {
+            return components.length > 0;
+        }
+
+        Annotation[] getComponents(Annotation source) {
+            final Class<?>[] groups =
+                ConstraintAnnotationAttributes.GROUPS.analyze(source.annotationType()).read(source);
+
+            final Class<? extends Payload>[] payload =
+                ConstraintAnnotationAttributes.PAYLOAD.analyze(source.annotationType()).read(source);
+
+            final Optional<ConstraintTarget> constraintTarget =
+                validWorker(ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO, source.annotationType())
+                    .map(w -> w.read(source));
+
+            final Map<Class<? extends Annotation>, AtomicInteger> constraintCounts = new HashMap<>();
+
+            return Stream.of(components).map(c -> {
+                final int index =
+                    constraintCounts.computeIfAbsent(c.annotationType(), k -> new AtomicInteger()).getAndIncrement();
+
+                final AnnotationProxyBuilder<Annotation> proxyBuilder = new AnnotationProxyBuilder<>(c);
+
+                proxyBuilder.setGroups(groups);
+                proxyBuilder.setPayload(payload);
+
+                if (constraintTarget.isPresent()
+                    && validWorker(ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO, c.annotationType())
+                        .isPresent()) {
+                    proxyBuilder.setValidationAppliesTo(constraintTarget.get());
+                }
+                overrides.optional().map(o -> o.get(new OverriddenAnnotationSpecifier(c.annotationType(), index)))
+                    .ifPresent(m -> {
+                        final Map<String, Object> sourceAttributes = readAttributes(source);
+                        m.forEach((k, v) -> proxyBuilder.setValue(k, sourceAttributes.get(v)));
+                    });
+                return proxyBuilder.isChanged() ? proxyBuilder.createAnnotation() : c;
+            }).toArray(Annotation[]::new);
+        }
+    }
+
+    private static final Set<ConstraintAnnotationAttributes> CONSTRAINT_ATTRIBUTES =
+        Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(ConstraintAnnotationAttributes.VALUE)));
+
+    private static final Set<Class<? extends Annotation>> VALIDATED_CONSTRAINT_TYPES = new HashSet<>();
+
+    public static Map<String, Object> readAttributes(Annotation a) {
+        final Lazy<Map<String, Object>> result = new Lazy<>(LinkedHashMap::new);
+
+        Stream.of(Reflection.getDeclaredMethods(a.annotationType())).filter(m -> m.getParameterCount() == 0)
+            .forEach(m -> {
+                final boolean mustUnset = Reflection.setAccessible(m, true);
+                try {
+                    result.get().put(m.getName(), m.invoke(a));
+                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                    Exceptions.raise(ValidationException::new, e, "Caught exception reading attributes of %s", a);
+                } finally {
+                    if (mustUnset) {
+                        Reflection.setAccessible(m, false);
+                    }
+                }
+            });
+        return result.optional().map(Collections::unmodifiableMap).orElseGet(Collections::emptyMap);
+    }
+
+    public static boolean isAnnotationDirectlyPresent(AnnotatedElement e, Class<? extends Annotation> t) {
+        return substitute(e).filter(s -> s.isAnnotationPresent(t)).isPresent();
+    }
+
+    public static <T extends Annotation> T getAnnotation(AnnotatedElement e, Class<T> annotationClass) {
+        return substitute(e).map(s -> s.getAnnotation(annotationClass)).orElse(null);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T extends Annotation> T[] getDeclaredAnnotationsByType(AnnotatedElement e,
+        Class<T> annotationClass) {
+        return substitute(e).map(s -> s.getDeclaredAnnotationsByType(annotationClass))
+            .orElse((T[]) ObjectUtils.EMPTY_ANNOTATION_ARRAY);
+    }
+
+    /**
+     * Accounts for {@link Constraint} meta-annotation AND {@link Repeatable}
+     * constraint annotations.
+     * 
+     * @param meta
+     * @return Annotation[]
+     */
+    public static Annotation[] getDeclaredConstraints(Meta<?> meta) {
+        return getDeclaredConstraints(meta.getHost());
+    }
+
+    private static Annotation[] getDeclaredConstraints(AnnotatedElement e) {
+        final Annotation[] declaredAnnotations =
+            substitute(e).map(AnnotatedElement::getDeclaredAnnotations).orElse(ObjectUtils.EMPTY_ANNOTATION_ARRAY);
+        
+        if (declaredAnnotations.length == 0) {
+            return declaredAnnotations;
+        }
+        // collect constraint explicitly nested into repeatable containers:
+        final Map<Class<? extends Annotation>, Annotation[]> repeated = new HashMap<>();
+
+        for (Annotation a : declaredAnnotations) {
+            final Class<? extends Annotation> annotationType = a.annotationType();
+            final Worker<? extends Annotation> w = ConstraintAnnotationAttributes.VALUE.analyze(annotationType);
+            if (w.isValid()
+                && ((Class<?>) w.getSpecificType()).getComponentType().isAnnotationPresent(Constraint.class)) {
+                repeated.put(annotationType, w.read(a));
+            }
+        }
+        Stream<Annotation> constraints = Stream.of(declaredAnnotations)
+                .filter(a -> a.annotationType().isAnnotationPresent(Constraint.class));
+
+        if (!repeated.isEmpty()) {
+            constraints = constraints.peek(c -> Exceptions.raiseIf(
+                Optional.of(c.annotationType()).map(t -> t.getAnnotation(Repeatable.class)).map(Repeatable::value)
+                    .filter(repeated::containsKey).isPresent(),
+                ConstraintDeclarationException::new,
+                "Simultaneous declaration of repeatable constraint and associated container on %s", e));
+
+            constraints = Stream.concat(constraints, repeated.values().stream().flatMap(Stream::of));
+        }
+        return constraints.toArray(Annotation[]::new);
+    }
+    
+
+    private static Optional<AnnotatedElement> substitute(AnnotatedElement e) {
+        if (e instanceof Parameter) {
+            final Parameter p = (Parameter) e;
+            if (p.getDeclaringExecutable() instanceof Constructor<?>) {
+                final Constructor<?> ctor = (Constructor<?>) p.getDeclaringExecutable();
+                final Class<?> dc = ctor.getDeclaringClass();
+                if (!(dc.getDeclaringClass() == null || Modifier.isStatic(dc.getModifiers()))) {
+                    // found ctor for non-static inner class
+                    final Annotation[][] parameterAnnotations = ctor.getParameterAnnotations();
+                    if (parameterAnnotations.length == ctor.getParameterCount() - 1) {
+                        final Parameter[] parameters = ctor.getParameters();
+                        final int idx = ObjectUtils.indexOf(parameters, p);
+                        if (idx == 0) {
+                            return Optional.empty();
+                        }
+                        return Optional.of(parameters[idx - 1]);
+                    }
+                    Validate.validState(parameterAnnotations.length == ctor.getParameterCount(),
+                            "Cannot make sense of parameter annotations of %s", ctor);
+                }
+            }
+        }
+        return Optional.of(e);
+    }
+
+    private final ApacheValidatorFactory validatorFactory;
+    private final LRUCache<Class<? extends Annotation>, Composition> compositions;
+
+    public AnnotationsManager(ApacheValidatorFactory validatorFactory) {
+        super();
+        this.validatorFactory = Validate.notNull(validatorFactory);
+        final String cacheSize =
+            validatorFactory.getProperties().get(ConfigurationImpl.Properties.CONSTRAINTS_CACHE_SIZE);
+        try {
+            compositions = new LRUCache<>(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);
+        }
+    }
+
+    public void validateConstraintDefinition(Class<? extends Annotation> type) {
+        if (VALIDATED_CONSTRAINT_TYPES.contains(type)) {
+            return;
+        }
+        Exceptions.raiseUnless(type.isAnnotationPresent(Constraint.class), ConstraintDefinitionException::new,
+            "%s is not a validation constraint", type);
+
+        final Set<ValidationTarget> supportedTargets = supportedTargets(type);
+
+        final Map<String, Method> attributes =
+            Stream.of(Reflection.getDeclaredMethods(type)).filter(m -> m.getParameterCount() == 0)
+                .collect(Collectors.toMap(Method::getName, Function.identity()));
+
+        if (supportedTargets.size() > 1
+            && !attributes.containsKey(ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO.getAttributeName())) {
+            Exceptions.raise(ConstraintDefinitionException::new,
+                "Constraint %s is both generic and cross-parameter but lacks %s attribute", type.getName(),
+                ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO);
+        }
+        for (ConstraintAnnotationAttributes attr : CONSTRAINT_ATTRIBUTES) {
+            if (attributes.containsKey(attr.getAttributeName())) {
+                Exceptions.raiseUnless(attr.analyze(type).isValid(), ConstraintDefinitionException::new,
+                    "%s declared invalid type for attribute %s", type, attr);
+
+                if (!attr.isValidDefaultValue(attributes.get(attr.getAttributeName()).getDefaultValue())) {
+                    Exceptions.raise(ConstraintDefinitionException::new,
+                        "%s declares invalid default value for attribute %s", type, attr);
+                }
+                if (attr == ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO) {
+                    if (supportedTargets.size() == 1) {
+                        Exceptions.raise(ConstraintDefinitionException::new,
+                            "Pure %s constraint %s should not declare attribute %s",
+                            supportedTargets.iterator().next(), type, attr);
+                    }
+                }
+            } else if (attr.isMandatory()) {
+                Exceptions.raise(ConstraintDefinitionException::new, "%s does not declare mandatory attribute %s",
+                    type, attr);
+            }
+            attributes.remove(attr.getAttributeName());
+        }
+        attributes.keySet().forEach(k -> Exceptions.raiseIf(k.startsWith("valid"),
+            ConstraintDefinitionException::new, "Invalid constraint attribute %s", k));
+
+        VALIDATED_CONSTRAINT_TYPES.add(type);
+    }
+
+    /**
+     * Retrieve the composing constraints for the specified constraint
+     * {@link Annotation}.
+     * 
+     * @param a
+     * @return {@link Annotation}[]
+     */
+    public Annotation[] getComposingConstraints(Annotation a) {
+        return getComposition(a.annotationType()).getComponents(a);
+    }
+
+    /**
+     * Learn whether {@code a} is composed.
+     * 
+     * @param a
+     * @return {@code boolean}
+     */
+    public boolean isComposed(Annotation a) {
+        return getComposition(a.annotationType()).isComposed();
+    }
+
+    /**
+     * Get the supported targets for {@code constraintType}.
+     * 
+     * @param constraintType
+     * @return {@link Set} of {@link ValidationTarget}
+     */
+    public <A extends Annotation> Set<ValidationTarget> supportedTargets(Class<A> constraintType) {
+        final Set<ConstraintValidatorInfo<A>> constraintValidatorInfo =
+            validatorFactory.getConstraintsCache().getConstraintValidatorInfo(constraintType);
+        final Stream<Set<ValidationTarget>> s;
+        if (constraintValidatorInfo.isEmpty()) {
+            // must be for composition:
+            s = Stream.of(new Composition(constraintType).components).map(Annotation::annotationType)
+                .map(this::supportedTargets);
+        } else {
+            s = constraintValidatorInfo.stream().map(ConstraintValidatorInfo::getSupportedTargets);
+        }
+        return s.flatMap(Collection::stream)
+            .collect(Collectors.toCollection(() -> EnumSet.noneOf(ValidationTarget.class)));
+    }
+
+    private Composition getComposition(Class<? extends Annotation> annotationType) {
+        return compositions.computeIfAbsent(annotationType, ct -> {
+            final Set<ValidationTarget> composedTargets = supportedTargets(annotationType);
+            final Composition result = new Composition(annotationType);
+            Stream.of(result.components).map(Annotation::annotationType).forEach(at -> {
+                final Set<ValidationTarget> composingTargets = supportedTargets(at);
+                if (Collections.disjoint(composingTargets, composedTargets)) {
+                    Exceptions.raise(ConstraintDefinitionException::new,
+                        "Attempt to compose %s of %s but validator types are incompatible", annotationType.getName(),
+                        at.getName());
+                }
+            });
+            return result;
+        });
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderCustomizableContextImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderCustomizableContextImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderCustomizableContextImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderCustomizableContextImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,67 @@
+/*
+ * 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.jsr.util;
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeContextBuilder;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext;
+
+import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;
+
+public class ContainerElementNodeBuilderCustomizableContextImpl
+    implements ContainerElementNodeBuilderCustomizableContext {
+    private final PathImpl path;
+    private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
+
+    public ContainerElementNodeBuilderCustomizableContextImpl(PathImpl path, String name, Class<?> containerType,
+        Integer typeArgumentIndex, ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
+        super();
+        this.builder = builder.ofLegalState();
+        this.path = path.addNode(new NodeImpl.ContainerElementNodeImpl(name, containerType, typeArgumentIndex));
+    }
+
+    @Override
+    public ContainerElementNodeContextBuilder inIterable() {
+        return new ContainerElementNodeContextBuilderImpl(path, builder);
+    }
+
+    @Override
+    public NodeBuilderCustomizableContext addPropertyNode(String name) {
+        return new NodeBuilderCustomizableContextImpl(path, name, builder);
+    }
+
+    @Override
+    public LeafNodeBuilderCustomizableContext addBeanNode() {
+        return new LeafNodeBuilderCustomizableContextImpl(path, builder);
+    }
+
+    @Override
+    public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
+        Integer typeArgumentIndex) {
+        path.addNode(new NodeImpl.ContainerElementNodeImpl(name, containerType, typeArgumentIndex));
+        return this;
+    }
+
+    @Override
+    public ConstraintValidatorContext addConstraintViolation() {
+        return builder.addConstraintViolation(path);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderDefinedContextImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderDefinedContextImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderDefinedContextImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeBuilderDefinedContextImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,61 @@
+/*
+ * 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.jsr.util;
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderDefinedContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext;
+
+import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;
+
+public class ContainerElementNodeBuilderDefinedContextImpl implements ContainerElementNodeBuilderDefinedContext {
+    private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
+    private final PathImpl path;
+
+    ContainerElementNodeBuilderDefinedContextImpl(PathImpl path,
+        ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
+        super();
+        this.path = path;
+        this.builder = builder.ofLegalState();
+    }
+
+    @Override
+    public NodeBuilderCustomizableContext addPropertyNode(String name) {
+        return new NodeBuilderCustomizableContextImpl(path, name, builder);
+    }
+
+    @Override
+    public LeafNodeBuilderCustomizableContext addBeanNode() {
+        return new LeafNodeBuilderCustomizableContextImpl(path, builder);
+    }
+
+    @Override
+    public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
+        Integer typeArgumentIndex) {
+        return new ContainerElementNodeBuilderCustomizableContextImpl(path, name, containerType, typeArgumentIndex,
+            builder);
+    }
+
+    @Override
+    public ConstraintValidatorContext addConstraintViolation() {
+        return builder.addConstraintViolation(path);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeContextBuilderImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeContextBuilderImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeContextBuilderImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ContainerElementNodeContextBuilderImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,75 @@
+/*
+ * 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.jsr.util;
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderDefinedContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeContextBuilder;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext;
+
+import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;
+
+public class ContainerElementNodeContextBuilderImpl implements ContainerElementNodeContextBuilder {
+    private final PathImpl path;
+    private ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
+
+    ContainerElementNodeContextBuilderImpl(PathImpl path,
+        ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
+        super();
+        this.builder = builder.ofLegalState();
+        this.path = path;
+        path.getLeafNode().inIterable();
+    }
+
+    @Override
+    public ContainerElementNodeBuilderDefinedContext atKey(Object key) {
+        path.getLeafNode().setKey(key);
+        return new ContainerElementNodeBuilderDefinedContextImpl(path, builder);
+    }
+
+    @Override
+    public ContainerElementNodeBuilderDefinedContext atIndex(Integer index) {
+        path.getLeafNode().setIndex(index);
+        return new ContainerElementNodeBuilderDefinedContextImpl(path, builder);
+    }
+
+    @Override
+    public NodeBuilderCustomizableContext addPropertyNode(String name) {
+        return new NodeBuilderCustomizableContextImpl(path, name, builder);
+    }
+
+    @Override
+    public LeafNodeBuilderCustomizableContext addBeanNode() {
+        return new LeafNodeBuilderCustomizableContextImpl(path, builder);
+    }
+
+    @Override
+    public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
+        Integer typeArgumentIndex) {
+        return new ContainerElementNodeBuilderCustomizableContextImpl(path, name, containerType, typeArgumentIndex,
+            builder);
+    }
+
+    @Override
+    public ConstraintValidatorContext addConstraintViolation() {
+        return builder.addConstraintViolation(path);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ExecutableTypes.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ExecutableTypes.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ExecutableTypes.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/ExecutableTypes.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,83 @@
+/*
+ * 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.jsr.util;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+import javax.validation.executable.ExecutableType;
+
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Validate;
+
+/**
+ * Utility methods relating to {@link ExecutableType}.
+ */
+public class ExecutableTypes {
+
+    private static final Set<ExecutableType> ALL_TYPES = Collections.unmodifiableSet(
+        EnumSet.of(ExecutableType.CONSTRUCTORS, ExecutableType.NON_GETTER_METHODS, ExecutableType.GETTER_METHODS));
+
+    private static final Set<ExecutableType> IMPLICIT_TYPES =
+        Collections.unmodifiableSet(EnumSet.of(ExecutableType.CONSTRUCTORS, ExecutableType.NON_GETTER_METHODS));
+
+    /**
+     * Interpret occurrences of {@link ExecutableType#ALL}, {@link ExecutableType#IMPLICIT}, and
+     * {@link ExecutableType#NONE}.
+     * 
+     * @param executableTypes
+     * @return (unmodifiable) {@link Set} of {@link ExecutableType}
+     */
+    public static Set<ExecutableType> interpret(Collection<ExecutableType> executableTypes) {
+        Validate.notNull(executableTypes);
+        if (executableTypes.isEmpty()) {
+            return Collections.emptySet();
+        }
+        final Set<ExecutableType> result = EnumSet.copyOf(executableTypes);
+        if (result.contains(ExecutableType.ALL)) {
+            return ALL_TYPES;
+        }
+        if (result.remove(ExecutableType.IMPLICIT)) {
+            if (!result.isEmpty()) {
+                Exceptions.raise(IllegalArgumentException::new, "Mixing %s with other %ss is illegal.",
+                    ExecutableType.IMPLICIT, ExecutableType.class.getSimpleName());
+            }
+            return IMPLICIT_TYPES;
+        }
+        result.remove(ExecutableType.NONE);
+        return result.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(result);
+    }
+
+    /**
+     * Interpret occurrences of {@link ExecutableType#ALL}, {@link ExecutableType#IMPLICIT}, and
+     * {@link ExecutableType#NONE}.
+     * 
+     * @param executableTypes
+     * @return (unmodifiable) {@link Set} of {@link ExecutableType}
+     */
+    public static Set<ExecutableType> interpret(ExecutableType... executableTypes) {
+        return interpret(Arrays.asList(executableTypes));
+    }
+
+    private ExecutableTypes() {
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/IOs.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/IOs.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/IOs.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/IOs.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,59 @@
+/*
+ * 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.jsr.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class IOs {
+    private IOs() {
+        // no-op
+    }
+
+    public static InputStream convertToMarkableInputStream(final InputStream stream) {
+        if (stream == null) {
+            return null;
+        }
+        try (InputStream in = stream) {
+            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            final byte[] buffer = new byte[1024];
+            int length;
+            while ((length = in.read(buffer)) != -1) {
+                baos.write(buffer, 0, length);
+            }
+            return new ByteArrayInputStream(baos.toByteArray());
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    //TODO see if needed
+    public static void closeQuietly(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (IOException e) {
+                // do nothing
+            }
+        }
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LRUCache.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LRUCache.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LRUCache.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LRUCache.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,41 @@
+/*
+ * 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.jsr.util;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class LRUCache<K, V> extends LinkedHashMap<K, V> {
+    private static final long serialVersionUID = 1L;
+
+    private final int maximumCapacity;
+
+    public LRUCache(int maximumCapacity) {
+        super(16, 0.75f, true);
+        if (maximumCapacity < 1) {
+            throw new IllegalArgumentException("maximumCapacity must be > 0");
+        }
+        this.maximumCapacity = maximumCapacity;
+    }
+
+    @Override
+    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+        return super.removeEldestEntry(eldest) || size() >= maximumCapacity;
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LeafNodeBuilderCustomizableContextImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LeafNodeBuilderCustomizableContextImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LeafNodeBuilderCustomizableContextImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/LeafNodeBuilderCustomizableContextImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,85 @@
+/*
+ * 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.jsr.util;
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderDefinedContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeContextBuilder;
+
+import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;
+
+public class LeafNodeBuilderCustomizableContextImpl
+    implements ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext {
+
+    private final class LeafNodeContextBuilderImpl implements LeafNodeContextBuilder {
+        private final LeafNodeBuilderDefinedContext definedContext = new LeafNodeBuilderDefinedContext() {
+
+            @Override
+            public ConstraintValidatorContext addConstraintViolation() {
+                return LeafNodeBuilderCustomizableContextImpl.this.addConstraintViolation();
+            }
+        };
+
+        @Override
+        public LeafNodeBuilderDefinedContext atKey(Object key) {
+            path.getLeafNode().setKey(key);
+            return definedContext;
+        }
+
+        @Override
+        public LeafNodeBuilderDefinedContext atIndex(Integer index) {
+            path.getLeafNode().setIndex(index);
+            return definedContext;
+        }
+
+        @Override
+        public ConstraintValidatorContext addConstraintViolation() {
+            return LeafNodeBuilderCustomizableContextImpl.this.addConstraintViolation();
+        }
+    }
+
+    private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
+    private final PathImpl path;
+
+    public LeafNodeBuilderCustomizableContextImpl(
+        PathImpl path, ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
+        this.builder = builder.ofLegalState();
+        this.path = path.addBean();
+    }
+
+    @Override
+    public LeafNodeContextBuilder inIterable() {
+        builder.ofLegalState();
+        path.getLeafNode().setInIterable(true);
+        return new LeafNodeContextBuilderImpl();
+    }
+
+    @Override
+    public ConstraintValidatorContext addConstraintViolation() {
+        return builder.addConstraintViolation(path);
+    }
+
+    @Override
+    public LeafNodeBuilderCustomizableContext inContainer(Class<?> containerType, Integer typeArgumentIndex) {
+        builder.ofLegalState();
+        path.getLeafNode().inContainer(containerType, typeArgumentIndex);
+        return this;
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Methods.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Methods.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Methods.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/Methods.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,66 @@
+/*
+ *  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.jsr.util;
+
+import java.beans.Introspector;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.stream.Stream;
+
+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;
+
+@Privilizing(@CallTo(Reflection.class))
+public final class Methods {
+    public static boolean isGetter(Method m) {
+        if (Modifier.isStatic(m.getModifiers()) || m.getParameterCount() > 0) {
+            return false;
+        }
+        // TODO look for capital letter after verb?
+        if (Boolean.TYPE.equals(m.getReturnType()) && m.getName().length() > 2 && m.getName().startsWith("is")) {
+            return true;
+        }
+        return !Void.TYPE.equals(m.getReturnType()) && m.getName().length() > 3 && m.getName().startsWith("get");
+    }
+
+    public static boolean isGetter(String methodName) {
+        Validate.notNull(methodName);
+        final int len = methodName.length();
+        return len > 2 && methodName.startsWith("is") || len > 3 && methodName.startsWith("get");
+    }
+
+    public static String propertyName(Method getter) {
+        Validate.isTrue(isGetter(getter), "%s is not a getter", getter);
+        return propertyName(getter.getName());
+    }
+
+    public static String propertyName(String methodName) {
+        Validate.isTrue(isGetter(methodName), "%s does not represent a property getter", methodName);
+        final String suffix = methodName.startsWith("is") ? methodName.substring(2) : methodName.substring(3);
+        return Introspector.decapitalize(suffix);
+    }
+
+    public static Method getter(Class<?> clazz, String property) {
+        return Reflection.find(clazz, t -> Stream.of(Reflection.getDeclaredMethods(t)).filter(Methods::isGetter)
+            .filter(m -> property.equals(Methods.propertyName(m))).findFirst().orElse(null));
+    }
+
+    private Methods() {
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderCustomizableContextImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderCustomizableContextImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderCustomizableContextImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderCustomizableContextImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,99 @@
+/*
+ * 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.jsr.util;
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext;
+
+import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;
+
+/**
+ * Description: implementation of
+ * {@link javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext}.<br/>
+ */
+public final class NodeBuilderCustomizableContextImpl
+    implements ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext {
+    private final PathImpl path;
+    private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
+
+    /**
+     * Create a new NodeBuilderCustomizableContextImpl instance.
+     * 
+     * @param path
+     * @param name
+     * @param builder
+     */
+    public NodeBuilderCustomizableContextImpl(PathImpl path, String name,
+        ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
+        this.builder = builder.ofLegalState();
+        this.path = path.addProperty(name);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeContextBuilder inIterable() {
+        return new NodeContextBuilderImpl(path, builder);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(String name) {
+        return addPropertyNode(name);
+    }
+
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addPropertyNode(
+        String name) {
+        builder.ofLegalState();
+        path.addProperty(name);
+        return this;
+    }
+
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext addBeanNode() {
+        return new LeafNodeBuilderCustomizableContextImpl(path, builder);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext addConstraintViolation() {
+        return builder.addConstraintViolation(path);
+    }
+
+    @Override
+    public NodeBuilderCustomizableContext inContainer(Class<?> containerClass, Integer typeArgumentIndex) {
+        builder.ofLegalState();
+        path.getLeafNode().inContainer(containerClass, typeArgumentIndex);
+        return this;
+    }
+
+    @Override
+    public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
+        Integer typeArgumentIndex) {
+        return new ContainerElementNodeBuilderCustomizableContextImpl(path, name, containerType, typeArgumentIndex,
+            builder);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderDefinedContextImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderDefinedContextImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderDefinedContextImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeBuilderDefinedContextImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,79 @@
+/*
+ * 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.jsr.util;
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderCustomizableContext;
+
+import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;
+
+/**
+ * Description: Implementation of {@link NodeBuilderDefinedContext}.<br/>
+ */
+public final class NodeBuilderDefinedContextImpl
+    implements ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext {
+    private final PathImpl path;
+    private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
+
+    /**
+     * Create a new NodeBuilderDefinedContextImpl instance.
+     * 
+     * @param path
+     * @param builder
+     */
+    public NodeBuilderDefinedContextImpl(PathImpl path,
+        ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
+        this.path = path;
+        this.builder = builder.ofLegalState();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(String name) {
+        return addPropertyNode(name);
+    }
+
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addPropertyNode(
+        String name) {
+        return new NodeBuilderCustomizableContextImpl(path, name, builder);
+    }
+
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext addBeanNode() {
+        return new LeafNodeBuilderCustomizableContextImpl(path, builder);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext addConstraintViolation() {
+        return builder.addConstraintViolation(path);
+    }
+
+    @Override
+    public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
+        Integer typeArgumentIndex) {
+        return new ContainerElementNodeBuilderCustomizableContextImpl(path, name, containerType, typeArgumentIndex,
+            builder);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeContextBuilderImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeContextBuilderImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeContextBuilderImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/util/NodeContextBuilderImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,98 @@
+/*
+ * 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.jsr.util;
+
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.ContainerElementNodeBuilderCustomizableContext;
+import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeContextBuilder;
+
+import org.apache.bval.jsr.job.ConstraintValidatorContextImpl;
+
+/**
+ * Description: Implementation of {@link NodeContextBuilder}.<br/>
+ */
+public final class NodeContextBuilderImpl
+    implements ConstraintValidatorContext.ConstraintViolationBuilder.NodeContextBuilder {
+    private final ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder;
+    private final PathImpl path;
+
+    /**
+     * Create a new NodeContextBuilderImpl instance.
+     * 
+     * @param path
+     * @param builder
+     */
+    NodeContextBuilderImpl(PathImpl path, ConstraintValidatorContextImpl<?>.ConstraintViolationBuilderImpl builder) {
+        this.builder = builder.ofLegalState();
+        this.path = path;
+        path.getLeafNode().inIterable();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext atKey(Object key) {
+        path.getLeafNode().setKey(key);
+        return new NodeBuilderDefinedContextImpl(path, builder);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext atIndex(Integer index) {
+        path.getLeafNode().setIndex(index);
+        return new NodeBuilderDefinedContextImpl(path, builder);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addNode(String name) {
+        return addPropertyNode(name);
+    }
+
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext addPropertyNode(
+        String name) {
+        return new NodeBuilderCustomizableContextImpl(path, name, builder);
+    }
+
+    @Override
+    public ConstraintValidatorContext.ConstraintViolationBuilder.LeafNodeBuilderCustomizableContext addBeanNode() {
+        return new LeafNodeBuilderCustomizableContextImpl(path, builder);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConstraintValidatorContext addConstraintViolation() {
+        return builder.addConstraintViolation(path);
+    }
+
+    @Override
+    public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name, Class<?> containerType,
+        Integer typeArgumentIndex) {
+        return new ContainerElementNodeBuilderCustomizableContextImpl(path, name, containerType, typeArgumentIndex,
+            builder);
+    }
+}