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 [8/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/m...

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ReturnValueD.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ReturnValueD.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ReturnValueD.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/ReturnValueD.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,36 @@
+/*
+ * 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.descriptor;
+
+import java.lang.reflect.Executable;
+
+import javax.validation.metadata.ReturnValueDescriptor;
+
+public class ReturnValueD<P extends ExecutableD<?, ?, P>, E extends Executable> extends CascadableContainerD<P, E>
+    implements ReturnValueDescriptor {
+
+    ReturnValueD(MetadataReader.ForContainer<E> reader, P parent) {
+        super(reader, parent);
+    }
+
+    @Override
+    public Class<?> getElementClass() {
+        return parent.getElementClass();
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/package-info.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/package-info.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/package-info.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/package-info.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,21 @@
+/*
+ *  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.
+ */
+/**
+ * This package houses the implementations and related classes for BV element descriptors, using the {@code D} suffix to
+ * succinctly denote implementations of {@code *Descriptor}.
+ */
+package org.apache.bval.jsr.descriptor;
\ No newline at end of file

Added: 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=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,189 @@
+/*
+ * 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.groups;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.validation.GroupDefinitionException;
+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.
+ */
+public final class Group implements GroupStrategy {
+    /**
+     * Models a group sequence.
+     */
+    public static final class Sequence extends GroupStrategy.Composite {
+        private static Set<Group> validGroups(Collection<Group> groups, Function<Group, ? extends GroupStrategy> mapper) {
+            final Set<Group> result = new LinkedHashSet<>();
+            final ObjectWrapper<Group> prev = new ObjectWrapper<>();
+
+            groups.stream().map(g -> Optional.of(g).<GroupStrategy> map(mapper).orElse(g)).map(GroupStrategy::getGroups)
+                .flatMap(Collection::stream).forEach(g -> {
+                    // only permit duplicates if they are contiguous:
+                    if (result.add(g)) {
+                        prev.accept(g);
+                        return;
+                    }
+                    if (!g.equals(prev.get())) {
+                        Exceptions.raise(GroupDefinitionException::new, "Invalid group sequence %s specified", groups);
+                    }
+                });
+            return result;
+        }
+
+        private final Set<Group> groups;
+
+        private Sequence(Collection<Group> groups) {
+            super(groups, true);
+            this.groups = Collections.unmodifiableSet(validGroups(groups, Function.identity()));
+        }
+
+        @Override
+        public Set<Group> getGroups() {
+            return groups;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("Group sequence: %s", groups);
+        }
+
+        @Override
+        public GroupStrategy redefining(Map<Group, ? extends GroupStrategy> redefinitions) {
+            if (Collections.disjoint(redefinitions.keySet(), groups)) {
+                return this;
+            }
+            final Set<GroupStrategy> components = new LinkedHashSet<>();
+
+            final Set<Group> mappedGroups;
+            try {
+                mappedGroups = validGroups(groups, g -> {
+                    final GroupStrategy result = Optional.of(g).<GroupStrategy> map(redefinitions::get).orElse(g);
+                    components.add(result);
+                    return result;
+                });
+            } catch (GroupDefinitionException e) {
+                throw Exceptions.create(GroupDefinitionException::new, "Could not expand %s using %s", this,
+                    redefinitions);
+            }
+            if (components.equals(mappedGroups)) {
+                return new Sequence(mappedGroups);
+            }
+            return new GroupStrategy.Composite(components, ordered);
+        }
+    }
+
+    /**
+     * the Default Group
+     */
+    public static final Group DEFAULT = new Group(Default.class);
+
+    public static final Group of(Class<?> group) {
+        return new Group(group);
+    }
+
+    public static final Sequence sequence(Group... groups) {
+        return sequence(Arrays.asList(groups));
+    }
+
+    public static final Sequence sequence(Collection<Group> groups) {
+        return new Sequence(groups);
+    }
+
+    private final Class<?> group;
+
+    /**
+     * Create a new Group instance.
+     * @param group
+     */
+    public Group(Class<?> group) {
+        this.group = Validate.notNull(group);
+    }
+
+    /**
+     * Get the actual group class.
+     * @return
+     */
+    public Class<?> getGroup() {
+        return group;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return String.format("%s{group=%s}", Group.class.getSimpleName(), group);
+    }
+
+    /**
+     * Learn whether the group represented is the default group.
+     * @return boolean
+     */
+    public boolean isDefault() {
+        return Default.class.equals(group);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object o) {
+        return this == o || o != null && getClass().equals(o.getClass()) && Objects.equals(group, ((Group) o).group);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        return group.hashCode();
+    }
+
+    @Override
+    public Set<Group> getGroups() {
+        return Collections.singleton(this);
+    }
+
+    @Override
+    public boolean applyTo(Predicate<GroupStrategy> operation) {
+        return operation.test(this);
+    }
+
+    @Override
+    public GroupStrategy redefining(Map<Group, ? extends GroupStrategy> redefinitions) {
+        final GroupStrategy redefined = redefinitions.get(this);
+        return redefined == null ? this : redefined;
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversion.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversion.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversion.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversion.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.groups;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import javax.validation.metadata.GroupConversionDescriptor;
+
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.LazyInt;
+import org.apache.bval.util.Validate;
+
+public class GroupConversion implements GroupConversionDescriptor {
+    public static class Builder {
+        private final Class<?> from;
+
+        private Builder(Class<?> from) {
+            this.from = from;
+        }
+
+        public GroupConversion to(Class<?> to) {
+            return new GroupConversion(from, to);
+        }
+    }
+
+    public static Builder from(Class<?> from) {
+        return new Builder(from);
+    }
+
+    private final Class<?> from;
+    private final Class<?> to;
+    private final LazyInt hashCode;
+    private final Lazy<String> toString;
+
+    private GroupConversion(Class<?> from, Class<?> to) {
+        super();
+        this.from = Validate.notNull(from, "from");
+        this.to = Validate.notNull(to, "to");
+        this.hashCode = new LazyInt(() -> Objects.hash(this.from, this.to));
+        this.toString = new Lazy<>(
+            () -> String.format("%s from %s to %s", GroupConversion.class.getSimpleName(), this.from, this.to));
+    }
+
+    @Override
+    public Class<?> getFrom() {
+        return from;
+    }
+
+    @Override
+    public Class<?> getTo() {
+        return to;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj == this
+            || Optional.ofNullable(obj).filter(GroupConversion.class::isInstance).map(GroupConversion.class::cast)
+                .filter(gc -> Objects.equals(from, gc.from) && Objects.equals(to, gc.to)).isPresent();
+    }
+
+    @Override
+    public int hashCode() {
+        return hashCode.getAsInt();
+    }
+
+    @Override
+    public String toString() {
+        return toString.get();
+    }
+}

Added: 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=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupStrategy.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupStrategy.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,241 @@
+/*
+ * 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.groups;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Consumer;
+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.
+ */
+public interface GroupStrategy {
+    public static class Simple implements GroupStrategy {
+        private final Set<Group> groups;
+
+        private Simple(Set<Group> groups) {
+            this.groups = groups;
+        }
+
+        @Override
+        public Set<Group> getGroups() {
+            return groups;
+        }
+
+        @Override
+        public GroupStrategy redefining(Map<Group, ? extends GroupStrategy> redefinitions) {
+            if (Collections.disjoint(redefinitions.keySet(), groups)) {
+                return this;
+            }
+            return groups.stream().map(g -> redefinitions.containsKey(g) ? redefinitions.get(g) : g)
+                .collect(Collectors.collectingAndThen(Collectors.toList(), GroupStrategy::composite));
+        }
+
+        @Override
+        public int hashCode() {
+            return groups.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj == this
+                || obj != null && obj.getClass().equals(getClass()) && ((Simple) obj).groups.equals(groups);
+        }
+
+        @Override
+        public String toString() {
+            return groups.toString();
+        }
+    }
+
+    public static class Composite implements GroupStrategy {
+        private final Set<? extends GroupStrategy> components;
+        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;
+        }
+
+        @Override
+        public Set<Group> getGroups() {
+            return components.stream().map(GroupStrategy::getGroups).flatMap(Collection::stream)
+                .collect(ToUnmodifiable.set());
+        }
+
+        @Override
+        public GroupStrategy redefining(Map<Group, ? extends GroupStrategy> redefinitions) {
+            if (!components.isEmpty()) {
+                final Set<GroupStrategy> redef =
+                    components.stream().map(cmp -> cmp.redefining(redefinitions)).collect(Collectors.toSet());
+                if (!redef.equals(components)) {
+                    return new Composite(redef, ordered);
+                }
+            }
+            return this;
+        }
+
+        @Override
+        public boolean applyTo(Predicate<GroupStrategy> operation) {
+            if (components.isEmpty()) {
+                return true;
+            }
+            final boolean applyAll = !ordered;
+            boolean result = true;
+            for (GroupStrategy gs : components) {
+                result = gs.applyTo(operation) && result;
+                if (!(applyAll || result)) {
+                    return false;
+                }
+            }
+            return result;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(components, ordered);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null || !obj.getClass().equals(getClass())) {
+                return false;
+            }
+            final Composite other = (Composite) obj;
+            return other.components.equals(components) && other.ordered == ordered;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%sordered: %s", ordered ? "" : "un", components);
+        }
+    }
+
+    public static final GroupStrategy EMPTY = new GroupStrategy() {
+
+        @Override
+        public GroupStrategy redefining(Map<Group, ? extends GroupStrategy> redefinitions) {
+            return this;
+        }
+
+        @Override
+        public Set<Group> getGroups() {
+            return Collections.emptySet();
+        }
+    };
+
+    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)
+                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+            }
+            if (!redefinitions.isEmpty()) {
+                return source.redefining(redefinitions);
+            }
+        }
+        return source;
+    }
+
+    public static GroupStrategy simple(Group... groups) {
+        return simple(Arrays.asList(groups));
+    }
+
+    public static GroupStrategy simple(Collection<? extends Group> coll) {
+        Validate.notNull(coll);
+        if (coll.size() == 1) {
+            return coll.iterator().next();
+        }
+        final Set<Group> groups = Collections.unmodifiableSet(new LinkedHashSet<>(coll));
+        return new Simple(groups);
+    }
+
+    public static GroupStrategy composite(GroupStrategy... components) {
+        return composite(Arrays.asList(components));
+    }
+
+    public static GroupStrategy composite(Collection<? extends GroupStrategy> components) {
+        if (components.isEmpty()) {
+            return EMPTY;
+        }
+        if (components.size() == 1) {
+            return components.iterator().next();
+        }
+        final Set<GroupStrategy> compressedComponents = new LinkedHashSet<>();
+
+        final Consumer<Set<Group>> addGroups = s -> {
+            if (!s.isEmpty()) {
+                compressedComponents.add(simple(s));
+                s.clear();
+            }
+        };
+        final Set<Group> unorderedGroups = new HashSet<>();
+        for (GroupStrategy component : components) {
+            if (component instanceof Composite && ((Composite) component).ordered) {
+                addGroups.accept(unorderedGroups);
+                compressedComponents.add(component);
+                continue;
+            }
+            unorderedGroups.addAll(component.getGroups());
+        }
+        addGroups.accept(unorderedGroups);
+        if (compressedComponents.size() == 1) {
+            return compressedComponents.iterator().next();
+        }
+        return new Composite(compressedComponents, false);
+    }
+
+    /**
+     * Get the associated groups.
+     * @return {@link Set} of {@link Group}
+     */
+    Set<Group> getGroups();
+
+    /**
+     * Get an equivalent strategy making group substitutions specified by {@code redefinitions}.
+     * @param redefinitions
+     * @return {@link GroupStrategy}
+     */
+    GroupStrategy redefining(Map<Group, ? extends GroupStrategy> redefinitions);
+
+    /**
+     * Apply the specified {@code boolean}-returning {@code operation}.
+     * @param operation
+     * @return {@code boolean}
+     */
+    default boolean applyTo(Predicate<GroupStrategy> operation) {
+        return operation.test(this);
+    }
+}

Added: 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=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,128 @@
+/*
+ * 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.groups;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+
+import javax.validation.GroupDefinitionException;
+
+import org.apache.bval.util.Exceptions;
+
+/**
+ * Defines the order to validate groups during validation. with some inspiration from reference implementation
+ *
+ * @author Roman Stumm
+ */
+public class Groups {
+    private final Set<Group> groups = new LinkedHashSet<>();
+    private final Set<Group.Sequence> sequences = new LinkedHashSet<>();
+
+    /**
+     * Get the Groups.
+     * 
+     * @return {@link Set} of {@link Group}.
+     */
+    public Set<Group> getGroups() {
+        return Collections.unmodifiableSet(groups);
+    }
+
+    /**
+     * Get the Group sequences.
+     * 
+     * @return {@link List} of {@link Group.Sequence}
+     */
+    public Collection<Group.Sequence> getSequences() {
+        return Collections.unmodifiableSet(sequences);
+    }
+
+    /**
+     * Insert a {@link Group}.
+     * 
+     * @param group
+     *            to insert
+     * @return success
+     */
+    boolean insertGroup(Group group) {
+        return groups.add(group);
+    }
+
+    /**
+     * Insert a sequence.
+     * 
+     * @param groups
+     *            {@link List} of {@link Group} to insert
+     * @return success
+     */
+    boolean insertSequence(Collection<Group> groups) {
+        return !(groups == null || groups.isEmpty()) && sequences.add(Group.sequence(groups));
+    }
+
+    /**
+     * Assert that the default group can be expanded to <code>defaultGroups</code>.
+     * 
+     * @param defaultGroups
+     */
+    @Deprecated
+    public void assertDefaultGroupSequenceIsExpandable(List<Group> defaultGroups) {
+        Consumer<List<Group>> action = (groupList) -> {
+            final int idx = groupList.indexOf(Group.DEFAULT);
+            if (idx >= 0) {
+                ensureExpandable(groupList, defaultGroups, idx);
+            }
+        };
+        sequences.stream().map(Group.Sequence::getGroups).map(ArrayList::new).forEach(action);
+    }
+
+    private void ensureExpandable(List<Group> groupList, List<Group> defaultGroupList, int defaultGroupIndex) {
+        for (int i = 0, sz = defaultGroupList.size(); i < sz; i++) {
+            final Group group = defaultGroupList.get(i);
+            if (group.isDefault()) {
+                continue; // the default group is the one we want to replace
+            }
+            // sequence contains group of default group sequence
+            final int index = groupList.indexOf(group);
+            if (index < 0) {
+                // group is not in the sequence
+                continue;
+            }
+            if ((i == 0 && index == defaultGroupIndex - 1)
+                || (i == defaultGroupList.size() - 1 && index == defaultGroupIndex + 1)) {
+                // if we are at the beginning or end of he defaultGroupSequence
+                // and the matches are either directly before or after we can
+                // continue, since we basically have two groups
+                continue;
+            }
+            Exceptions.raise(GroupDefinitionException::new, "Unable to expand default group list %s into sequence %s",
+                defaultGroupList, groupList);
+        }
+    }
+
+    public GroupStrategy asStrategy() {
+        final List<GroupStrategy> components = new ArrayList<>();
+        components.addAll(groups);
+        components.addAll(sequences);
+        return GroupStrategy.composite(components);
+    }
+}
\ No newline at end of file

Added: 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=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,196 @@
+/*
+ * 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.groups;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.GroupDefinitionException;
+import javax.validation.GroupSequence;
+import javax.validation.ValidationException;
+import javax.validation.groups.Default;
+import javax.validation.metadata.GroupConversionDescriptor;
+
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Validate;
+
+/**
+ * Description: compute group order, based on the RI behavior as to guarantee
+ * compatibility with interpretations of the spec.<br/>
+ * Implementation is thread-safe.
+ */
+public class GroupsComputer {
+    public static final Class<?>[] DEFAULT_GROUP = { Default.class };
+
+    /**
+     * The default group array used in case any of the validate methods is
+     * called without a group.
+     */
+    public static final Groups DEFAULT_GROUPS;
+    static {
+        DEFAULT_GROUPS = new Groups();
+        for (Class<?> g : DEFAULT_GROUP) {
+            DEFAULT_GROUPS.insertGroup(new Group(g));
+        }
+    }
+
+    /** caching resolved groups in a thread-safe map. */
+    private final Map<Class<?>, List<Group>> resolvedSequences = new ConcurrentHashMap<>();
+
+    /**
+     * Compute groups from an array of group classes.
+     * 
+     * @param groups
+     * @return {@link Groups}
+     */
+    @SafeVarargs
+    public final Groups computeGroups(Class<?>... groups) {
+        Exceptions.raiseIf(groups == null, IllegalArgumentException::new, "null validation groups specified");
+        return computeGroups(Arrays.asList(groups));
+    }
+
+    /**
+     * Compute groups for a single cascading validation taking into account the specified set of
+     * {@link GroupConversionDescriptor}s.
+     * 
+     * @param groupConversions
+     * @param group
+     * @return {@link Groups}
+     */
+    @Deprecated
+    public final Groups computeCascadingGroups(Set<GroupConversionDescriptor> groupConversions, Class<?> group) {
+        final Groups preliminaryResult = computeGroups(Stream.of(group));
+
+        final Map<Class<?>, Class<?>> gcMap = groupConversions.stream()
+            .collect(Collectors.toMap(GroupConversionDescriptor::getFrom, GroupConversionDescriptor::getTo));
+
+        final boolean simpleGroup = preliminaryResult.getSequences().isEmpty();
+
+        // conversion of a simple (non-sequence) group:
+        if (simpleGroup && gcMap.containsKey(group)) {
+            return computeGroups(Stream.of(gcMap.get(group)));
+        }
+        final Groups result = new Groups();
+
+        if (simpleGroup) {
+            // ignore group inheritance from initial argument as that is handled elsewhere:
+            result.insertGroup(preliminaryResult.getGroups().iterator().next());
+        } else {
+            // expand group sequence conversions in place:
+
+            for (Group.Sequence seq : preliminaryResult.getSequences()) {
+                final List<Group> converted = new ArrayList<>();
+                for (Group gg : seq.getGroups()) {
+                    final Class<?> c = gg.getGroup();
+                    if (gcMap.containsKey(c)) {
+                        final Groups convertedGroupExpansion = computeGroups(Stream.of(gcMap.get(c)));
+                        if (convertedGroupExpansion.getSequences().isEmpty()) {
+                            converted.add(gg);
+                        } else {
+                            convertedGroupExpansion.getSequences().stream().map(Group.Sequence::getGroups)
+                                .flatMap(Collection::stream).forEach(converted::add);
+                        }
+                    }
+                }
+                result.insertSequence(converted);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Compute groups from a {@link Collection}.
+     * 
+     * @param groups
+     * @return {@link Groups}
+     */
+    public Groups computeGroups(Collection<Class<?>> groups) {
+        Validate.notNull(groups, "groups");
+
+        if (groups.isEmpty() || Arrays.asList(DEFAULT_GROUP).equals(new ArrayList<>(groups))) {
+            return DEFAULT_GROUPS;
+        }
+        return computeGroups(groups.stream());
+    }
+
+    /**
+     * Compute groups from a {@link Stream}.
+     * 
+     * @param groups
+     * @return {@link Groups}
+     */
+    public Groups computeGroups(Stream<Class<?>> groups) {
+        final Groups result = new Groups();
+
+        groups.peek(g -> {
+            Exceptions.raiseIf(g == null, IllegalArgumentException::new, "Null group specified");
+
+            Exceptions.raiseUnless(g.isInterface(), ValidationException::new,
+                "A group must be an interface. %s is not.", g);
+
+        }).forEach(g -> {
+            final GroupSequence anno = g.getAnnotation(GroupSequence.class);
+            if (anno == null) {
+                result.insertGroup(new Group(g));
+                insertInheritedGroups(g, result);
+            } else {
+                result.insertSequence(
+                    resolvedSequences.computeIfAbsent(g, gg -> resolveSequence(gg, anno, new HashSet<>())));
+            }
+        });
+        if (Arrays.asList(DEFAULT_GROUP).equals(result.getGroups()) && result.getSequences().isEmpty()) {
+            return DEFAULT_GROUPS;
+        }
+        return result;
+    }
+
+    private void insertInheritedGroups(Class<?> clazz, Groups chain) {
+        for (Class<?> extendedInterface : clazz.getInterfaces()) {
+            chain.insertGroup(new Group(extendedInterface));
+            insertInheritedGroups(extendedInterface, chain);
+        }
+    }
+
+    private List<Group> resolveSequence(Class<?> group, GroupSequence sequenceAnnotation,
+        Set<Class<?>> processedSequences) {
+        Exceptions.raiseUnless(processedSequences.add(group), GroupDefinitionException::new,
+            "Cyclic dependency in groups definition");
+
+        final List<Group> resolvedGroupSequence = new ArrayList<>();
+        for (Class<?> clazz : sequenceAnnotation.value()) {
+            final GroupSequence anno = clazz.getAnnotation(GroupSequence.class);
+            if (anno == null) {
+                // group part of sequence
+                resolvedGroupSequence.add(new Group(clazz));
+            } else {
+                // recursion!
+                resolvedGroupSequence.addAll(resolveSequence(clazz, anno, processedSequences));
+            }
+        }
+        return resolvedGroupSequence;
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ComputeConstraintValidatorClass.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ComputeConstraintValidatorClass.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ComputeConstraintValidatorClass.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ComputeConstraintValidatorClass.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,214 @@
+/*
+ *  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.job;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.ConstraintDefinitionException;
+import javax.validation.ConstraintValidator;
+import javax.validation.UnexpectedTypeException;
+import javax.validation.constraintvalidation.ValidationTarget;
+
+import org.apache.bval.jsr.ConstraintCached;
+import org.apache.bval.jsr.ConstraintCached.ConstraintValidatorInfo;
+import org.apache.bval.jsr.descriptor.ConstraintD;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.bval.util.reflection.Reflection.Interfaces;
+import org.apache.bval.util.reflection.TypeUtils;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+@Privilizing(@CallTo(Reflection.class))
+class ComputeConstraintValidatorClass<A extends Annotation>
+    implements Supplier<Class<? extends ConstraintValidator<A, ?>>> {
+
+    private static class TypeWrapper {
+        final Class<?> componentType;
+        final int arrayDepth;
+
+        TypeWrapper(Class<?> type) {
+            Class<?> c = type;
+            int d = 0;
+            while (Object[].class.isAssignableFrom(c)) {
+                d++;
+                c = c.getComponentType();
+            }
+            this.componentType = c;
+            this.arrayDepth = d;
+        }
+
+        Class<?> unwrapArrayComponentType(Class<?> t) {
+            Exceptions.raiseUnless(t.isAssignableFrom(componentType), IllegalArgumentException::new,
+                "%s not assignable from %s", t, componentType);
+            if (arrayDepth == 0) {
+                return t;
+            }
+            return Array.newInstance(t, new int[arrayDepth]).getClass();
+        }
+    }
+
+    private static final String CV = ConstraintValidator.class.getSimpleName();
+    private static final WildcardType UNBOUNDED = TypeUtils.wildcardType().build();
+
+    private static Class<?> getValidatedType(Class<? extends ConstraintValidator<?, ?>> validatorType) {
+        final Type result = TypeUtils.getTypeArguments(validatorType, ConstraintValidator.class)
+            .get(ConstraintValidator.class.getTypeParameters()[1]);
+        if (!isSupported(result)) {
+            Exceptions.raise(ConstraintDefinitionException::new, "Validated type %s declared by %s %s is unsupported",
+                result, CV, validatorType.getName());
+        }
+        return TypeUtils.getRawType(result, null);
+    }
+
+    private static boolean isSupported(Type validatedType) {
+        if (validatedType instanceof Class<?>) {
+            return true;
+        }
+        if (validatedType instanceof ParameterizedType) {
+            return Stream.of(((ParameterizedType) validatedType).getActualTypeArguments())
+                .allMatch(arg -> TypeUtils.equals(arg, UNBOUNDED));
+        }
+        return false;
+    }
+
+    private final ConstraintCached constraintsCache;
+    private final ConstraintD<?> descriptor;
+    private final ValidationTarget validationTarget;
+    private final Class<?> validatedType;
+
+    ComputeConstraintValidatorClass(ConstraintCached constraintsCache, ConstraintD<A> descriptor,
+        ValidationTarget validationTarget, Class<?> validatedType) {
+        super();
+        this.constraintsCache = Validate.notNull(constraintsCache, "constraintsCache");
+        this.descriptor = Validate.notNull(descriptor, "descriptor");
+        this.validationTarget = Validate.notNull(validationTarget, "validationTarget");
+        this.validatedType = Validate.notNull(validatedType, "validatedType");
+    }
+
+    @Override
+    public Class<? extends ConstraintValidator<A, ?>> get() {
+        @SuppressWarnings("unchecked")
+        final Class<A> constraintType = (Class<A>) descriptor.getAnnotation().annotationType();
+        return findValidator(constraintsCache.getConstraintValidatorInfo(constraintType));
+    }
+
+    private Class<? extends ConstraintValidator<A, ?>> findValidator(Set<ConstraintValidatorInfo<A>> infos) {
+        switch (validationTarget) {
+        case PARAMETERS:
+            return findCrossParameterValidator(infos);
+        case ANNOTATED_ELEMENT:
+            return findAnnotatedElementValidator(infos);
+        default:
+            return null;
+        }
+    }
+
+    private Class<? extends ConstraintValidator<A, ?>> findCrossParameterValidator(
+        Set<ConstraintValidatorInfo<A>> infos) {
+
+        final Set<ConstraintValidatorInfo<A>> set =
+            infos.stream().filter(info -> info.getSupportedTargets().contains(ValidationTarget.PARAMETERS))
+                .collect(Collectors.toSet());
+
+        @SuppressWarnings("unchecked")
+        final Class<A> constraintType = (Class<A>) descriptor.getAnnotation().annotationType();
+
+        final int size = set.size();
+        Exceptions.raiseIf(size > 1 || !isComposed() && set.isEmpty(), ConstraintDefinitionException::new,
+            "%d cross-parameter %ss found for constraint type %s", size, CV, constraintType);
+
+        final Class<? extends ConstraintValidator<A, ?>> result = set.iterator().next().getType();
+        if (!TypeUtils.isAssignable(Object[].class, getValidatedType(result))) {
+            Exceptions.raise(ConstraintDefinitionException::new,
+                "Cross-parameter %s %s does not support the validation of an object array", CV, result.getName());
+        }
+        return result;
+    }
+
+    private Class<? extends ConstraintValidator<A, ?>> findAnnotatedElementValidator(
+        Set<ConstraintValidatorInfo<A>> infos) {
+
+        final Map<Class<?>, Class<? extends ConstraintValidator<?, ?>>> validators = infos.stream()
+            .filter(info -> info.getSupportedTargets().contains(ValidationTarget.ANNOTATED_ELEMENT))
+            .map(ConstraintValidatorInfo::getType).collect(
+                Collectors.toMap(ComputeConstraintValidatorClass::getValidatedType, Function.identity(), (v1, v2) -> {
+                    Exceptions.raiseUnless(Objects.equals(v1, v2), UnexpectedTypeException::new,
+                        "Detected collision of constraint and target type between %s and %s", v1, v2);
+                    return v1;
+                }));
+
+        final Map<Type, Class<? extends ConstraintValidator<?, ?>>> candidates = new HashMap<>();
+
+        walkHierarchy().filter(validators::containsKey).forEach(type -> {
+            // if we haven't already found a candidate whose validated type
+            // is a subtype of the current evaluated type, save:
+            if (!candidates.keySet().stream().anyMatch(k -> TypeUtils.isAssignable(k, type))) {
+                candidates.put(type, validators.get(type));
+            }
+        });
+        final String cond;
+        switch (candidates.size()) {
+        case 1:
+            @SuppressWarnings("unchecked")
+            final Class<? extends ConstraintValidator<A, ?>> result =
+                (Class<? extends ConstraintValidator<A, ?>>) candidates.values().iterator().next();
+            return result;
+        case 0:
+            if (isComposed()) {
+                return null;
+            }
+            cond = "No compliant";
+            break;
+        default:
+            cond = "> 1 maximally specific";
+            break;
+        }
+        throw Exceptions.create(UnexpectedTypeException::new, "%s %s %s found for annotated element of type %s", cond,
+            descriptor.getAnnotation().annotationType().getName(), CV, TypeUtils.toString(validatedType));
+    }
+
+    // account for validated array types by unwrapping and rewrapping component
+    // type hierarchy:
+    private Stream<Class<?>> walkHierarchy() {
+        final TypeWrapper w = new TypeWrapper(Reflection.primitiveToWrapper(validatedType));
+        Stream.Builder<Class<?>> hierarchy = Stream.builder();
+        Reflection.hierarchy(w.componentType, Interfaces.INCLUDE).forEach(hierarchy);
+        final Stream<Class<?>> result = hierarchy.build().map(w::unwrapArrayComponentType);
+        if (validatedType.isInterface() || validatedType.isArray()) {
+            return Stream.concat(result, Stream.of(Object.class));
+        }
+        return result;
+    }
+
+    private boolean isComposed() {
+        return !descriptor.getComposingConstraints().isEmpty();
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ConstraintValidatorContextImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ConstraintValidatorContextImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ConstraintValidatorContextImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ConstraintValidatorContextImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,204 @@
+/*
+ * 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.job;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.validation.ClockProvider;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ConstraintViolation;
+import javax.validation.ElementKind;
+import javax.validation.MessageInterpolator;
+import javax.validation.ValidationException;
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.CrossParameterDescriptor;
+
+import org.apache.bval.jsr.descriptor.ComposedD;
+import org.apache.bval.jsr.descriptor.ConstraintD;
+import org.apache.bval.jsr.descriptor.CrossParameterD;
+import org.apache.bval.jsr.util.ContainerElementNodeBuilderCustomizableContextImpl;
+import org.apache.bval.jsr.util.LeafNodeBuilderCustomizableContextImpl;
+import org.apache.bval.jsr.util.NodeBuilderCustomizableContextImpl;
+import org.apache.bval.jsr.util.NodeBuilderDefinedContextImpl;
+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.Lazy;
+import org.apache.bval.util.Validate;
+
+public class ConstraintValidatorContextImpl<T> implements ConstraintValidatorContext, MessageInterpolator.Context {
+    public class ConstraintViolationBuilderImpl implements ConstraintValidatorContext.ConstraintViolationBuilder {
+        private final String template;
+        private final PathImpl path;
+
+        private boolean complete;
+
+        ConstraintViolationBuilderImpl(String template, PathImpl path) {
+            this.template = template;
+            this.path = path;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public NodeBuilderDefinedContext addNode(String name) {
+            return new NodeBuilderDefinedContextImpl(extensiblePath().addProperty(name), this);
+        }
+
+        @Override
+        public NodeBuilderCustomizableContext addPropertyNode(String name) {
+            return new NodeBuilderCustomizableContextImpl(extensiblePath(), name, this);
+        }
+
+        @Override
+        public LeafNodeBuilderCustomizableContext addBeanNode() {
+            return new LeafNodeBuilderCustomizableContextImpl(extensiblePath(), this);
+        }
+
+        @Override
+        public NodeBuilderDefinedContext addParameterNode(int index) {
+            ofLegalState();
+            Exceptions.raiseUnless(frame.descriptor instanceof CrossParameterDescriptor, ValidationException::new,
+                "Cannot add parameter node for %s", f -> f.args(frame.descriptor.getClass().getName()));
+
+            final CrossParameterD<?, ?> crossParameter =
+                ComposedD.unwrap(frame.descriptor, CrossParameterD.class).findFirst().get();
+
+            final String parameterName = crossParameter.getParent().getParameterDescriptors().get(index).getName();
+
+            path.removeLeafNode();
+            return new NodeBuilderDefinedContextImpl(path.addNode(new NodeImpl.ParameterNodeImpl(parameterName, index)),
+                this);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public ConstraintValidatorContext addConstraintViolation() {
+            return addConstraintViolation(path);
+        }
+
+        public synchronized ConstraintViolationBuilderImpl ofLegalState() {
+            Validate.validState(!complete, "#addConstraintViolation() already called");
+            return this;
+        }
+
+        public ConstraintValidatorContext addConstraintViolation(PathImpl p) {
+            synchronized (this) {
+                ofLegalState();
+                complete = true;
+            }
+            addError(template, p);
+            return ConstraintValidatorContextImpl.this;
+        }
+
+        @Override
+        public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(String name,
+            Class<?> containerType, Integer typeArgumentIndex) {
+            ofLegalState();
+            return new ContainerElementNodeBuilderCustomizableContextImpl(extensiblePath(), name,
+                containerType, typeArgumentIndex, this);
+        }
+
+        private PathImpl extensiblePath() {
+            if (path.isRootPath()) {
+                return PathImpl.create();
+            }
+            final PathImpl result = PathImpl.copy(path);
+            final NodeImpl leafNode = result.getLeafNode();
+            if (leafNode.getKind() == ElementKind.BEAN
+                && !(leafNode.isInIterable() || leafNode.getContainerClass() != null)) {
+                result.removeLeafNode();
+            }
+            return result;
+        }
+    }
+
+    private final ValidationJob<T>.Frame<?> frame;
+    private final ConstraintD<?> constraint;
+    private final Lazy<Set<ConstraintViolation<T>>> violations = new Lazy<>(HashSet::new);
+    private boolean defaultConstraintViolationDisabled;
+
+    ConstraintValidatorContextImpl(ValidationJob<T>.Frame<?> frame, ConstraintD<?> constraint) {
+        super();
+        this.frame = Validate.notNull(frame, "frame");
+        this.constraint = Validate.notNull(constraint, "constraint");
+    }
+
+    @Override
+    public void disableDefaultConstraintViolation() {
+        this.defaultConstraintViolationDisabled = true;
+    }
+
+    @Override
+    public String getDefaultConstraintMessageTemplate() {
+        return constraint.getMessageTemplate();
+    }
+
+    @Override
+    public ConstraintViolationBuilder buildConstraintViolationWithTemplate(String messageTemplate) {
+        return new ConstraintViolationBuilderImpl(messageTemplate, frame.context.getPath());
+    }
+
+    @Override
+    public ClockProvider getClockProvider() {
+        return frame.getJob().validatorContext.getClockProvider();
+    }
+
+    @Override
+    public <U> U unwrap(Class<U> type) {
+        try {
+            return type.cast(this);
+        } catch (ClassCastException e) {
+            throw new ValidationException(e);
+        }
+    }
+
+    ValidationJob<T>.Frame<?> getFrame() {
+        return frame;
+    }
+
+    Set<ConstraintViolation<T>> getRequiredViolations() {
+        if (!violations.optional().isPresent()) {
+            if (defaultConstraintViolationDisabled) {
+                Exceptions.raise(ValidationException::new, "Expected custom constraint violation(s)");
+            }
+            addError(getDefaultConstraintMessageTemplate(), frame.context.getPath());
+        }
+        return violations.get();
+    }
+
+    @Override
+    public ConstraintDescriptor<?> getConstraintDescriptor() {
+        return constraint;
+    }
+
+    @Override
+    public Object getValidatedValue() {
+        return frame.context.getValue();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private void addError(String messageTemplate, PathImpl propertyPath) {
+        violations.get().add(((ValidationJob) frame.getJob()).createViolation(messageTemplate, this, propertyPath));
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateBean.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateBean.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateBean.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateBean.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.job;
+
+import org.apache.bval.jsr.ApacheFactoryContext;
+import org.apache.bval.jsr.ConstraintViolationImpl;
+import org.apache.bval.jsr.GraphContext;
+import org.apache.bval.jsr.descriptor.BeanD;
+import org.apache.bval.jsr.descriptor.ConstraintD;
+import org.apache.bval.jsr.util.PathImpl;
+import org.apache.bval.util.Validate;
+
+public final class ValidateBean<T> extends ValidationJob<T> {
+
+    private final T bean;
+
+    ValidateBean(ApacheFactoryContext validatorContext, T bean, Class<?>[] groups) {
+        super(validatorContext, groups);
+        this.bean = Validate.notNull(bean, IllegalArgumentException::new, "bean");
+    }
+
+    @Override
+    protected Frame<BeanD<T>> computeBaseFrame() {
+        return new BeanFrame<T>(new GraphContext(validatorContext, PathImpl.create(), bean));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    protected Class<T> getRootBeanClass() {
+        return (Class<T>) bean.getClass();
+    }
+
+    @Override
+    ConstraintViolationImpl<T> createViolation(String messageTemplate, String message,
+        ConstraintValidatorContextImpl<T> context, PathImpl propertyPath) {
+        return new ConstraintViolationImpl<>(messageTemplate, message, bean,
+            context.getFrame().getBean(), propertyPath, context.getFrame().context.getValue(),
+            context.getConstraintDescriptor(), getRootBeanClass(),
+            context.getConstraintDescriptor().unwrap(ConstraintD.class).getDeclaredOn(), null, null);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateExecutable.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateExecutable.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateExecutable.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateExecutable.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,71 @@
+/*
+ *  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.job;
+
+import java.lang.annotation.ElementType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.function.Function;
+
+import javax.validation.Path;
+import javax.validation.Path.Node;
+
+import org.apache.bval.jsr.ApacheFactoryContext;
+import org.apache.bval.jsr.metadata.Meta;
+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;
+
+public abstract class ValidateExecutable<E extends Executable, T> extends ValidationJob<T> {
+    private static final Function<Method, Path.Node> METHOD_NODE =
+        m -> new NodeImpl.MethodNodeImpl(m.getName(), Arrays.asList(m.getParameterTypes()));
+
+    private static final Function<Constructor<?>, Path.Node> CONSTRUCTOR_NODE =
+        c -> new NodeImpl.ConstructorNodeImpl(c.getDeclaringClass().getSimpleName(),
+            Arrays.asList(c.getParameterTypes()));
+
+    protected final E executable;
+
+    private final Function<E, Path.Node> executableNode;
+
+    @SuppressWarnings("unchecked")
+    public ValidateExecutable(ApacheFactoryContext validatorContext, Class<?>[] groups, Meta<E> meta) {
+        super(validatorContext, groups);
+        this.executable = Validate.notNull(meta, IllegalArgumentException::new, "meta").getHost();
+
+        switch (meta.getElementType()) {
+        case CONSTRUCTOR:
+            executableNode = (Function<E, Node>) CONSTRUCTOR_NODE;
+            break;
+        case METHOD:
+            executableNode = (Function<E, Node>) METHOD_NODE;
+            break;
+        default:
+            throw Exceptions.create(IllegalArgumentException::new, "Unsupported %s: %s",
+                ElementType.class.getSimpleName(), meta);
+        }
+    }
+
+    protected PathImpl createBasePath() {
+        final PathImpl path = PathImpl.create();
+        path.addNode(executableNode.apply(executable));
+        return path;
+    }
+}
\ No newline at end of file

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateParameters.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateParameters.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateParameters.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidateParameters.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,210 @@
+/*
+ * 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.job;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ParameterNameProvider;
+import javax.validation.constraintvalidation.ValidationTarget;
+import javax.validation.metadata.ExecutableDescriptor;
+
+import org.apache.bval.jsr.ApacheFactoryContext;
+import org.apache.bval.jsr.ConstraintViolationImpl;
+import org.apache.bval.jsr.GraphContext;
+import org.apache.bval.jsr.descriptor.ConstraintD;
+import org.apache.bval.jsr.descriptor.CrossParameterD;
+import org.apache.bval.jsr.descriptor.ParameterD;
+import org.apache.bval.jsr.groups.Group;
+import org.apache.bval.jsr.groups.GroupStrategy;
+import org.apache.bval.jsr.metadata.Meta;
+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.Lazy;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.TypeUtils;
+
+public abstract class ValidateParameters<E extends Executable, T> extends ValidateExecutable<E, T> {
+
+    public static class ForMethod<T> extends ValidateParameters<Method, T> {
+
+        ForMethod(ApacheFactoryContext validatorContext, T object, Method executable, Object[] parameterValues,
+            Class<?>[] groups) {
+            super(validatorContext, object, Validate.notNull(executable, IllegalArgumentException::new, "null method"),
+                parameterValues, groups, new Meta.ForMethod(executable));
+            Validate.notNull(object, IllegalArgumentException::new, "object");
+        }
+
+        @Override
+        protected ExecutableDescriptor describe() {
+            return validatorContext.getDescriptorManager().getBeanDescriptor(object.getClass())
+                .getConstraintsForMethod(executable.getName(), executable.getParameterTypes());
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        protected Class<T> getRootBeanClass() {
+            return (Class<T>) object.getClass();
+        }
+
+        @Override
+        protected List<String> getParameterNames(ParameterNameProvider parameterNameProvider) {
+            return parameterNameProvider.getParameterNames(executable);
+        }
+
+        @Override
+        protected T getRootBean() {
+            return object;
+        }
+    }
+
+    public static class ForConstructor<T> extends ValidateParameters<Constructor<? extends T>, T> {
+
+        ForConstructor(ApacheFactoryContext validatorContext, Constructor<? extends T> executable,
+            Object[] parameterValues, Class<?>[] groups) {
+            super(validatorContext, null, Validate.notNull(executable, IllegalArgumentException::new, "null ctor"),
+                parameterValues, groups, new Meta.ForConstructor<>(executable));
+        }
+
+        @Override
+        protected ExecutableDescriptor describe() {
+            return validatorContext.getDescriptorManager().getBeanDescriptor(executable.getDeclaringClass())
+                .getConstraintsForConstructor(executable.getParameterTypes());
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        protected Class<T> getRootBeanClass() {
+            return (Class<T>) executable.getDeclaringClass();
+        }
+
+        @Override
+        protected List<String> getParameterNames(ParameterNameProvider parameterNameProvider) {
+            return parameterNameProvider.getParameterNames(executable);
+        }
+
+        @Override
+        protected T getRootBean() {
+            return null;
+        }
+    }
+
+    class ParametersFrame extends Frame<CrossParameterD<?, ?>> {
+        private final ExecutableDescriptor executableDescriptor;
+
+        protected ParametersFrame(ExecutableDescriptor executableDescriptor, GraphContext context) {
+            super(null, (CrossParameterD<?, ?>) Validate.notNull(executableDescriptor, "executableDescriptor")
+                .getCrossParameterDescriptor(), context);
+            this.executableDescriptor = executableDescriptor;
+        }
+
+        @Override
+        protected ValidationTarget getValidationTarget() {
+            return ValidationTarget.PARAMETERS;
+        }
+
+        @Override
+        void process(GroupStrategy groups, Consumer<ConstraintViolation<T>> sink) {
+            Validate.notNull(sink, "sink");
+            final Lazy<Set<Frame<?>>> parameterFrames = new Lazy<>(this::parameterFrames);
+
+            GroupStrategy.redefining(groups, Collections.singletonMap(Group.DEFAULT, descriptor.getGroupStrategy()))
+                .applyTo(noViolations(gs -> {
+                    validateDescriptorConstraints(gs, sink);
+                    parameterFrames.get().forEach(p -> p.validateDescriptorConstraints(gs, sink));
+                }));
+            parameterFrames.get().forEach(p -> p.recurse(groups, sink));
+        }
+
+        @Override
+        Object getBean() {
+            return object;
+        }
+
+        private Set<Frame<?>> parameterFrames() {
+            return executableDescriptor.getParameterDescriptors().stream()
+                .map(pd -> new SproutFrame<ParameterD<?>>(this, (ParameterD<?>) pd, parameter(pd.getIndex())))
+                .collect(Collectors.toSet());
+        }
+    }
+
+    private static final String PARAMETERS_DO_NOT_MATCH = "Parameters do not match";
+
+    protected final T object;
+    protected final Lazy<List<String>> parameterNames =
+        new Lazy<>(() -> getParameterNames(validatorContext.getParameterNameProvider()));
+
+    private final Object[] parameterValues;
+
+    ValidateParameters(ApacheFactoryContext validatorContext, T object, E executable, Object[] parameterValues,
+        Class<?>[] groups, Meta<E> meta) {
+        super(validatorContext, groups, meta);
+        this.object = object;
+        this.parameterValues =
+            Validate.notNull(parameterValues, IllegalArgumentException::new, "null parameter values").clone();
+
+        final Type[] genericParameterTypes = executable.getGenericParameterTypes();
+        Exceptions.raiseUnless(parameterValues.length == genericParameterTypes.length, IllegalArgumentException::new,
+            PARAMETERS_DO_NOT_MATCH);
+        IntStream.range(0, genericParameterTypes.length)
+            .forEach(n -> Exceptions.raiseUnless(TypeUtils.isInstance(parameterValues[n], genericParameterTypes[n]),
+                IllegalArgumentException::new, PARAMETERS_DO_NOT_MATCH));
+    }
+
+    @Override
+    protected Frame<?> computeBaseFrame() {
+        return new ParametersFrame(describe(), new GraphContext(validatorContext,
+            createBasePath().addNode(new NodeImpl.CrossParameterNodeImpl()), parameterValues));
+    }
+
+    @Override
+    protected boolean hasWork() {
+        return describe() != null;
+    }
+
+    protected abstract ExecutableDescriptor describe();
+
+    protected abstract List<String> getParameterNames(ParameterNameProvider parameterNameProvider);
+
+    protected abstract T getRootBean();
+
+    @Override
+    ConstraintViolationImpl<T> createViolation(String messageTemplate, String message,
+        ConstraintValidatorContextImpl<T> context, PathImpl propertyPath) {
+        return new ConstraintViolationImpl<T>(messageTemplate, message, getRootBean(), context.getFrame().getBean(),
+            propertyPath, context.getFrame().context.getValue(), context.getConstraintDescriptor(), getRootBeanClass(),
+            context.getConstraintDescriptor().unwrap(ConstraintD.class).getDeclaredOn(), null, parameterValues);
+    }
+
+    private GraphContext parameter(int i) {
+        final PathImpl path = createBasePath();
+        path.addNode(new NodeImpl.ParameterNodeImpl(parameterNames.get().get(i), i));
+        return new GraphContext(validatorContext, path, parameterValues[i]);
+    }
+}