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 [14/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/xml/AnnotationProxy.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/AnnotationProxy.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/AnnotationProxy.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/AnnotationProxy.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,169 @@
+/*
+ *  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.xml;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+import javax.validation.Valid;
+
+import org.apache.bval.jsr.metadata.Signature;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.ObjectUtils;
+import org.apache.bval.util.StringUtils;
+import org.apache.bval.util.reflection.Reflection;
+
+/**
+ * Description: <br/>
+ * InvocationHandler implementation of <code>Annotation</code> that pretends it is a "real" source code annotation.
+ * <p/>
+ */
+class AnnotationProxy implements Annotation, InvocationHandler, Serializable {
+
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+    
+    private Signature EQUALS = new Signature("equals", Object.class);
+
+    private final Class<? extends Annotation> annotationType;
+    private final SortedMap<String, Object> values;
+
+    /**
+     * Create a new AnnotationProxy instance.
+     * 
+     * @param <A>
+     * @param descriptor
+     */
+    <A extends Annotation> AnnotationProxy(AnnotationProxyBuilder<A> descriptor) {
+        this.annotationType = descriptor.getType();
+        values = new TreeMap<>();
+        int processedValuesFromDescriptor = 0;
+        for (final Method m : descriptor.getMethods()) {
+            if (descriptor.contains(m.getName())) {
+                values.put(m.getName(), descriptor.getValue(m.getName()));
+                processedValuesFromDescriptor++;
+            } else {
+                if (m.getDefaultValue() == null) {
+                    Exceptions.raise(IllegalArgumentException::new, "No value provided for %s", m.getName());
+                }
+                values.put(m.getName(), m.getDefaultValue());
+            }
+        }
+        Exceptions.raiseUnless(processedValuesFromDescriptor == descriptor.size() || Valid.class.equals(annotationType),
+            IllegalArgumentException::new, "Trying to instantiate %s with unknown parameters.",
+            f -> f.args(annotationType.getName()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (values.containsKey(method.getName())) {
+            return values.get(method.getName());
+        }
+        if (EQUALS.equals(Signature.of(method))) {
+            return equalTo(args[0]);
+        }
+        return method.invoke(this, args);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<? extends Annotation> annotationType() {
+        return annotationType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return values.entrySet().stream()
+            .map(e -> String.format("%s=%s", e.getKey(), StringUtils.valueOf(e.getValue())))
+            .collect(Collectors.joining(", ", String.format("@%s(", annotationType().getName()), ")"));
+    }
+
+    @Override
+    public int hashCode() {
+        return values.entrySet().stream().mapToInt(e -> {
+            return (127 * e.getKey().hashCode()) ^ ObjectUtils.hashCode(e.getValue());
+        }).sum();
+    }
+
+    private boolean equalTo(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof Annotation) {
+            final Annotation other = (Annotation) obj;
+            return other.annotationType().equals(annotationType)
+                && values.entrySet().stream().allMatch(e -> memberEquals(other, e.getKey(), e.getValue()));
+        }
+        return false;
+    }
+
+    private boolean memberEquals(Annotation other, String name, Object value) {
+        final Method member = Reflection.getDeclaredMethod(annotationType, name);
+        final Object otherValue;
+        try {
+            otherValue = member.invoke(other);
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            throw new IllegalStateException(e);
+        }
+        Exceptions.raiseIf(otherValue == null || !otherValue.getClass().equals(value.getClass()),
+            IllegalStateException::new, "Unexpected value %s for member %s of %s", otherValue, name, other);
+
+        if (value instanceof Object[]) {
+            return Arrays.equals((Object[]) value, (Object[]) otherValue);
+        }
+        if (value instanceof byte[]) {
+            return Arrays.equals((byte[]) value, (byte[]) otherValue);
+        }
+        if (value instanceof short[]) {
+            return Arrays.equals((short[]) value, (short[]) otherValue);
+        }
+        if (value instanceof int[]) {
+            return Arrays.equals((int[]) value, (int[]) otherValue);
+        }
+        if (value instanceof char[]) {
+            return Arrays.equals((char[]) value, (char[]) otherValue);
+        }
+        if (value instanceof long[]) {
+            return Arrays.equals((long[]) value, (long[]) otherValue);
+        }
+        if (value instanceof float[]) {
+            return Arrays.equals((float[]) value, (float[]) otherValue);
+        }
+        if (value instanceof double[]) {
+            return Arrays.equals((double[]) value, (double[]) otherValue);
+        }
+        if (value instanceof boolean[]) {
+            return Arrays.equals((boolean[]) value, (boolean[]) otherValue);
+        }
+        return value.equals(otherValue);
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/AnnotationProxyBuilder.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/AnnotationProxyBuilder.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/AnnotationProxyBuilder.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/AnnotationProxyBuilder.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,268 @@
+/*
+ *  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.xml;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.enterprise.util.AnnotationLiteral;
+import javax.validation.ConstraintTarget;
+import javax.validation.Payload;
+import javax.validation.Valid;
+import javax.validation.ValidationException;
+import javax.validation.groups.ConvertGroup;
+
+import org.apache.bval.cdi.EmptyAnnotationLiteral;
+import org.apache.bval.jsr.ConstraintAnnotationAttributes;
+import org.apache.bval.jsr.util.AnnotationsManager;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privileged;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+/**
+ * Description: Holds the information and creates an annotation proxy during xml
+ * parsing of validation mapping constraints. <br/>
+ */
+@Privilizing(@CallTo(Reflection.class))
+public final class AnnotationProxyBuilder<A extends Annotation> {
+    private static final ConcurrentMap<Class<?>, Method[]> METHODS_CACHE = new ConcurrentHashMap<>();
+
+    public static <A> Method[] findMethods(final Class<A> annotationType) {
+        // cache only built-in constraints to avoid memory leaks:
+        // TODO use configurable cache size property?
+        if (annotationType.getName().startsWith("javax.validation.constraints.")) {
+            return METHODS_CACHE.computeIfAbsent(annotationType, Reflection::getDeclaredMethods);
+        }
+        return Reflection.getDeclaredMethods(annotationType);
+    }
+
+    private final Class<A> type;
+    private final Map<String, Object> elements = new HashMap<>();
+    private final Method[] methods;
+    private boolean changed;
+
+    /**
+     * Create a new AnnotationProxyBuilder instance.
+     *
+     * @param annotationType
+     */
+    public AnnotationProxyBuilder(final Class<A> annotationType) {
+        this.type = annotationType;
+        this.methods = findMethods(annotationType);
+    }
+
+    /**
+     * Create a new AnnotationProxyBuilder instance.
+     *
+     * @param annotationType
+     * @param elements
+     */
+    public AnnotationProxyBuilder(Class<A> annotationType, Map<String, Object> elements) {
+        this(annotationType);
+        elements.forEach(this.elements::put);
+    }
+
+    /**
+     * Create a builder initially configured to create an annotation equivalent
+     * to {@code annot}.
+     * 
+     * @param annot
+     *            Annotation to be replicated.
+     */
+    @SuppressWarnings("unchecked")
+    public AnnotationProxyBuilder(A annot) {
+        this((Class<A>) annot.annotationType());
+        elements.putAll(AnnotationsManager.readAttributes(annot));
+    }
+
+    public Method[] getMethods() {
+        return methods;
+    }
+
+    /**
+     * Add an element to the configuration.
+     *
+     * @param elementName
+     * @param value
+     */
+    @Deprecated
+    public Object putValue(String elementName, Object value) {
+        return elements.put(elementName, value);
+    }
+
+    /**
+     * Add an element to the configuration.
+     *
+     * @param elementName
+     * @param value
+     * @return whether any change occurred
+     */
+    public boolean setValue(String elementName, Object value) {
+        final boolean result = !Objects.equals(elements.put(elementName, value), value);
+        changed |= result;
+        return result;
+    }
+
+    /**
+     * Get the specified element value from the current configuration.
+     *
+     * @param elementName
+     * @return Object value
+     */
+    public Object getValue(String elementName) {
+        return elements.get(elementName);
+    }
+
+    /**
+     * Learn whether a given element has been configured.
+     *
+     * @param elementName
+     * @return <code>true</code> if an <code>elementName</code> element is found
+     *         on this annotation
+     */
+    public boolean contains(String elementName) {
+        return elements.containsKey(elementName);
+    }
+
+    /**
+     * Get the number of configured elements.
+     *
+     * @return int
+     */
+    public int size() {
+        return elements.size();
+    }
+
+    /**
+     * Get the configured Annotation type.
+     *
+     * @return Class<A>
+     */
+    public Class<A> getType() {
+        return type;
+    }
+
+    /**
+     * Configure the well-known JSR303 "message" element.
+     *
+     * @param message
+     * @return
+     */
+    public boolean setMessage(String message) {
+        return setValue(ConstraintAnnotationAttributes.MESSAGE.getAttributeName(), message);
+    }
+
+    /**
+     * Configure the well-known JSR303 "groups" element.
+     *
+     * @param groups
+     * @return
+     */
+    public boolean setGroups(Class<?>[] groups) {
+        return setValue(ConstraintAnnotationAttributes.GROUPS.getAttributeName(), groups);
+    }
+
+    /**
+     * Configure the well-known JSR303 "payload" element.
+     * 
+     * @param payload
+     * @return
+     */
+    public boolean setPayload(Class<? extends Payload>[] payload) {
+        return setValue(ConstraintAnnotationAttributes.PAYLOAD.getAttributeName(), payload);
+    }
+
+    /**
+     * Configure the well-known "validationAppliesTo" element.
+     * 
+     * @param constraintTarget
+     */
+    public boolean setValidationAppliesTo(ConstraintTarget constraintTarget) {
+        return setValue(ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO.getAttributeName(), constraintTarget);
+    }
+
+    public boolean isChanged() {
+        return changed;
+    }
+
+    /**
+     * Create the annotation represented by this builder.
+     *
+     * @return {@link Annotation}
+     */
+    public A createAnnotation() {
+        final ClassLoader classLoader = Reflection.getClassLoader(getType());
+        @SuppressWarnings("unchecked")
+        final Class<A> proxyClass = (Class<A>) Proxy.getProxyClass(classLoader, getType());
+        return doCreateAnnotation(proxyClass, new AnnotationProxy(this));
+    }
+
+    @Privileged
+    private A doCreateAnnotation(final Class<A> proxyClass, final InvocationHandler handler) {
+        try {
+            final Constructor<A> constructor = proxyClass.getConstructor(InvocationHandler.class);
+            final boolean mustUnset = Reflection.setAccessible(constructor, true); // java
+                                                                                   // 8
+            try {
+                return constructor.newInstance(handler);
+            } finally {
+                if (mustUnset) {
+                    Reflection.setAccessible(constructor, false);
+                }
+            }
+        } catch (Exception e) {
+            throw new ValidationException("Unable to create annotation for configured constraint", e);
+        }
+    }
+
+    public static final class ValidAnnotation extends EmptyAnnotationLiteral<Valid> implements Valid {
+        private static final long serialVersionUID = 1L;
+
+        public static final ValidAnnotation INSTANCE = new ValidAnnotation();
+    }
+
+    public static final class ConvertGroupAnnotation extends AnnotationLiteral<ConvertGroup> implements ConvertGroup {
+        private static final long serialVersionUID = 1L;
+
+        private final Class<?> from;
+        private final Class<?> to;
+
+        public ConvertGroupAnnotation(final Class<?> from, final Class<?> to) {
+            this.from = from;
+            this.to = to;
+        }
+
+        @Override
+        public Class<?> from() {
+            return from;
+        }
+
+        @Override
+        public Class<?> to() {
+            return to;
+        }
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/MappingValidator.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/MappingValidator.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/MappingValidator.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/MappingValidator.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,245 @@
+/*
+ *  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.xml;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import javax.validation.ValidationException;
+
+import org.apache.bval.jsr.ConstraintAnnotationAttributes;
+import org.apache.bval.jsr.metadata.ContainerElementKey;
+import org.apache.bval.jsr.metadata.Meta;
+import org.apache.bval.jsr.metadata.Meta.ForConstructor;
+import org.apache.bval.jsr.metadata.Signature;
+import org.apache.bval.jsr.util.Methods;
+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.TypeUtils;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+@Privilizing(@CallTo(Reflection.class))
+public class MappingValidator {
+    private static final Set<ConstraintAnnotationAttributes> RESERVED_CONSTRAINT_ELEMENT_NAMES = Collections
+        .unmodifiableSet(EnumSet.of(ConstraintAnnotationAttributes.GROUPS, ConstraintAnnotationAttributes.MESSAGE,
+            ConstraintAnnotationAttributes.PAYLOAD, ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO));
+
+    private static <T> BinaryOperator<T> enforceUniqueness(String message, Function<? super T, ?> describe) {
+        return (t, u) -> {
+            throw Exceptions.create(ValidationException::new, message, describe.apply(t));
+        };
+    }
+
+    private final ConstraintMappingsType constraintMappings;
+    private final Function<String, Class<?>> resolveClass;
+
+    public MappingValidator(ConstraintMappingsType constraintMappings, Function<String, Class<?>> resolveClass) {
+        super();
+        this.constraintMappings = Validate.notNull(constraintMappings, "constraintMappings");
+        this.resolveClass = Validate.notNull(resolveClass, "resolveClass");
+    }
+
+    public void validateMappings() {
+        constraintMappings.getBean().stream().map(this::applyChecks).collect(Collectors.toMap(Function.identity(),
+            Function.identity(), enforceUniqueness("Duplicate XML constrained bean %s", Class::getName)));
+    }
+
+    private Class<?> applyChecks(BeanType bean) {
+        final Class<?> t = resolveClass.apply(bean.getClazz());
+
+        final ClassType classType = bean.getClassType();
+        if (classType != null) {
+            constraints(new Meta.ForClass<>(t), classType.getConstraint());
+        }
+        final Set<String> fieldProperties = fieldProperties(t, bean.getField());
+        final Set<String> getterProperties = getterProperties(t, bean.getGetter());
+        final Set<Signature> methods = methods(t, bean.getMethod());
+        @SuppressWarnings("unused")
+        final Set<Signature> constructors = constructors(t, bean.getConstructor());
+
+        final Set<String> propertyOverlap = new HashSet<>(fieldProperties);
+        propertyOverlap.retainAll(getterProperties);
+
+        if (!propertyOverlap.isEmpty()) {
+            Exceptions.raise(ValidationException::new,
+                "The following %s properties were specified via XML field and getter: %s", bean.getClazz(),
+                propertyOverlap);
+        }
+        final Set<String> getterMethodOverlap = methods.stream().filter(s -> s.getParameterTypes().length == 0)
+            .map(Signature::getName).filter(Methods::isGetter).map(Methods::propertyName)
+            .filter(getterProperties::contains).collect(Collectors.toSet());
+
+        if (!getterMethodOverlap.isEmpty()) {
+            Exceptions.raise(ValidationException::new,
+                "The following %s getters were specified via XML getter and method: %s", bean.getClazz(),
+                getterMethodOverlap);
+        }
+        return t;
+    }
+
+    private Set<String> fieldProperties(Class<?> t, List<FieldType> fields) {
+        return fields.stream().peek(f -> {
+            final Field fld = Reflection.find(t, c -> Reflection.getDeclaredField(c, f.getName()));
+            if (fld == null) {
+                Exceptions.raise(ValidationException::new, "Unknown XML constrained field %s of %s", f.getName(), t);
+            }
+            final Meta.ForField metaField = new Meta.ForField(fld);
+            constraints(metaField, f.getConstraint());
+            containerElements(metaField, f.getContainerElementType());
+        }).collect(Collectors.toMap(FieldType::getName, Function.identity(),
+            enforceUniqueness("Duplicate XML constrained field %s of " + t, FieldType::getName))).keySet();
+    }
+
+    private Set<String> getterProperties(Class<?> t, List<GetterType> getters) {
+        return getters.stream().peek(g -> {
+            final Method getter = Methods.getter(t, g.getName());
+            if (getter == null) {
+                Exceptions.raise(ValidationException::new, "Unknown XML constrained getter for property %s of %s",
+                    g.getName(), t);
+            }
+            final Meta.ForMethod metaGetter = new Meta.ForMethod(getter);
+            constraints(metaGetter, g.getConstraint());
+            containerElements(metaGetter, g.getContainerElementType());
+        }).collect(Collectors.toMap(GetterType::getName, Function.identity(),
+            enforceUniqueness("Duplicate XML constrained getter %s of " + t, GetterType::getName))).keySet();
+    }
+
+    private Set<Signature> methods(Class<?> t, List<MethodType> methods) {
+        return methods.stream().map(mt -> {
+            final Class<?>[] parameterTypes = getParameterTypes(mt.getParameter());
+            final Signature result = new Signature(mt.getName(), parameterTypes);
+            final Method m = Reflection.find(t, c -> Reflection.getDeclaredMethod(c, mt.getName(), parameterTypes));
+            Exceptions.raiseIf(m == null, ValidationException::new, "Unknown method %s of %s", result, t);
+
+            Optional.of(mt).map(MethodType::getReturnValue).ifPresent(rv -> {
+                final Meta.ForMethod metaMethod = new Meta.ForMethod(m);
+                constraints(metaMethod, rv.getConstraint());
+                containerElements(metaMethod, rv.getContainerElementType());
+            });
+            final Parameter[] params = m.getParameters();
+
+            IntStream.range(0, parameterTypes.length).forEach(n -> {
+                final Meta.ForParameter metaParam = new Meta.ForParameter(params[n], params[n].getName());
+                final ParameterType parameterType = mt.getParameter().get(n);
+                constraints(metaParam, parameterType.getConstraint());
+                containerElements(metaParam, parameterType.getContainerElementType());
+            });
+
+            return result;
+        }).collect(Collectors.toSet());
+    }
+
+    private Set<Signature> constructors(Class<?> t, List<ConstructorType> ctors) {
+        return ctors.stream().map(ctor -> {
+            final Class<?>[] parameterTypes = getParameterTypes(ctor.getParameter());
+            final Signature result = new Signature(t.getSimpleName(), parameterTypes);
+            final Constructor<?> dc = Reflection.getDeclaredConstructor(t, parameterTypes);
+            Exceptions.raiseIf(dc == null, ValidationException::new, "Unknown %s constructor %s", t, result);
+
+            Optional.of(ctor).map(ConstructorType::getReturnValue).ifPresent(rv -> {
+                final ForConstructor<?> metaCtor = new Meta.ForConstructor<>(dc);
+                constraints(metaCtor, rv.getConstraint());
+                containerElements(metaCtor, rv.getContainerElementType());
+            });
+            final Parameter[] params = dc.getParameters();
+
+            IntStream.range(0, parameterTypes.length).forEach(n -> {
+                final Meta.ForParameter metaParam = new Meta.ForParameter(params[n], params[n].getName());
+                final ParameterType parameterType = ctor.getParameter().get(n);
+                constraints(metaParam, parameterType.getConstraint());
+                containerElements(metaParam, parameterType.getContainerElementType());
+            });
+            return result;
+        }).collect(Collectors.toSet());
+    }
+
+    private Class<?>[] getParameterTypes(List<ParameterType> paramElements) {
+        return paramElements.stream().map(ParameterType::getType).map(resolveClass).toArray(Class[]::new);
+    }
+
+    private Set<ContainerElementKey> containerElements(Meta<?> meta,
+        List<ContainerElementTypeType> containerElementTypes) {
+        if (containerElementTypes.isEmpty()) {
+            return Collections.emptySet();
+        }
+        final Class<?> containerType = TypeUtils.getRawType(meta.getType(), null);
+        final int typeParameterCount = containerType.getTypeParameters().length;
+        if (typeParameterCount == 0) {
+            Exceptions.raise(ValidationException::new, "Cannot specify container element types for %s",
+                meta.describeHost());
+        }
+        return containerElementTypes.stream().map(e -> {
+            Integer typeArgumentIndex = e.getTypeArgumentIndex();
+            if (typeArgumentIndex == null) {
+                if (typeParameterCount > 1) {
+                    Exceptions.raise(ValidationException::new,
+                        "Unable to resolve unspecified type argument index for %s", meta.describeHost());
+                }
+                typeArgumentIndex = Integer.valueOf(0);
+            }
+            final ContainerElementKey result = new ContainerElementKey(containerType, typeArgumentIndex);
+
+            final Meta.ForContainerElement elementMeta = new Meta.ForContainerElement(meta, result);
+
+            constraints(elementMeta, e.getConstraint());
+            containerElements(elementMeta, e.getContainerElementType());
+
+            return result;
+        }).collect(Collectors.toMap(Function.identity(), ContainerElementKey::getTypeArgumentIndex, enforceUniqueness(
+            "Duplicate XML constrained container element %d of " + meta.describeHost(), Function.identity()))).keySet();
+    }
+
+    private void constraints(Meta<?> meta, List<ConstraintType> constraints) {
+        constraints.forEach(constraint -> {
+            final Class<?> annotation = resolveClass.apply(constraint.getAnnotation());
+            Exceptions.raiseUnless(annotation.isAnnotation(), ValidationException::new, "%s is not an annotation",
+                annotation);
+
+            final Set<String> missingElements = Stream.of(Reflection.getDeclaredMethods(annotation))
+                .filter(m -> m.getParameterCount() == 0 && m.getDefaultValue() == null).map(Method::getName)
+                .collect(Collectors.toSet());
+
+            for (final ElementType elementType : constraint.getElement()) {
+                final String name = elementType.getName();
+                if (RESERVED_CONSTRAINT_ELEMENT_NAMES.stream().map(ConstraintAnnotationAttributes::getAttributeName)
+                    .anyMatch(Predicate.isEqual(name))) {
+                    Exceptions.raise(ValidationException::new, "Constraint of %s declares reserved parameter name %s.",
+                        meta.describeHost(), name);
+                }
+                missingElements.remove(name);
+            }
+            Exceptions.raiseUnless(missingElements.isEmpty(), ValidationException::new,
+                "Missing required elements of %s: %s", annotation, missingElements);
+        });
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/SchemaManager.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/SchemaManager.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/SchemaManager.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/SchemaManager.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,294 @@
+/*
+ * 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.xml;
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.validation.ValidationException;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.UnmarshallerHandler;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.ValidatorHandler;
+
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.StringUtils;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.Reflection;
+import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+/**
+ * Unmarshals XML converging on latest schema version. Presumes backward compatiblity between schemae.
+ */
+public class SchemaManager {
+    public static class Builder {
+        private final SortedMap<Key, Lazy<Schema>> data = new TreeMap<>();
+
+        public Builder add(String version, String ns, String resource) {
+            data.put(new Key(version, ns), new Lazy<>(() -> SchemaManager.loadSchema(resource)));
+            return this;
+        }
+
+        public SchemaManager build() {
+            return new SchemaManager(new TreeMap<>(data));
+        }
+    }
+
+    private static class Key implements Comparable<Key> {
+        private static final Comparator<Key> CMP = Comparator.comparing(Key::getVersion).thenComparing(Key::getNs);
+
+        final String version;
+        final String ns;
+
+        Key(String version, String ns) {
+            super();
+            Validate.isTrue(StringUtils.isNotBlank(version), "version cannot be null/empty/blank");
+            this.version = version;
+            Validate.isTrue(StringUtils.isNotBlank(ns), "ns cannot be null/empty/blank");
+            this.ns = ns;
+        }
+
+        public String getVersion() {
+            return version;
+        }
+
+        public String getNs() {
+            return ns;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            return Optional.ofNullable(obj).filter(SchemaManager.Key.class::isInstance)
+                .map(SchemaManager.Key.class::cast)
+                .filter(k -> Objects.equals(this.version, k.version) && Objects.equals(this.ns, k.ns)).isPresent();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(version, ns);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s:%s", version, ns);
+        }
+
+        @Override
+        public int compareTo(Key o) {
+            return CMP.compare(this, o);
+        }
+    }
+
+    private class DynamicValidatorHandler extends XMLFilterImpl {
+        ContentHandler ch;
+        SAXParseException e;
+
+        @Override
+        public void setContentHandler(ContentHandler handler) {
+            super.setContentHandler(handler);
+            this.ch = handler;
+        }
+
+        @Override
+        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+            if (getContentHandler() == ch) {
+                final String version = Objects.toString(atts.getValue("version"), data.firstKey().getVersion());
+                final Key schemaKey = new Key(version, uri);
+                Exceptions.raiseUnless(data.containsKey(schemaKey), ValidationException::new,
+                    "Unknown validation schema %s", schemaKey);
+
+                final Schema schema = data.get(schemaKey).get();
+                final ValidatorHandler vh = schema.newValidatorHandler();
+                vh.startDocument();
+                vh.setContentHandler(ch);
+                super.setContentHandler(vh);
+            }
+            try {
+                super.startElement(uri, localName, qName, atts);
+            } catch (SAXParseException e) {
+                this.e = e;
+            }
+        }
+
+        @Override
+        public void error(SAXParseException e) throws SAXException {
+            this.e = e;
+            super.error(e);
+        }
+
+        @Override
+        public void fatalError(SAXParseException e) throws SAXException {
+            this.e = e;
+            super.fatalError(e);
+        }
+
+        void validate() throws SAXParseException {
+            if (e != null) {
+                throw e;
+            }
+        }
+    }
+
+    //@formatter:off
+    private enum XmlAttributeType {
+        CDATA, ID, IDREF, IDREFS, NMTOKEN, NMTOKENS, ENTITY, ENTITIES, NOTATION;
+        //@formatter:on
+    }
+
+    private class SchemaRewriter extends XMLFilterImpl {
+        private boolean root = true;
+
+        @Override
+        public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+            final Key schemaKey =
+                new Key(Objects.toString(atts.getValue("version"), data.firstKey().getVersion()), uri);
+
+            if (!target.equals(schemaKey) && data.containsKey(schemaKey)) {
+                uri = target.ns;
+                if (root) {
+                    atts = rewrite(atts);
+                    root = false;
+                }
+            }
+            super.startElement(uri, localName, qName, atts);
+        }
+
+        private Attributes rewrite(Attributes atts) {
+            final AttributesImpl result;
+            if (atts instanceof AttributesImpl) {
+                result = (AttributesImpl) atts;
+            } else {
+                result = new AttributesImpl(atts);
+            }
+            set(result, "", VERSION_ATTRIBUTE, "", XmlAttributeType.CDATA, target.version);
+            return result;
+        }
+
+        private void set(AttributesImpl attrs, String uri, String localName, String qName, XmlAttributeType type,
+            String value) {
+            for (int i = 0, sz = attrs.getLength(); i < sz; i++) {
+                if (Objects.equals(qName, attrs.getQName(i))
+                    || Objects.equals(uri, attrs.getURI(i)) && Objects.equals(localName, attrs.getLocalName(i))) {
+                    attrs.setAttribute(i, uri, localName, qName, type.name(), value);
+                    return;
+                }
+            }
+            attrs.addAttribute(uri, localName, qName, type.name(), value);
+        }
+    }
+
+    public static final String VERSION_ATTRIBUTE = "version";
+
+    private static final Logger log = Logger.getLogger(SchemaManager.class.getName());
+    private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+    private static final SAXParserFactory SAX_PARSER_FACTORY;
+
+    static {
+        SAX_PARSER_FACTORY = SAXParserFactory.newInstance();
+        SAX_PARSER_FACTORY.setNamespaceAware(true);
+    }
+
+    static Schema loadSchema(String resource) {
+        final URL schemaUrl = Reflection.getClassLoader(XmlUtils.class).getResource(resource);
+        try {
+            return SCHEMA_FACTORY.newSchema(schemaUrl);
+        } catch (SAXException e) {
+            log.log(Level.WARNING, String.format("Unable to parse schema: %s", resource), e);
+            return null;
+        }
+    }
+
+    private static Class<?> getObjectFactory(Class<?> type) throws ClassNotFoundException {
+        final String className = String.format("%s.%s", type.getPackage().getName(), "ObjectFactory");
+        return Reflection.toClass(className, type.getClassLoader());
+    }
+
+    private final Key target;
+    private final SortedMap<Key, Lazy<Schema>> data;
+    private final String description;
+
+    private SchemaManager(SortedMap<Key, Lazy<Schema>> data) {
+        super();
+        this.data = Collections.unmodifiableSortedMap(data);
+        this.target = data.lastKey();
+        this.description = target.ns.substring(target.ns.lastIndexOf('/') + 1);
+    }
+
+    public Optional<Schema> getSchema(String ns, String version) {
+        return Optional.of(new Key(version, ns)).map(data::get).map(Lazy::get);
+    }
+
+    public Optional<Schema> getSchema(Document document) {
+        return Optional.ofNullable(document).map(Document::getDocumentElement)
+            .map(e -> getSchema(e.getAttribute(XMLConstants.XMLNS_ATTRIBUTE), e.getAttribute(VERSION_ATTRIBUTE))).get();
+    }
+
+    public <E extends Exception> Schema requireSchema(Document document, Function<String, E> exc) throws E {
+        return getSchema(document).orElseThrow(() -> Objects.requireNonNull(exc, "exc")
+            .apply(String.format("Unknown %s schema", Objects.toString(description, ""))));
+    }
+
+    public <T> T unmarshal(InputSource input, Class<T> type) throws Exception {
+        final XMLReader xmlReader = SAX_PARSER_FACTORY.newSAXParser().getXMLReader();
+
+        // validate specified schema:
+        final DynamicValidatorHandler schemaValidator = new DynamicValidatorHandler();
+        xmlReader.setContentHandler(schemaValidator);
+
+        // rewrite to latest schema, if required:
+        final SchemaRewriter schemaRewriter = new SchemaRewriter();
+        schemaValidator.setContentHandler(schemaRewriter);
+
+        JAXBContext jc = JAXBContext.newInstance(getObjectFactory(type));
+        // unmarshal:
+        final UnmarshallerHandler unmarshallerHandler = jc.createUnmarshaller().getUnmarshallerHandler();
+        schemaRewriter.setContentHandler(unmarshallerHandler);
+
+        xmlReader.parse(input);
+        schemaValidator.validate();
+
+        @SuppressWarnings("unchecked")
+        final JAXBElement<T> result = (JAXBElement<T>) unmarshallerHandler.getResult();
+        return result.getValue();
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,159 @@
+/*
+ *  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.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+import javax.validation.ValidationException;
+import javax.validation.spi.ConfigurationState;
+
+import org.apache.bval.jsr.metadata.MetadataBuilder;
+import org.apache.bval.jsr.metadata.MetadataBuilder.ForBean;
+import org.apache.bval.jsr.metadata.MetadataSource;
+import org.apache.bval.jsr.metadata.ValidatorMappingProvider;
+import org.apache.bval.jsr.metadata.XmlBuilder;
+import org.apache.bval.jsr.metadata.XmlValidationMappingProvider;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+import org.xml.sax.InputSource;
+
+/**
+ * Uses JAXB to parse constraints.xml based on the validation-mapping XML schema.
+ */
+@Privilizing(@CallTo(Reflection.class))
+public class ValidationMappingParser implements MetadataSource {
+    private static final SchemaManager SCHEMA_MANAGER = new SchemaManager.Builder()
+        .add(XmlBuilder.Version.v10.getId(), "http://jboss.org/xml/ns/javax/validation/mapping",
+            "META-INF/validation-mapping-1.0.xsd")
+        .add(XmlBuilder.Version.v11.getId(), "http://jboss.org/xml/ns/javax/validation/mapping",
+            "META-INF/validation-mapping-1.1.xsd")
+        .add(XmlBuilder.Version.v20.getId(), "http://xmlns.jcp.org/xml/ns/validation/mapping",
+            "META-INF/validation-mapping-2.0.xsd")
+        .build();
+
+    @Override
+    public void process(ConfigurationState configurationState,
+        Consumer<ValidatorMappingProvider> addValidatorMappingProvider, BiConsumer<Class<?>, ForBean<?>> addBuilder) {
+        if (configurationState.isIgnoreXmlConfiguration()) {
+            return;
+        }
+        final Set<Class<?>> beanTypes = new HashSet<>();
+        for (final InputStream xmlStream : configurationState.getMappingStreams()) {
+            final ConstraintMappingsType mapping = parseXmlMappings(xmlStream);
+
+            Optional.of(mapping).map(this::toMappingProvider).ifPresent(addValidatorMappingProvider);
+
+            final Map<Class<?>, MetadataBuilder.ForBean<?>> builders = new XmlBuilder(mapping).forBeans();
+            if (Collections.disjoint(beanTypes, builders.keySet())) {
+                builders.forEach(addBuilder::accept);
+                beanTypes.addAll(builders.keySet());
+            } else {
+                Exceptions.raise(ValidationException::new,
+                    builders.keySet().stream().filter(beanTypes::contains).map(Class::getName).collect(Collectors
+                        .joining("bean classes specified multiple times for XML validation mapping: [", "; ", "]")));
+            }
+        }
+    }
+
+    /**
+     * @param in
+     *            XML stream to parse using the validation-mapping-1.0.xsd
+     */
+    private ConstraintMappingsType parseXmlMappings(final InputStream in) {
+        try {
+            return SCHEMA_MANAGER.unmarshal(new InputSource(in), ConstraintMappingsType.class);
+        } catch (Exception e) {
+            throw new ValidationException("Failed to parse XML deployment descriptor file.", e);
+        } finally {
+            try {
+                in.reset(); // can be read several times + we ensured it was
+                            // re-readable in addMapping()
+            } catch (final IOException e) {
+                // no-op
+            }
+        }
+    }
+
+    private ValidatorMappingProvider toMappingProvider(ConstraintMappingsType mapping) {
+        if (mapping.getConstraintDefinition().isEmpty()) {
+            return null;
+        }
+        final Map<Class<? extends Annotation>, ValidatedByType> validatorMappings = new HashMap<>();
+
+        for (ConstraintDefinitionType constraintDefinition : mapping.getConstraintDefinition()) {
+            final String annotationClassName = constraintDefinition.getAnnotation();
+
+            final Class<?> clazz = loadClass(annotationClassName, mapping.getDefaultPackage());
+
+            Exceptions.raiseUnless(clazz.isAnnotation(), ValidationException::new, "%s is not an annotation",
+                annotationClassName);
+
+            final Class<? extends Annotation> annotationClass = clazz.asSubclass(Annotation.class);
+
+            Exceptions.raiseIf(validatorMappings.containsKey(annotationClass), ValidationException::new,
+                "XML constraint validator(s) for %s already configured.", annotationClass);
+
+            validatorMappings.put(annotationClass, constraintDefinition.getValidatedBy());
+        }
+        return new XmlValidationMappingProvider(validatorMappings,
+            cn -> toQualifiedClassName(cn, mapping.getDefaultPackage()));
+    }
+
+    private Class<?> loadClass(String className, String defaultPackage) {
+        return loadClass(toQualifiedClassName(className, defaultPackage));
+    }
+
+    private String toQualifiedClassName(String className, String defaultPackage) {
+        if (!isQualifiedClass(className)) {
+            if (className.startsWith("[L") && className.endsWith(";")) {
+                className = "[L" + defaultPackage + '.' + className.substring(2);
+            } else {
+                className = defaultPackage + '.' + className;
+            }
+        }
+        return className;
+    }
+
+    private boolean isQualifiedClass(String clazz) {
+        return clazz.indexOf('.') >= 0;
+    }
+
+    private Class<?> loadClass(final String className) {
+        ClassLoader loader = Reflection.getClassLoader(ValidationMappingParser.class);
+        if (loader == null) {
+            loader = getClass().getClassLoader();
+        }
+        try {
+            return Reflection.toClass(className, loader);
+        } catch (ClassNotFoundException ex) {
+            throw Exceptions.create(ValidationException::new, ex, "Unable to load class: %s", className);
+        }
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,149 @@
+/*
+ * 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.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import javax.validation.BootstrapConfiguration;
+import javax.validation.ValidationException;
+import javax.validation.executable.ExecutableType;
+
+import org.apache.bval.jsr.BootstrapConfigurationImpl;
+import org.apache.bval.jsr.ConfigurationImpl;
+import org.apache.bval.jsr.metadata.XmlBuilder;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privileged;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+import org.xml.sax.InputSource;
+
+/**
+ * Description: uses jaxb to parse validation.xml<br/>
+ */
+@Privilizing(@CallTo(Reflection.class))
+public class ValidationParser {
+
+    private static final String DEFAULT_VALIDATION_XML_FILE = "META-INF/validation.xml";
+    private static final Logger log = Logger.getLogger(ValidationParser.class.getName());
+
+    private static final SchemaManager SCHEMA_MANAGER = new SchemaManager.Builder()
+        .add(XmlBuilder.Version.v10.getId(), "http://jboss.org/xml/ns/javax/validation/configuration",
+            "META-INF/validation-configuration-1.0.xsd")
+        .add(XmlBuilder.Version.v11.getId(), "http://jboss.org/xml/ns/javax/validation/configuration",
+            "META-INF/validation-configuration-1.1.xsd")
+        .add(XmlBuilder.Version.v20.getId(), "http://xmlns.jcp.org/xml/ns/validation/configuration",
+            "META-INF/validation-configuration-2.0.xsd")
+        .build();
+
+    public static String getValidationXmlFile(String file) {
+        return file == null ? DEFAULT_VALIDATION_XML_FILE : file;
+    }
+
+    public static BootstrapConfiguration processValidationConfig(final String file,
+        final ConfigurationImpl targetConfig) {
+        final ValidationConfigType xmlConfig = parseXmlConfig(file);
+        if (xmlConfig == null) {
+            return null;
+        }
+        final boolean executableValidationEnabled;
+        final Set<ExecutableType> defaultValidatedExecutableTypes;
+
+        if (xmlConfig.getExecutableValidation() == null) {
+            defaultValidatedExecutableTypes = EnumSet.of(ExecutableType.IMPLICIT);
+            executableValidationEnabled = true;
+        } else {
+            final Optional<ExecutableValidationType> executableValidation =
+                Optional.of(xmlConfig).map(ValidationConfigType::getExecutableValidation);
+            executableValidationEnabled = executableValidation.map(ExecutableValidationType::getEnabled)
+                .filter(Predicate.isEqual(Boolean.TRUE)).isPresent();
+
+            defaultValidatedExecutableTypes = executableValidation.filter(x -> executableValidationEnabled)
+                .map(ExecutableValidationType::getDefaultValidatedExecutableTypes)
+                .map(DefaultValidatedExecutableTypesType::getExecutableType).map(EnumSet::copyOf)
+                .orElse(EnumSet.noneOf(ExecutableType.class));
+        }
+        return new BootstrapConfigurationImpl(xmlConfig.getDefaultProvider(), xmlConfig.getConstraintValidatorFactory(),
+            xmlConfig.getMessageInterpolator(), xmlConfig.getTraversableResolver(),
+            xmlConfig.getParameterNameProvider(), new HashSet<>(xmlConfig.getConstraintMapping()),
+            executableValidationEnabled, defaultValidatedExecutableTypes, toMap(xmlConfig.getProperty()),
+            xmlConfig.getClockProvider(), new HashSet<>(xmlConfig.getValueExtractor()));
+    }
+
+    private static Map<String, String> toMap(final List<PropertyType> property) {
+        return property == null || property.isEmpty() ? Collections.emptyMap()
+            : property.stream().collect(Collectors.toMap(PropertyType::getName, PropertyType::getValue));
+    }
+
+    @Privileged
+    private static ValidationConfigType parseXmlConfig(final String validationXmlFile) {
+        try (InputStream inputStream = getInputStream(getValidationXmlFile(validationXmlFile))) {
+            if (inputStream == null) {
+                log.log(Level.FINEST,
+                    String.format("No %s found. Using annotation based configuration only.", validationXmlFile));
+                return null;
+            }
+            log.log(Level.FINEST, String.format("%s found.", validationXmlFile));
+
+            return SCHEMA_MANAGER.unmarshal(new InputSource(inputStream), ValidationConfigType.class);
+        } catch (Exception e) {
+            throw Exceptions.create(ValidationException::new, e, "Unable to parse %s", validationXmlFile);
+        }
+    }
+
+    public static InputStream open(String mappingFileName) {
+        if (mappingFileName.charAt(0) == '/') {
+            // Classloader needs a path without a starting /
+            mappingFileName = mappingFileName.substring(1);
+        }
+        try {
+            final InputStream in = getInputStream(mappingFileName);
+            Exceptions.raiseIf(in == null, ValidationException::new,
+                    "Unable to open input stream for mapping file %s", mappingFileName);
+            return(in);
+        } catch (IOException e) {
+            throw Exceptions.create(ValidationException::new, e, "Unable to open input stream for mapping file %s",
+                mappingFileName);
+        }
+    }
+
+    static InputStream getInputStream(final String path) throws IOException {
+        final ClassLoader loader = Reflection.getClassLoader(ValidationParser.class);
+        final List<URL> urls = Collections.list(loader.getResources(path));
+        Exceptions.raiseIf(urls.stream().distinct().count() > 1, ValidationException::new,
+            "More than one %s is found in the classpath", path);
+        return urls.isEmpty() ? null : urls.get(0).openStream();
+    }
+
+    private ValidationParser() {
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.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.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.helpers.DefaultValidationEventHandler;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.apache.bval.util.reflection.Reflection;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+class XmlUtils {
+    private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
+    private static final Logger log = Logger.getLogger(XmlUtils.class.getName());
+    private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+
+    static Schema loadSchema(String resource) {
+        final URL schemaUrl = Reflection.getClassLoader(XmlUtils.class).getResource(resource);
+        try {
+            return SCHEMA_FACTORY.newSchema(schemaUrl);
+        } catch (SAXException e) {
+            log.log(Level.WARNING, String.format("Unable to parse schema: %s", resource), e);
+            return null;
+        }
+    }
+
+    static Document parse(InputStream in) throws SAXException, IOException, ParserConfigurationException {
+        return DOCUMENT_BUILDER_FACTORY.newDocumentBuilder().parse(in);
+    }
+
+    static <T> T unmarshal(Document document, Schema schema, Class<T> type) throws JAXBException {
+        final JAXBContext jc = JAXBContext.newInstance(type);
+        final Unmarshaller unmarshaller = jc.createUnmarshaller();
+        unmarshaller.setSchema(schema);
+        unmarshaller.setEventHandler(new DefaultValidationEventHandler());
+        final JAXBElement<T> root = unmarshaller.unmarshal(document, type);
+        return root.getValue();
+    }
+}
\ No newline at end of file

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/routines/EMailValidationUtils.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/routines/EMailValidationUtils.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/routines/EMailValidationUtils.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/routines/EMailValidationUtils.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.routines;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Description: holds the regexp to validate an email address<br>
+ * User: roman.stumm<br>
+ * Date: 17.06.2010<br>
+ * Time: 10:40:59<br>
+ */
+public class EMailValidationUtils {
+    private static String ATOM = "[^\\x00-\\x1F\\(\\)\\<\\>\\@\\,\\;\\:\\\\\\\"\\.\\[\\]\\s]";
+    private static String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*";
+    private static String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";
+    public static final Pattern DEFAULT_EMAIL_PATTERN;
+
+    static {
+        DEFAULT_EMAIL_PATTERN = Pattern.compile("^" + ATOM + "+(\\." + ATOM + "+)*@" + DOMAIN + "|" + IP_DOMAIN + ")$",
+            Pattern.CASE_INSENSITIVE);
+    }
+
+    /**
+     * Learn whether a given object is a valid email address.
+     * 
+     * @param value
+     *            to check
+     * @return <code>true</code> if the validation passes
+     */
+    public static boolean isValid(Object value) {
+        return isValid(value, DEFAULT_EMAIL_PATTERN);
+    }
+
+    /**
+     * Learn whether a particular value matches a given pattern per
+     * {@link Matcher#matches()}.
+     * 
+     * @param value
+     * @param aPattern
+     * @return <code>true</code> if <code>value</code> was a <code>String</code>
+     *         matching <code>aPattern</code>
+     */
+    // TODO it would seem to make sense to move or reduce the visibility of this
+    // method as it is more general than email.
+    public static boolean isValid(Object value, Pattern aPattern) {
+        if (value == null) {
+            return true;
+        }
+        if (!(value instanceof CharSequence)) {
+            return false;
+        }
+        CharSequence seq = (CharSequence) value;
+        if (seq.length() == 0) {
+            return true;
+        }
+        return aPattern.matcher(seq).matches();
+    }
+
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/BValVersion.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/BValVersion.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/BValVersion.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/BValVersion.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.bval.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+/**
+ * This class contains version information for BVal.
+ * It uses Ant's filter tokens to convert the template into a java
+ * file with current information.
+ */
+@Privilizing(@CallTo(Reflection.class))
+public class BValVersion {
+
+    /** Project name */
+    public static final String PROJECT_NAME = "Apache BVal";
+    /** Unique id of the current project/version/revision */
+    public static final String PROJECT_ID;
+    /** Version number */
+    public static final String VERSION_NUMBER;
+    /** Major release number */
+    public static final int MAJOR_RELEASE;
+    /** Minor release number */
+    public static final int MINOR_RELEASE;
+    /** Patch/point release number */
+    public static final int PATCH_RELEASE;
+    /** Release status */
+    public static final String RELEASE_STATUS;
+    /** Version control revision number */
+    public static final String REVISION_NUMBER;
+
+    static {
+        Properties revisionProps = new Properties();
+        try (InputStream in = BValVersion.class.getResourceAsStream("/META-INF/org.apache.bval.revision.properties")) {
+            if (in != null) {
+                revisionProps.load(in);
+            }
+        } catch (IOException ioe) {
+        }
+
+        String vers = revisionProps.getProperty("project.version");
+        if (StringUtils.isBlank(vers)) {
+            vers = "0.0.0";
+        }
+        VERSION_NUMBER = vers;
+
+        StringTokenizer tok = new StringTokenizer(VERSION_NUMBER, ".-");
+        int major, minor, patch;
+        try {
+            major = tok.hasMoreTokens() ? Integer.parseInt(tok.nextToken()) : 0;
+        } catch (Exception e) {
+            major = 0;
+        }
+
+        try {
+            minor = tok.hasMoreTokens() ? Integer.parseInt(tok.nextToken()) : 0;
+        } catch (Exception e) {
+            minor = 0;
+        }
+
+        try {
+            patch = tok.hasMoreTokens() ? Integer.parseInt(tok.nextToken()) : 0;
+        } catch (Exception e) {
+            patch = 0;
+        }
+
+        String revision = revisionProps.getProperty("svn.revision");
+        if (StringUtils.isBlank(revision)) {
+            revision = "unknown";
+        } else {
+            tok = new StringTokenizer(revision, ":");
+            String strTok = null;
+            while (tok.hasMoreTokens()) {
+                try {
+                    strTok = tok.nextToken();
+                } catch (Exception e) {
+                }
+            }
+            if (strTok != null) {
+                revision = strTok;
+            }
+        }
+
+        MAJOR_RELEASE = major;
+        MINOR_RELEASE = minor;
+        PATCH_RELEASE = patch;
+        RELEASE_STATUS = tok.hasMoreTokens() ? tok.nextToken("!") : "";
+        REVISION_NUMBER = revision;
+        PROJECT_ID = PROJECT_NAME + " " + VERSION_NUMBER + "-r" + REVISION_NUMBER;
+    }
+
+    /**
+     * Get the project version number.
+     * @return String
+     */
+    public static String getVersion() {
+        return VERSION_NUMBER;
+    }
+
+    /**
+     * Get the version control revision number.
+     * @return String
+     */
+    public static String getRevision() {
+        return REVISION_NUMBER;
+    }
+
+    /**
+     * Get the project name.
+     * @return String
+     */
+    public static String getName() {
+        return PROJECT_NAME;
+    }
+
+    /**
+     * Get the fully-qualified project id.
+     * @return String
+     */
+    public static String getID() {
+        return PROJECT_ID;
+    }
+
+    /**
+     * Main method of this class that prints the {@link #toString()} to <code>System.out</code>.
+     * @param args ignored
+     */
+    public static void main(String[] args) {
+        System.out.println(new BValVersion().toString());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buf = new StringBuilder(80 * 40);
+        appendBanner(buf);
+        buf.append("\n");
+
+        appendProperty("os.name", buf).append("\n");
+        appendProperty("os.version", buf).append("\n");
+        appendProperty("os.arch", buf).append("\n\n");
+
+        appendProperty("java.version", buf).append("\n");
+        appendProperty("java.vendor", buf).append("\n\n");
+
+        buf.append("java.class.path:\n");
+        final StringTokenizer tok = new StringTokenizer(Reflection.getProperty("java.class.path"));
+        while (tok.hasMoreTokens()) {
+            buf.append("\t").append(tok.nextToken());
+            buf.append("\n");
+        }
+        buf.append("\n");
+
+        appendProperty("user.dir", buf).append("\n");
+        return buf.toString();
+    }
+
+    private void appendBanner(StringBuilder buf) {
+        buf.append("Project").append(": ").append(getName());
+        buf.append("\n");
+        buf.append("Version").append(": ").append(getVersion());
+        buf.append("\n");
+        buf.append("Revision").append(": ").append(getRevision());
+        buf.append("\n");
+    }
+
+    private StringBuilder appendProperty(String prop, StringBuilder buf) {
+        return buf.append(prop).append(": ").append(Reflection.getProperty(prop));
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CloseableAble.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CloseableAble.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CloseableAble.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/CloseableAble.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.bval.util;
+
+import java.io.Closeable;
+
+@FunctionalInterface
+public interface CloseableAble {
+
+    Closeable getCloseable();
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Comparators.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Comparators.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Comparators.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Comparators.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.bval.util;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+/**
+ * {@link Comparator} related utilities.
+ */
+public class Comparators {
+
+    /**
+     * Get a {@link Comparator} capable of comparing {@link Iterable}s.
+     * 
+     * @param each
+     * @return {@link Comparator}
+     */
+    public static <T, I extends Iterable<T>> Comparator<I> comparingIterables(Comparator<? super T> each) {
+        return (quid, quo) -> {
+            final Iterator<T> quids = quid.iterator();
+            final Iterator<T> quos = quo.iterator();
+
+            while (quids.hasNext()) {
+                if (quos.hasNext()) {
+                    final int rz = each.compare(quids.next(), quos.next());
+                    if (rz != 0) {
+                        return rz;
+                    }
+                    continue;
+                }
+                return 1;
+            }
+            return quos.hasNext() ? -1 : 0;
+        };
+    }
+
+    private Comparators() {
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/EmulatedAnnotatedType.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/EmulatedAnnotatedType.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/EmulatedAnnotatedType.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/EmulatedAnnotatedType.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.util;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.AnnotatedTypeVariable;
+import java.lang.reflect.AnnotatedWildcardType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+public class EmulatedAnnotatedType<T extends Type> implements AnnotatedType {
+    private static class Parameterized extends EmulatedAnnotatedType<ParameterizedType>
+        implements AnnotatedParameterizedType {
+
+        Parameterized(ParameterizedType wrapped) {
+            super(wrapped);
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedActualTypeArguments() {
+            return wrapArray(wrapped.getActualTypeArguments());
+        }
+    }
+
+    private static class Variable extends EmulatedAnnotatedType<TypeVariable<?>> implements AnnotatedTypeVariable {
+
+        Variable(TypeVariable<?> wrapped) {
+            super(wrapped);
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedBounds() {
+            return wrapped.getAnnotatedBounds();
+        }
+    }
+
+    private static class Wildcard extends EmulatedAnnotatedType<WildcardType> implements AnnotatedWildcardType {
+
+        Wildcard(WildcardType wrapped) {
+            super(wrapped);
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedLowerBounds() {
+            return wrapArray(wrapped.getLowerBounds());
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedUpperBounds() {
+            return wrapArray(wrapped.getUpperBounds());
+        }
+    }
+
+    public static EmulatedAnnotatedType<?> wrap(Type type) {
+        if (type instanceof ParameterizedType) {
+            return new EmulatedAnnotatedType.Parameterized((ParameterizedType) type);
+        }
+        if (type instanceof TypeVariable<?>) {
+            return new EmulatedAnnotatedType.Variable((TypeVariable<?>) type);
+        }
+        if (type instanceof WildcardType) {
+            return new EmulatedAnnotatedType.Wildcard((WildcardType) type);
+        }
+        return new EmulatedAnnotatedType<>(type);
+    }
+
+    private static EmulatedAnnotatedType<?>[] wrapArray(Type[] types) {
+        return Stream.of(types).map(EmulatedAnnotatedType::wrap).toArray(EmulatedAnnotatedType[]::new);
+    }
+
+    private static final Annotation[] EMPTY_ANNOTATION_ARRAY = {};
+
+    protected final T wrapped;
+    private final Optional<AnnotatedElement> annotated;
+
+    private EmulatedAnnotatedType(T wrapped) {
+        super();
+        this.wrapped = Validate.notNull(wrapped);
+        this.annotated =
+            Optional.of(wrapped).filter(AnnotatedElement.class::isInstance).map(AnnotatedElement.class::cast);
+    }
+
+    @Override
+    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
+        return annotated.map(e -> e.getAnnotation(annotationClass)).orElse(null);
+    }
+
+    @Override
+    public Annotation[] getAnnotations() {
+        return annotated.map(AnnotatedElement::getAnnotations).orElse(EMPTY_ANNOTATION_ARRAY);
+    }
+
+    @Override
+    public Annotation[] getDeclaredAnnotations() {
+        return annotated.map(AnnotatedElement::getDeclaredAnnotations).orElse(EMPTY_ANNOTATION_ARRAY);
+    }
+
+    @Override
+    public Type getType() {
+        return wrapped;
+    }
+}

Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Escapes.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Escapes.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Escapes.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/util/Escapes.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,203 @@
+/**
+ * Copyright (C) 2006-2018 Talend Inc. - www.talend.com
+ * <p>
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bval.util;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+// taken from commons-lang3
+public final class Escapes {
+    private static final CharSequenceTranslator UNESCAPE_JAVA =
+            new AggregateTranslator(
+                    new OctalUnescaper(),     // .between('\1', '\377'),
+                    new UnicodeUnescaper(),
+                    new LookupTranslator(new String[][] {
+                            {"\\b", "\b"},
+                            {"\\n", "\n"},
+                            {"\\t", "\t"},
+                            {"\\f", "\f"},
+                            {"\\r", "\r"}
+                    }),
+                    new LookupTranslator(
+                            new String[][] {
+                                    {"\\\\", "\\"},
+                                    {"\\\"", "\""},
+                                    {"\\'", "'"},
+                                    {"\\", ""}
+                            })
+            );
+
+    private Escapes() {
+        // no-op
+    }
+
+    public static int unescapeJava(final CharSequence from, final int offset, final Writer output) {
+        // return StringEscapeUtils.UNESCAPE_JAVA.translate(path, pos.getIndex(), target);
+        return UNESCAPE_JAVA.translate(from, offset, output);
+    }
+
+    protected interface CharSequenceTranslator {
+        int translate(CharSequence input, int index, Writer out);
+    }
+
+    private static class AggregateTranslator implements CharSequenceTranslator {
+        private final CharSequenceTranslator[] translators;
+
+        private AggregateTranslator(final CharSequenceTranslator... translators) {
+            this.translators = translators;
+        }
+
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) {
+            for (final CharSequenceTranslator translator : translators) {
+                final int consumed = translator.translate(input, index, out);
+                if(consumed != 0) {
+                    return consumed;
+                }
+            }
+            return 0;
+        }
+    }
+
+    private static class OctalUnescaper implements CharSequenceTranslator {
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) {
+            final int remaining = input.length() - index - 1;
+            final StringBuilder builder = new StringBuilder();
+            if (input.charAt(index) == '\\' && remaining > 0 && isOctalDigit(input.charAt(index + 1))) {
+                final int next = index + 1;
+                final int next2 = index + 2;
+                final int next3 = index + 3;
+
+                builder.append(input.charAt(next));
+
+                if (remaining > 1 && isOctalDigit(input.charAt(next2))) {
+                    builder.append(input.charAt(next2));
+                    if (remaining > 2 && isZeroToThree(input.charAt(next)) && isOctalDigit(input.charAt(next3))) {
+                        builder.append(input.charAt(next3));
+                    }
+                }
+
+                try {
+                    out.write(Integer.parseInt(builder.toString(), 8));
+                } catch (IOException e) {
+                    throw new IllegalStateException(e);
+                }
+                return 1 + builder.length();
+            }
+            return 0;
+        }
+
+        private boolean isOctalDigit(final char ch) {
+            return ch >= '0' && ch <= '7';
+        }
+
+        private boolean isZeroToThree(final char ch) {
+            return ch >= '0' && ch <= '3';
+        }
+    }
+
+    public static class UnicodeUnescaper implements CharSequenceTranslator {
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) {
+            if (input.charAt(index) == '\\' && index + 1 < input.length() && input.charAt(index + 1) == 'u') {
+                int i = 2;
+                while (index + i < input.length() && input.charAt(index + i) == 'u') {
+                    i++;
+                }
+
+                if (index + i < input.length() && input.charAt(index + i) == '+') {
+                    i++;
+                }
+
+                if (index + i + 4 <= input.length()) {
+                    // Get 4 hex digits
+                    final CharSequence unicode = input.subSequence(index + i, index + i + 4);
+
+                    try {
+                        final int value = Integer.parseInt(unicode.toString(), 16);
+                        out.write((char) value);
+                    } catch (final NumberFormatException nfe) {
+                        throw new IllegalArgumentException("Unable to parse unicode value: " + unicode, nfe);
+                    } catch (final IOException e) {
+                        throw new IllegalStateException(e);
+                    }
+                    return i + 4;
+                }
+                throw new IllegalArgumentException("Less than 4 hex digits in unicode value: '" + input.subSequence(index, input.length())
+                        + "' due to end of CharSequence");
+            }
+            return 0;
+        }
+    }
+
+    public static class LookupTranslator implements CharSequenceTranslator {
+        private final Map<String, String> lookupMap;
+        private final Set<Character> prefixSet;
+        private final int shortest;
+        private final int longest;
+
+        private LookupTranslator(final String[][] lookup) {
+            lookupMap = new HashMap<>();
+            prefixSet = new HashSet<>();
+            int _shortest = Integer.MAX_VALUE;
+            int _longest = 0;
+            if (lookup != null) {
+                for (final CharSequence[] seq : lookup) {
+                    this.lookupMap.put(seq[0].toString(), seq[1].toString());
+                    this.prefixSet.add(seq[0].charAt(0));
+                    final int sz = seq[0].length();
+                    if (sz < _shortest) {
+                        _shortest = sz;
+                    }
+                    if (sz > _longest) {
+                        _longest = sz;
+                    }
+                }
+            }
+            shortest = _shortest;
+            longest = _longest;
+        }
+
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) {
+            if (prefixSet.contains(input.charAt(index))) {
+                int max = longest;
+                if (index + longest > input.length()) {
+                    max = input.length() - index;
+                }
+                for (int i = max; i >= shortest; i--) {
+                    final CharSequence subSeq = input.subSequence(index, index + i);
+                    final String result = lookupMap.get(subSeq.toString());
+
+                    if (result != null) {
+                        try {
+                            out.write(result);
+                        } catch (final IOException e) {
+                            throw new IllegalStateException(e);
+                        }
+                        return i;
+                    }
+                }
+            }
+            return 0;
+        }
+    }
+}