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 [11/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/metadata/Meta.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Meta.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,363 @@
+/*
+ * 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.metadata;
+
+import java.lang.annotation.ElementType;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.bval.util.EmulatedAnnotatedType;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.TypeUtils;
+
+/**
+ * Validation class model.
+ *
+ * @param <E>
+ */
+public abstract class Meta<E extends AnnotatedElement> {
+
+ public static class ForClass<T> extends Meta<Class<T>> {
+ private final AnnotatedType annotatedType;
+
+ public ForClass(Class<T> host) {
+ super(host, ElementType.TYPE);
+ this.annotatedType = EmulatedAnnotatedType.wrap(host);
+ }
+
+ @Override
+ public final Class<T> getDeclaringClass() {
+ return getHost();
+ }
+
+ @Override
+ public Type getType() {
+ return getHost();
+ }
+
+ @Override
+ public AnnotatedType getAnnotatedType() {
+ return annotatedType;
+ }
+
+ @Override
+ public String getName() {
+ return getHost().getName();
+ }
+
+ @Override
+ public Meta<?> getParent() {
+ return null;
+ }
+ }
+
+ public static abstract class ForMember<M extends Member & AnnotatedElement> extends Meta<M> {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private final Lazy<Meta<Class<?>>> parent = new Lazy<>(() -> new Meta.ForClass(getDeclaringClass()));
+
+ protected ForMember(M host, ElementType elementType) {
+ super(host, elementType);
+ }
+
+ @Override
+ public Class<?> getDeclaringClass() {
+ return getHost().getDeclaringClass();
+ }
+
+ @Override
+ public Meta<Class<?>> getParent() {
+ return parent.get();
+ }
+ }
+
+ public static class ForField extends ForMember<Field> {
+
+ public ForField(Field host) {
+ super(host, ElementType.FIELD);
+ }
+
+ @Override
+ public Type getType() {
+ return getHost().getGenericType();
+ }
+
+ @Override
+ public AnnotatedType getAnnotatedType() {
+ return getHost().getAnnotatedType();
+ }
+
+ @Override
+ public String getName() {
+ return getHost().getName();
+ }
+ }
+
+ public static abstract class ForExecutable<E extends Executable> extends ForMember<E> {
+
+ protected ForExecutable(E host, ElementType elementType) {
+ super(host, elementType);
+ }
+
+ @Override
+ public AnnotatedType getAnnotatedType() {
+ return getHost().getAnnotatedReturnType();
+ }
+ }
+
+ public static class ForConstructor<T> extends ForExecutable<Constructor<? extends T>> {
+
+ public ForConstructor(Constructor<? extends T> host) {
+ super(host, ElementType.CONSTRUCTOR);
+ }
+
+ @Override
+ public Type getType() {
+ return getHost().getDeclaringClass();
+ }
+
+ @Override
+ public String getName() {
+ return getHost().getDeclaringClass().getSimpleName();
+ }
+ }
+
+ public static class ForMethod extends ForExecutable<Method> {
+
+ public ForMethod(Method host) {
+ super(host, ElementType.METHOD);
+ }
+
+ @Override
+ public Type getType() {
+ return getHost().getGenericReturnType();
+ }
+
+ @Override
+ public String getName() {
+ return getHost().getName();
+ }
+ }
+
+ public static class ForCrossParameter<E extends Executable> extends Meta<E> {
+
+ private final Meta<E> parent;
+
+ public ForCrossParameter(Meta<E> parent) {
+ super(parent.getHost(), parent.getElementType());
+ this.parent = parent;
+ }
+
+ @Override
+ public Type getType() {
+ return Object[].class;
+ }
+
+ @Override
+ public String getName() {
+ return "<cross parameter>";
+ }
+
+ @Override
+ public String describeHost() {
+ return String.format("%s of %s", getName(), getHost());
+ }
+
+ @Override
+ public Meta<E> getParent() {
+ return parent;
+ }
+
+ @Override
+ public Class<?> getDeclaringClass() {
+ return getHost().getDeclaringClass();
+ }
+
+ @Override
+ public AnnotatedType getAnnotatedType() {
+ return getHost().getAnnotatedReturnType();
+ }
+ }
+
+ public static class ForParameter extends Meta<Parameter> {
+
+ private final String name;
+ private final Lazy<Meta<? extends Executable>> parent = new Lazy<>(this::computeParent);
+
+ public ForParameter(Parameter host, String name) {
+ super(host, ElementType.PARAMETER);
+ this.name = Validate.notNull(name, "name");
+ }
+
+ @Override
+ public Type getType() {
+ return getHost().getParameterizedType();
+ }
+
+ @Override
+ public Class<?> getDeclaringClass() {
+ return getHost().getDeclaringExecutable().getDeclaringClass();
+ }
+
+ @Override
+ public AnnotatedType getAnnotatedType() {
+ return getHost().getAnnotatedType();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String describeHost() {
+ return String.format("%s of %s", getName(), getHost().getDeclaringExecutable());
+ }
+
+ @Override
+ public Meta<? extends Executable> getParent() {
+ return parent.get();
+ }
+
+ private Meta<? extends Executable> computeParent() {
+ final Executable exe = getHost().getDeclaringExecutable();
+ return exe instanceof Method ? new Meta.ForMethod((Method) exe)
+ : new Meta.ForConstructor<>((Constructor<?>) exe);
+ }
+ }
+
+ public static class ForContainerElement extends Meta<AnnotatedType> {
+
+ private final Meta<?> parent;
+ private final ContainerElementKey key;
+
+ public ForContainerElement(Meta<?> parent, ContainerElementKey key) {
+ super(key.getAnnotatedType(), ElementType.TYPE_USE);
+ this.parent = Validate.notNull(parent, "parent");
+ this.key = Validate.notNull(key, "key");
+ }
+
+ @Override
+ public Type getType() {
+ Type result = getHost().getType();
+ if (result instanceof TypeVariable<?>) {
+ final Type parentType = parent.getType();
+ if (parentType instanceof ParameterizedType) {
+ final Map<TypeVariable<?>, Type> typeArguments =
+ TypeUtils.getTypeArguments((ParameterizedType) parentType);
+ if (typeArguments.containsKey(result)) {
+ return typeArguments.get(result);
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public Class<?> getDeclaringClass() {
+ return parent.getDeclaringClass();
+ }
+
+ @Override
+ public AnnotatedType getAnnotatedType() {
+ return key.getAnnotatedType();
+ }
+
+ public Integer getTypeArgumentIndex() {
+ return Integer.valueOf(key.getTypeArgumentIndex());
+ }
+
+ @Override
+ public String getName() {
+ return key.toString();
+ }
+
+ @Override
+ public String describeHost() {
+ return String.format("%s of %s", key, parent);
+ }
+
+ @Override
+ public Meta<?> getParent() {
+ return parent;
+ }
+ }
+
+ private final E host;
+ private final ElementType elementType;
+
+ protected Meta(E host, ElementType elementType) {
+ super();
+ this.host = Validate.notNull(host, "host");
+ this.elementType = Validate.notNull(elementType, "elementType");
+ }
+
+ public E getHost() {
+ return host;
+ }
+
+ public ElementType getElementType() {
+ return elementType;
+ }
+
+ public abstract Type getType();
+
+ public abstract Class<?> getDeclaringClass();
+
+ public abstract AnnotatedType getAnnotatedType();
+
+ public abstract String getName();
+
+ public abstract Meta<?> getParent();
+
+ @Override
+ public final String toString() {
+ return String.format("%s.%s(%s)", Meta.class.getSimpleName(), getClass().getSimpleName(), describeHost());
+ }
+
+ public String describeHost() {
+ return host.toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!obj.getClass().equals(getClass())) {
+ return false;
+ }
+ return Objects.equals(((Meta<?>) obj).getHost(), getHost());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getHost());
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilder.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilder.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilder.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilder.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,96 @@
+/*
+ * 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.metadata;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.bval.jsr.groups.GroupConversion;
+
+/**
+ * Common interface for populating the Bean Validation descriptors from various sources. Most implementations should
+ * concern themselves with a single level of an inheritance hierarchy.
+ */
+public final class MetadataBuilder {
+
+ public interface ForBean<T> extends HasAnnotationBehavior {
+ MetadataBuilder.ForClass<T> getClass(Meta<Class<T>> meta);
+
+ Map<String, ForContainer<Field>> getFields(Meta<Class<T>> meta);
+
+ /**
+ * Returned keys are property names per XML mapping spec.
+ *
+ * @param meta
+ * @return {@link Map}
+ */
+ Map<String, ForContainer<Method>> getGetters(Meta<Class<T>> meta);
+
+ Map<Signature, ForExecutable<Constructor<? extends T>>> getConstructors(Meta<Class<T>> meta);
+
+ Map<Signature, ForExecutable<Method>> getMethods(Meta<Class<T>> meta);
+
+ default boolean isEmpty() {
+ return false;
+ }
+ }
+
+ public interface ForElement<E extends AnnotatedElement> extends HasAnnotationBehavior {
+
+ Annotation[] getDeclaredConstraints(Meta<E> meta);
+
+ default Map<Meta<E>, Annotation[]> getConstraintDeclarationMap(Meta<E> meta) {
+ return Collections.singletonMap(meta, getDeclaredConstraints(meta));
+ }
+ }
+
+ public interface ForClass<T> extends ForElement<Class<T>> {
+
+ List<Class<?>> getGroupSequence(Meta<Class<T>> meta);
+ }
+
+ public interface ForContainer<E extends AnnotatedElement> extends MetadataBuilder.ForElement<E> {
+
+ boolean isCascade(Meta<E> meta);
+
+ Set<GroupConversion> getGroupConversions(Meta<E> meta);
+
+ Map<ContainerElementKey, ForContainer<AnnotatedType>> getContainerElementTypes(Meta<E> meta);
+ }
+
+ public interface ForExecutable<E extends Executable> extends HasAnnotationBehavior {
+
+ MetadataBuilder.ForContainer<E> getReturnValue(Meta<E> meta);
+
+ MetadataBuilder.ForElement<E> getCrossParameter(Meta<E> meta);
+
+ List<ForContainer<Parameter>> getParameters(Meta<E> meta);
+ }
+
+ private MetadataBuilder() {
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilders.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilders.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilders.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataBuilders.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,62 @@
+/*
+ * 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.metadata;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.validation.ValidationException;
+
+import org.apache.bval.jsr.util.Methods;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Validate;
+
+public class MetadataBuilders {
+
+ private final Map<Class<?>, List<MetadataBuilder.ForBean<?>>> beanBuilders = new ConcurrentHashMap<>();
+
+ public <T> void registerCustomBuilder(Class<T> bean, MetadataBuilder.ForBean<T> builder) {
+ Validate.notNull(bean, "bean");
+ Validate.notNull(builder, "builder");
+ validateCustomBuilder(bean, builder);
+ beanBuilders.computeIfAbsent(bean, c -> new ArrayList<>()).add(builder);
+ }
+
+ public <T> List<MetadataBuilder.ForBean<T>> getCustomBuilders(Class<T> bean) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ final List<MetadataBuilder.ForBean<T>> list = (List) beanBuilders.get(bean);
+ return list == null ? Collections.emptyList() : Collections.unmodifiableList(list);
+ }
+
+ public Set<Class<?>> getCustomizedTypes() {
+ return beanBuilders.keySet();
+ }
+
+ private <T> void validateCustomBuilder(Class<T> bean, MetadataBuilder.ForBean<T> builder) {
+ final Meta<Class<T>> meta = new Meta.ForClass<>(bean);
+ final Set<String> propertyNames = builder.getGetters(meta).keySet();
+ builder.getMethods(meta).keySet().stream().map(Signature::getName).filter(Methods::isGetter)
+ .map(Methods::propertyName).forEach(pn -> {
+ Exceptions.raiseIf(propertyNames.contains(pn), ValidationException::new,
+ "%s user metadata cannot specify both method and getter elements for %s", f -> f.args(bean, pn));
+ });
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataSource.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataSource.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataSource.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/MetadataSource.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,40 @@
+/*
+ * 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.metadata;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.spi.ConfigurationState;
+
+/**
+ * Service interface for user metadata customizations.
+ */
+public interface MetadataSource {
+
+ /**
+ * Add {@link ConstraintValidator} mappings and/or metadata builders.
+ *
+ * @param configurationState
+ * may be read for environmental cues
+ * @param addMappingProvider
+ * @param addBuilder
+ */
+ void process(ConfigurationState configurationState, Consumer<ValidatorMappingProvider> addMappingProvider,
+ BiConsumer<Class<?>, MetadataBuilder.ForBean<?>> addBuilder);
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ReflectionBuilder.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,376 @@
+/*
+ * 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.metadata;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import javax.validation.ConstraintDeclarationException;
+import javax.validation.ConstraintTarget;
+import javax.validation.GroupSequence;
+import javax.validation.ParameterNameProvider;
+import javax.validation.Valid;
+import javax.validation.constraintvalidation.ValidationTarget;
+import javax.validation.groups.ConvertGroup;
+
+import org.apache.bval.jsr.ApacheValidatorFactory;
+import org.apache.bval.jsr.ConstraintAnnotationAttributes;
+import org.apache.bval.jsr.groups.GroupConversion;
+import org.apache.bval.jsr.util.AnnotationsManager;
+import org.apache.bval.jsr.util.Methods;
+import org.apache.bval.jsr.util.ToUnmodifiable;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.ObjectUtils;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+@Privilizing(@CallTo(Reflection.class))
+public class ReflectionBuilder {
+
+ private class ForBean<T> implements MetadataBuilder.ForBean<T> {
+ private final Meta<Class<T>> meta;
+
+ ForBean(Meta<Class<T>> meta) {
+ super();
+ this.meta = Validate.notNull(meta, "meta");
+ }
+
+ @Override
+ public MetadataBuilder.ForClass<T> getClass(Meta<Class<T>> ignored) {
+ return new ReflectionBuilder.ForClass<>(meta);
+ }
+
+ @Override
+ public Map<String, MetadataBuilder.ForContainer<Field>> getFields(Meta<Class<T>> ignored) {
+ final Field[] declaredFields = Reflection.getDeclaredFields(meta.getHost());
+ if (declaredFields.length == 0) {
+ return Collections.emptyMap();
+ }
+ return Stream.of(declaredFields).filter(f -> !(Modifier.isStatic(f.getModifiers()) || f.isSynthetic()))
+ .collect(
+ Collectors.toMap(Field::getName, f -> new ReflectionBuilder.ForContainer<>(new Meta.ForField(f))));
+ }
+
+ @Override
+ public Map<String, MetadataBuilder.ForContainer<Method>> getGetters(Meta<Class<T>> ignored) {
+ final Method[] declaredMethods = Reflection.getDeclaredMethods(meta.getHost());
+ if (declaredMethods.length == 0) {
+ return Collections.emptyMap();
+ }
+ final Map<String, Set<Method>> getters = new HashMap<>();
+ for (Method m : declaredMethods) {
+ if (Methods.isGetter(m)) {
+ getters.computeIfAbsent(Methods.propertyName(m), k -> new LinkedHashSet<>()).add(m);
+ }
+ }
+ final Map<String, MetadataBuilder.ForContainer<Method>> result = new TreeMap<>();
+ getters.forEach((k, methods) -> {
+ if ("class".equals(k)) {
+ return;
+ }
+ final List<MetadataBuilder.ForContainer<Method>> delegates = methods.stream()
+ .map(g -> new ReflectionBuilder.ForContainer<>(new Meta.ForMethod(g))).collect(Collectors.toList());
+ if (delegates.isEmpty()) {
+ return;
+ }
+ final MetadataBuilder.ForContainer<Method> builder;
+ if (delegates.size() == 1) {
+ builder = delegates.get(0);
+ } else {
+ builder = compositeBuilder.get().new ForContainer<>(delegates);
+ }
+ result.put(k, builder);
+ });
+ return result;
+ }
+
+ @Override
+ public Map<Signature, MetadataBuilder.ForExecutable<Constructor<? extends T>>> getConstructors(Meta<Class<T>> ignored) {
+ final Constructor<? extends T>[] declaredConstructors = Reflection.getDeclaredConstructors(meta.getHost());
+ if (declaredConstructors.length == 0) {
+ return Collections.emptyMap();
+ }
+ return Stream.of(declaredConstructors).collect(
+ Collectors.toMap(Signature::of, c -> new ReflectionBuilder.ForExecutable<>(new Meta.ForConstructor<>(c),
+ ParameterNameProvider::getParameterNames)));
+ }
+
+ @Override
+ public Map<Signature, MetadataBuilder.ForExecutable<Method>> getMethods(Meta<Class<T>> ignored) {
+ final Method[] declaredMethods = Reflection.getDeclaredMethods(meta.getHost());
+ if (declaredMethods.length == 0) {
+ return Collections.emptyMap();
+ }
+ final Map<Signature, Set<Method>> methodsBySignature = new HashMap<>();
+ for (Method m : declaredMethods) {
+ if (!Modifier.isStatic(m.getModifiers())) {
+ methodsBySignature.computeIfAbsent(Signature.of(m), k -> new LinkedHashSet<>()).add(m);
+ }
+ }
+ final Map<Signature, MetadataBuilder.ForExecutable<Method>> result = new TreeMap<>();
+
+ // we can't filter the getters since they can be validated, todo: read the config to know if we need or not
+
+ methodsBySignature.forEach((sig, methods) -> {
+ final List<MetadataBuilder.ForExecutable<Method>> delegates =
+ methods.stream().map(g -> new ReflectionBuilder.ForExecutable<>(new Meta.ForMethod(g),
+ ParameterNameProvider::getParameterNames)).collect(Collectors.toList());
+ if (delegates.isEmpty()) {
+ return;
+ }
+ final MetadataBuilder.ForExecutable<Method> builder;
+ if (delegates.size() == 1) {
+ builder = delegates.get(0);
+ } else {
+ builder = compositeBuilder.get().new ForExecutable<MetadataBuilder.ForExecutable<Method>, Method>(
+ delegates, ParameterNameProvider::getParameterNames);
+ }
+ result.put(sig, builder);
+ });
+ return result;
+ }
+ }
+
+ private abstract class ForElement<E extends AnnotatedElement> implements MetadataBuilder.ForElement<E> {
+ final Meta<E> meta;
+
+ ForElement(Meta<E> meta) {
+ super();
+ this.meta = Validate.notNull(meta, "meta");
+ }
+
+ @Override
+ public Annotation[] getDeclaredConstraints(Meta<E> ignored) {
+ return AnnotationsManager.getDeclaredConstraints(meta);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this || this.getClass().isInstance(obj) && ((ForElement<?>) obj).meta.equals(meta);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getClass(), meta);
+ }
+ }
+
+ private class ForClass<T> extends ForElement<Class<T>> implements MetadataBuilder.ForClass<T> {
+
+ ForClass(Meta<Class<T>> meta) {
+ super(meta);
+ }
+
+ @Override
+ public List<Class<?>> getGroupSequence(Meta<Class<T>> ignored) {
+ final GroupSequence groupSequence = AnnotationsManager.getAnnotation(meta.getHost(), GroupSequence.class);
+ return groupSequence == null ? null : Collections.unmodifiableList(Arrays.asList(groupSequence.value()));
+ }
+ }
+
+ private class ForContainer<E extends AnnotatedElement> extends ReflectionBuilder.ForElement<E>
+ implements MetadataBuilder.ForContainer<E> {
+
+ ForContainer(Meta<E> meta) {
+ super(meta);
+ }
+
+ @Override
+ public Map<ContainerElementKey, MetadataBuilder.ForContainer<AnnotatedType>> getContainerElementTypes(
+ Meta<E> ignored) {
+ final AnnotatedType annotatedType = meta.getAnnotatedType();
+ if (annotatedType instanceof AnnotatedParameterizedType) {
+
+ final AnnotatedParameterizedType container = (AnnotatedParameterizedType) annotatedType;
+
+ final Map<ContainerElementKey, MetadataBuilder.ForContainer<AnnotatedType>> result = new TreeMap<>();
+
+ final AnnotatedType[] typeArgs = container.getAnnotatedActualTypeArguments();
+ for (int i = 0; i < typeArgs.length; i++) {
+ final ContainerElementKey key = new ContainerElementKey(container, i);
+ result.put(key, new ReflectionBuilder.ForContainer<>(new Meta.ForContainerElement(meta, key)));
+ }
+ return result;
+ }
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public boolean isCascade(Meta<E> ignored) {
+ return AnnotationsManager.isAnnotationDirectlyPresent(meta.getHost(), Valid.class);
+ }
+
+ @Override
+ public Set<GroupConversion> getGroupConversions(Meta<E> ignored) {
+ return Stream.of(AnnotationsManager.getDeclaredAnnotationsByType(meta.getHost(), ConvertGroup.class))
+ .map(cg -> GroupConversion.from(cg.from()).to(cg.to())).collect(ToUnmodifiable.set());
+ }
+ }
+
+ private class ForExecutable<E extends Executable> implements MetadataBuilder.ForExecutable<E> {
+
+ final Meta<E> meta;
+ final BiFunction<ParameterNameProvider, E, List<String>> getParameterNames;
+
+ ForExecutable(Meta<E> meta, BiFunction<ParameterNameProvider,E, List<String>> getParameterNames) {
+ super();
+ this.meta = Validate.notNull(meta, "meta");
+ this.getParameterNames = Validate.notNull(getParameterNames, "getParameterNames");
+ }
+
+ @Override
+ public List<MetadataBuilder.ForContainer<Parameter>> getParameters(Meta<E> ignored) {
+ final Parameter[] parameters = meta.getHost().getParameters();
+ if (parameters.length == 0) {
+ return Collections.emptyList();
+ }
+ final List<String> parameterNames = getParameterNames.apply(validatorFactory.getParameterNameProvider(),meta.getHost());
+
+ return IntStream.range(0, parameters.length).mapToObj(
+ n -> new ReflectionBuilder.ForContainer<>(new Meta.ForParameter(parameters[n], parameterNames.get(n))))
+ .collect(ToUnmodifiable.list());
+ }
+
+ @Override
+ public ForContainer<E> getReturnValue(Meta<E> ignored) {
+ return new ReflectionBuilder.ForContainer<E>(meta) {
+
+ @Override
+ public Annotation[] getDeclaredConstraints(Meta<E> meta) {
+ return getConstraints(ConstraintTarget.RETURN_VALUE);
+ }
+ };
+ }
+
+ @Override
+ public MetadataBuilder.ForElement<E> getCrossParameter(Meta<E> ignored) {
+ return new ReflectionBuilder.ForElement<E>(meta) {
+ @Override
+ public Annotation[] getDeclaredConstraints(Meta<E> meta) {
+ return getConstraints(ConstraintTarget.PARAMETERS);
+ }
+ };
+ }
+
+ private Annotation[] getConstraints(ConstraintTarget constraintTarget) {
+ return Optional.of(getConstraintsByTarget()).map(m -> m.get(constraintTarget))
+ .map(l -> l.toArray(new Annotation[l.size()])).orElse(ObjectUtils.EMPTY_ANNOTATION_ARRAY);
+ }
+
+ private Map<ConstraintTarget, List<Annotation>> getConstraintsByTarget() {
+ final Annotation[] declaredConstraints = AnnotationsManager.getDeclaredConstraints(meta);
+ if (ObjectUtils.isEmptyArray(declaredConstraints)) {
+ return Collections.emptyMap();
+ }
+ final Map<ConstraintTarget, List<Annotation>> result = new EnumMap<>(ConstraintTarget.class);
+
+ for (Annotation constraint : declaredConstraints) {
+ final Class<? extends Annotation> constraintType = constraint.annotationType();
+ final Optional<ConstraintTarget> explicitTarget =
+ Optional.of(ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO.analyze(constraintType))
+ .filter(ConstraintAnnotationAttributes.Worker::isValid)
+ .<ConstraintTarget> map(w -> w.read(constraint)).filter(et -> et != ConstraintTarget.IMPLICIT);
+
+ final ConstraintTarget target;
+
+ if (explicitTarget.isPresent()) {
+ target = explicitTarget.get();
+ } else {
+ final Set<ValidationTarget> supportedTargets =
+ validatorFactory.getAnnotationsManager().supportedTargets(constraintType);
+
+ if (supportedTargets.size() == 1) {
+ final ValidationTarget validationTarget = supportedTargets.iterator().next();
+ switch (validationTarget) {
+ case PARAMETERS:
+ target = ConstraintTarget.PARAMETERS;
+ break;
+ case ANNOTATED_ELEMENT:
+ target = ConstraintTarget.RETURN_VALUE;
+ break;
+ default:
+ throw Exceptions.create(IllegalStateException::new, "Unknown %s %s for %s",
+ ValidationTarget.class.getSimpleName(), validationTarget, constraintType);
+ }
+ } else {
+ target = impliedConstraintTarget();
+ if (target == null) {
+ Exceptions.raise(ConstraintDeclarationException::new,
+ "Found %d possible %s types for constraint type %s and no explicit assignment via #%s()",
+ supportedTargets.size(), ValidationTarget.class.getSimpleName(),
+ constraintType.getName(),
+ ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO.getAttributeName());
+ }
+ }
+ }
+ result.computeIfAbsent(target, k -> new ArrayList<>()).add(constraint);
+ }
+ return result;
+ }
+
+ private ConstraintTarget impliedConstraintTarget() {
+ if (meta.getHost().getParameterCount() == 0) {
+ return ConstraintTarget.RETURN_VALUE;
+ }
+ if (Void.TYPE.equals(meta.getType())) {
+ return ConstraintTarget.PARAMETERS;
+ }
+ return null;
+ }
+ }
+
+ private final ApacheValidatorFactory validatorFactory;
+ private final Lazy<CompositeBuilder> compositeBuilder;
+
+ public ReflectionBuilder(ApacheValidatorFactory validatorFactory) {
+ super();
+ this.validatorFactory = Validate.notNull(validatorFactory, "validatorFactory");
+ this.compositeBuilder =
+ new Lazy<>(() -> new CompositeBuilder(this.validatorFactory, x -> AnnotationBehavior.ABSTAIN));
+ }
+
+ public <T> MetadataBuilder.ForBean<T> forBean(Class<T> beanClass) {
+ return new ReflectionBuilder.ForBean<>(new Meta.ForClass<T>(beanClass));
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Signature.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Signature.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Signature.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/Signature.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,91 @@
+/*
+ * 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.metadata;
+
+import java.lang.reflect.Executable;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.bval.jsr.util.Methods;
+import org.apache.bval.util.Comparators;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.LazyInt;
+import org.apache.bval.util.StringUtils;
+import org.apache.bval.util.Validate;
+
+public final class Signature implements Comparable<Signature> {
+ private static final Comparator<Signature> COMPARATOR = Comparator.nullsFirst(Comparator
+ .comparing(Signature::getName).thenComparing(Comparator.comparing(s -> Arrays.asList(s.getParameterTypes()),
+ Comparators.comparingIterables(Comparator.comparing(Class::getName)))));
+
+ public static Signature of(Executable x) {
+ return new Signature(x.getName(), x.getParameterTypes());
+ }
+
+ private final String name;
+ private final Class<?>[] parameterTypes;
+ private final LazyInt hashCode;
+ private final Lazy<String> toString;
+
+ public Signature(String name, Class<?>... parameterTypes) {
+ super();
+ this.name = Validate.notNull(name, "name");
+ Validate.isTrue(StringUtils.isNotBlank(name), "name is blank");
+ this.parameterTypes = Validate.notNull(parameterTypes, "parameterTypes").clone();
+ hashCode = new LazyInt(() -> Arrays.deepHashCode(new Object[] { this.name, this.parameterTypes }));
+ toString = new Lazy<>(() -> String.format("%s: %s(%s)", getClass().getSimpleName(), this.name,
+ Stream.of(this.parameterTypes).map(Class::getName).collect(Collectors.joining(", "))));
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Class<?>[] getParameterTypes() {
+ return parameterTypes.clone();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this || Optional.ofNullable(obj).filter(Signature.class::isInstance).map(Signature.class::cast)
+ .filter(sig -> Objects.equals(name, sig.name) && Objects.deepEquals(parameterTypes, sig.parameterTypes))
+ .isPresent();
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode.getAsInt();
+ }
+
+ @Override
+ public String toString() {
+ return toString.get();
+ }
+
+ @Override
+ public int compareTo(Signature sig) {
+ return COMPARATOR.compare(this, sig);
+ }
+
+ public boolean isGetter() {
+ return parameterTypes.length == 0 && Methods.isGetter(name);
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMapping.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMapping.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMapping.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMapping.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,121 @@
+/*
+ * 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.metadata;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import javax.validation.ConstraintValidator;
+
+import org.apache.bval.util.Validate;
+
+public class ValidatorMapping<A extends Annotation> implements HasAnnotationBehavior {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private static final ValidatorMapping EMPTY = new ValidatorMapping("empty", Collections.emptyList());
+
+ @SuppressWarnings("unchecked")
+ public static <A extends Annotation> ValidatorMapping<A> empty() {
+ return EMPTY;
+ }
+
+ public static <A extends Annotation> ValidatorMapping<A> merge(
+ List<? extends ValidatorMapping<A>> validatorMappings,
+ AnnotationBehaviorMergeStrategy annotationBehaviorMergeStrategy) {
+
+ final AnnotationBehavior behavior = annotationBehaviorMergeStrategy.apply(validatorMappings);
+
+ final List<? extends ValidatorMapping<A>> nonEmpty =
+ validatorMappings.stream().filter(m -> !m.isEmpty()).collect(Collectors.toList());
+
+ if (nonEmpty.size() <= 1) {
+ // avoid creating the composite instance if behavior matches:
+ final ValidatorMapping<A> simpleResult = nonEmpty.isEmpty() ? empty() : nonEmpty.get(0);
+
+ if (simpleResult.hasBehavior(behavior)) {
+ return simpleResult;
+ }
+ }
+ final String source =
+ nonEmpty.stream().map(ValidatorMapping::getSource).collect(Collectors.joining(";", "[", "]"));
+
+ return new ValidatorMapping<>(source, nonEmpty.stream().map(ValidatorMapping::getValidatorTypes)
+ .flatMap(Collection::stream).distinct().collect(Collectors.toList()), behavior);
+ }
+
+ private final String source;
+ private final List<Class<? extends ConstraintValidator<A, ?>>> validatorTypes;
+ private final AnnotationBehavior annotationBehavior;
+
+ public ValidatorMapping(String source, List<Class<? extends ConstraintValidator<A, ?>>> validatorTypes) {
+ this(source, validatorTypes, AnnotationBehavior.ABSTAIN);
+ }
+
+ public ValidatorMapping(String source, List<Class<? extends ConstraintValidator<A, ?>>> validatorTypes,
+ AnnotationBehavior annotationBehavior) {
+ this.source = Objects.toString(source, "unspecified");
+ this.validatorTypes = Collections.unmodifiableList(Validate.notNull(validatorTypes, "validatorTypes"));
+ this.annotationBehavior = Validate.notNull(annotationBehavior, "annotationBehavior");
+ }
+
+ public List<Class<? extends ConstraintValidator<A, ?>>> getValidatorTypes() {
+ return validatorTypes;
+ }
+
+ public AnnotationBehavior getAnnotationBehavior() {
+ return annotationBehavior;
+ }
+
+ public boolean isEmpty() {
+ return validatorTypes.isEmpty();
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!getClass().isInstance(obj)) {
+ return false;
+ }
+ final ValidatorMapping<?> other = (ValidatorMapping<?>) obj;
+ return getSource().equals(other.getSource()) && getAnnotationBehavior() == other.getAnnotationBehavior()
+ && getValidatorTypes().equals(other.getValidatorTypes());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getSource(), getAnnotationBehavior(), getValidatorTypes());
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s[source: %s; annotationBehavior: %s; validatorTypes: %s]",
+ ValidatorMapping.class.getSimpleName(), getSource(), getAnnotationBehavior(), getValidatorTypes());
+ }
+
+ public boolean hasBehavior(AnnotationBehavior annotationBehavior) {
+ return getAnnotationBehavior() == annotationBehavior;
+ }
+}
\ No newline at end of file
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/ValidatorMappingProvider.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr.metadata;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Optional;
+
+import javax.validation.ConstraintDefinitionException;
+import javax.validation.ConstraintValidator;
+
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.reflection.TypeUtils;
+
+public abstract class ValidatorMappingProvider {
+
+ public final <A extends Annotation> ValidatorMapping<A> getValidatorMapping(Class<A> constraintType) {
+ final Optional<ValidatorMapping<A>> result =
+ Optional.ofNullable(this.<A> doGetValidatorMapping(constraintType));
+ if (result.isPresent()) {
+ for (Class<? extends ConstraintValidator<A, ?>> t : result.get().getValidatorTypes()) {
+ final Type constraintParameter = TypeUtils.getTypeArguments(t, ConstraintValidator.class)
+ .get(ConstraintValidator.class.getTypeParameters()[0]);
+
+ if (!constraintType.equals(constraintParameter)) {
+ Exceptions.raise(ConstraintDefinitionException::new,
+ "%s %s expected first type parameter of %s, %s; source %s", ConstraintValidator.class, t,
+ constraintType, constraintParameter, result.get().getSource());
+ }
+ }
+ return result.get();
+ }
+ return null;
+ }
+
+ protected abstract <A extends Annotation> ValidatorMapping<A> doGetValidatorMapping(Class<A> constraintType);
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlBuilder.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlBuilder.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlBuilder.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlBuilder.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,704 @@
+/*
+ * 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.metadata;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+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.ConstraintDeclarationException;
+import javax.validation.ConstraintTarget;
+import javax.validation.Payload;
+import javax.validation.ValidationException;
+import javax.validation.groups.Default;
+import javax.xml.bind.JAXBElement;
+
+import org.apache.bval.jsr.ConstraintAnnotationAttributes;
+import org.apache.bval.jsr.groups.GroupConversion;
+import org.apache.bval.jsr.util.ToUnmodifiable;
+import org.apache.bval.jsr.xml.AnnotationProxyBuilder;
+import org.apache.bval.jsr.xml.AnnotationType;
+import org.apache.bval.jsr.xml.BeanType;
+import org.apache.bval.jsr.xml.ClassType;
+import org.apache.bval.jsr.xml.ConstraintMappingsType;
+import org.apache.bval.jsr.xml.ConstraintType;
+import org.apache.bval.jsr.xml.ConstructorType;
+import org.apache.bval.jsr.xml.ContainerElementTypeType;
+import org.apache.bval.jsr.xml.CrossParameterType;
+import org.apache.bval.jsr.xml.ElementType;
+import org.apache.bval.jsr.xml.FieldType;
+import org.apache.bval.jsr.xml.GetterType;
+import org.apache.bval.jsr.xml.GroupConversionType;
+import org.apache.bval.jsr.xml.GroupSequenceType;
+import org.apache.bval.jsr.xml.GroupsType;
+import org.apache.bval.jsr.xml.MappingValidator;
+import org.apache.bval.jsr.xml.MethodType;
+import org.apache.bval.jsr.xml.ParameterType;
+import org.apache.bval.jsr.xml.PayloadType;
+import org.apache.bval.jsr.xml.ReturnValueType;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.ObjectUtils;
+import org.apache.bval.util.StringUtils;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+@Privilizing(@CallTo(Reflection.class))
+public class XmlBuilder {
+ //@formatter:off
+ public enum Version {
+ v10("1.0"), v11("1.1"), v20("2.0");
+ //@formatter:on
+
+ static Version of(ConstraintMappingsType constraintMappings) {
+ Validate.notNull(constraintMappings);
+ String version = constraintMappings.getVersion();
+ if (StringUtils.isBlank(version)) {
+ return v10;
+ }
+ version = version.trim();
+ for (Version candidate : values()) {
+ if (candidate.id.equals(version)) {
+ return candidate;
+ }
+ }
+ throw new ValidationException("Unknown schema version: " + version);
+ }
+
+ private final String id;
+
+ private Version(String number) {
+ this.id = number;
+ }
+
+ public String getId() {
+ return id;
+ }
+ }
+
+ private class ForBean<T> implements MetadataBuilder.ForBean<T> {
+
+ private final BeanType descriptor;
+
+ ForBean(BeanType descriptor) {
+ super();
+ this.descriptor = Validate.notNull(descriptor, "descriptor");
+ }
+
+ Class<?> getBeanClass() {
+ return resolveClass(descriptor.getClazz());
+ }
+
+ @Override
+ public MetadataBuilder.ForClass<T> getClass(Meta<Class<T>> meta) {
+ final ClassType classType = descriptor.getClassType();
+ return classType == null ? EmptyBuilder.instance().<T> forBean().getClass(meta)
+ : new XmlBuilder.ForClass<T>(classType);
+ }
+
+ @Override
+ public Map<String, MetadataBuilder.ForContainer<Field>> getFields(Meta<Class<T>> meta) {
+ return descriptor.getField().stream()
+ .collect(ToUnmodifiable.map(FieldType::getName, XmlBuilder.ForField::new));
+ }
+
+ @Override
+ public Map<String, MetadataBuilder.ForContainer<Method>> getGetters(Meta<Class<T>> meta) {
+ return descriptor.getGetter().stream()
+ .collect(ToUnmodifiable.map(GetterType::getName, XmlBuilder.ForGetter::new));
+ }
+
+ @Override
+ public Map<Signature, MetadataBuilder.ForExecutable<Constructor<? extends T>>> getConstructors(Meta<Class<T>> meta) {
+ if (!atLeast(Version.v11)) {
+ return Collections.emptyMap();
+ }
+ final Function<ConstructorType, Class<?>[]> params = ct -> ct.getParameter().stream()
+ .map(ParameterType::getType).map(XmlBuilder.this::resolveClass).toArray(Class[]::new);
+
+ final Function<ConstructorType, Signature> signature =
+ ct -> new Signature(meta.getHost().getName(), params.apply(ct));
+
+ return descriptor.getConstructor().stream()
+ .collect(Collectors.toMap(signature, XmlBuilder.ForConstructor::new));
+ }
+
+ @Override
+ public Map<Signature, MetadataBuilder.ForExecutable<Method>> getMethods(Meta<Class<T>> meta) {
+ if (!atLeast(Version.v11)) {
+ return Collections.emptyMap();
+ }
+ final Function<MethodType, Class<?>[]> params = mt -> mt.getParameter().stream().map(ParameterType::getType)
+ .map(XmlBuilder.this::resolveClass).toArray(Class[]::new);
+
+ final Function<MethodType, Signature> signature = mt -> new Signature(mt.getName(), params.apply(mt));
+
+ return descriptor.getMethod().stream().collect(Collectors.toMap(signature, XmlBuilder.ForMethod::new));
+ }
+
+ @Override
+ public final AnnotationBehavior getAnnotationBehavior() {
+ return descriptor.getIgnoreAnnotations() ? AnnotationBehavior.EXCLUDE : AnnotationBehavior.INCLUDE;
+ }
+ }
+
+ private class NonRootLevel<SELF extends NonRootLevel<SELF, D>, D> implements HasAnnotationBehavior {
+ protected final D descriptor;
+ private Lazy<Boolean> getIgnoreAnnotations;
+
+ public NonRootLevel(D descriptor) {
+ super();
+ this.descriptor = Validate.notNull(descriptor, "descriptor");
+ }
+
+ @Override
+ public final AnnotationBehavior getAnnotationBehavior() {
+ return Optional.ofNullable(getIgnoreAnnotations).map(Lazy::get)
+ .map(b -> b.booleanValue() ? AnnotationBehavior.EXCLUDE : AnnotationBehavior.INCLUDE)
+ .orElse(AnnotationBehavior.ABSTAIN);
+ }
+
+ @SuppressWarnings("unchecked")
+ final SELF withGetIgnoreAnnotations(Function<D, Boolean> getIgnoreAnnotations) {
+ Validate.notNull(getIgnoreAnnotations);
+ this.getIgnoreAnnotations = new Lazy<>(() -> getIgnoreAnnotations.apply(descriptor));
+ return (SELF) this;
+ }
+ }
+
+ private class ForElement<SELF extends XmlBuilder.ForElement<SELF, E, D>, E extends AnnotatedElement, D>
+ extends NonRootLevel<SELF, D> implements MetadataBuilder.ForElement<E> {
+
+ private Lazy<Annotation[]> getDeclaredConstraints;
+
+ ForElement(D descriptor) {
+ super(descriptor);
+ }
+
+ @Override
+ public final Annotation[] getDeclaredConstraints(Meta<E> meta) {
+ return lazy(getDeclaredConstraints, "getDeclaredConstraints");
+ }
+
+ final SELF withGetConstraintTypes(Function<D, List<ConstraintType>> getConstraintTypes) {
+ return withGetDeclaredConstraints(getConstraintTypes
+ .andThen(l -> l.stream().map(XmlBuilder.this::createConstraint).toArray(Annotation[]::new)));
+ }
+
+ @SuppressWarnings("unchecked")
+ final SELF withGetDeclaredConstraints(Function<D, Annotation[]> getDeclaredConstraints) {
+ this.getDeclaredConstraints = new Lazy<>(() -> getDeclaredConstraints.apply(descriptor));
+ return (SELF) this;
+ }
+ }
+
+ private class ForClass<T> extends ForElement<ForClass<T>, Class<T>, ClassType> implements MetadataBuilder.ForClass<T> {
+
+ ForClass(ClassType descriptor) {
+ super(descriptor);
+ this.withGetConstraintTypes(ClassType::getConstraint)
+ .withGetIgnoreAnnotations(ClassType::getIgnoreAnnotations);
+ }
+
+ @Override
+ public List<Class<?>> getGroupSequence(Meta<Class<T>> meta) {
+ final GroupSequenceType groupSequence = descriptor.getGroupSequence();
+ return groupSequence == null ? null
+ : groupSequence.getValue().stream().map(XmlBuilder.this::resolveClass).collect(ToUnmodifiable.list());
+ }
+ }
+
+ private class ForContainer<SELF extends XmlBuilder.ForContainer<SELF, E, D>, E extends AnnotatedElement, D>
+ extends XmlBuilder.ForElement<SELF, E, D> implements MetadataBuilder.ForContainer<E> {
+
+ private Lazy<Boolean> isCascade;
+ private Lazy<Set<GroupConversion>> getGroupConversions;
+ private Lazy<List<ContainerElementTypeType>> getContainerElementTypes;
+
+ ForContainer(D descriptor) {
+ super(descriptor);
+ }
+
+ @Override
+ public boolean isCascade(Meta<E> meta) {
+ return Boolean.TRUE.equals(lazy(isCascade, "isCascade"));
+ }
+
+ @Override
+ public Set<GroupConversion> getGroupConversions(Meta<E> meta) {
+ return lazy(getGroupConversions, "getGroupConversions");
+ }
+
+ @Override
+ public Map<ContainerElementKey, MetadataBuilder.ForContainer<AnnotatedType>> getContainerElementTypes(
+ Meta<E> meta) {
+ if (!atLeast(Version.v20)) {
+ return Collections.emptyMap();
+ }
+ final List<ContainerElementTypeType> elements = lazy(getContainerElementTypes, "getContainerElementTypes");
+ final AnnotatedType annotatedType = meta.getAnnotatedType();
+ final E host = meta.getHost();
+
+ if (annotatedType instanceof AnnotatedParameterizedType) {
+ final AnnotatedType[] actualTypeArguments =
+ ((AnnotatedParameterizedType) annotatedType).getAnnotatedActualTypeArguments();
+
+ return elements.stream().collect(ToUnmodifiable.map(cet -> {
+ Integer typeArgumentIndex = cet.getTypeArgumentIndex();
+ if (typeArgumentIndex == null) {
+ Exceptions.raiseIf(actualTypeArguments.length > 1, ValidationException::new,
+ "Missing required type argument index for %s", host);
+ typeArgumentIndex = Integer.valueOf(0);
+ }
+ return new ContainerElementKey(annotatedType, typeArgumentIndex);
+ }, XmlBuilder.ForContainerElementType::new));
+ }
+ if (!elements.isEmpty()) {
+ Exceptions.raise(ValidationException::new, "Illegally specified %d container element type(s) for %s",
+ elements.size(), host);
+ }
+ return Collections.emptyMap();
+ }
+
+ @SuppressWarnings("unchecked")
+ SELF withGetValid(Function<D, String> getValid) {
+ Validate.notNull(getValid);
+ this.isCascade = new Lazy<>(() -> getValid.apply(descriptor) != null);
+ return (SELF) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ SELF withGetGroupConversions(Function<D, List<GroupConversionType>> getGroupConversions) {
+ Validate.notNull(getGroupConversions);
+
+ this.getGroupConversions = new Lazy<>(() -> {
+ return getGroupConversions.apply(descriptor).stream().map(gc -> {
+ final String from = gc.getFrom();
+ final Class<?> source = from == null ? Default.class : resolveClass(from);
+ final Class<?> target = resolveClass(gc.getTo());
+ return GroupConversion.from(source).to(target);
+ }).collect(ToUnmodifiable.set());
+ });
+ return (SELF) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ SELF withGetContainerElementTypes(Function<D, List<ContainerElementTypeType>> getContainerElementTypes) {
+ Validate.notNull(getContainerElementTypes);
+ this.getContainerElementTypes = new Lazy<>(() -> getContainerElementTypes.apply(descriptor));
+ return (SELF) this;
+ }
+ }
+
+ private class ForContainerElementType
+ extends ForContainer<ForContainerElementType, AnnotatedType, ContainerElementTypeType> {
+
+ ForContainerElementType(ContainerElementTypeType descriptor) {
+ super(descriptor);
+ this.withGetConstraintTypes(ContainerElementTypeType::getConstraint)
+ .withGetValid(ContainerElementTypeType::getValid)
+ .withGetGroupConversions(ContainerElementTypeType::getConvertGroup)
+ .withGetContainerElementTypes(ContainerElementTypeType::getContainerElementType);
+ }
+ }
+
+ private class ForField extends XmlBuilder.ForContainer<ForField, Field, FieldType> {
+
+ ForField(FieldType descriptor) {
+ super(descriptor);
+ this.withGetIgnoreAnnotations(FieldType::getIgnoreAnnotations)
+ .withGetConstraintTypes(FieldType::getConstraint).withGetValid(FieldType::getValid)
+ .withGetGroupConversions(FieldType::getConvertGroup)
+ .withGetContainerElementTypes(FieldType::getContainerElementType);
+ }
+ }
+
+ private class ForGetter extends XmlBuilder.ForContainer<ForGetter, Method, GetterType> {
+
+ ForGetter(GetterType descriptor) {
+ super(descriptor);
+ this.withGetIgnoreAnnotations(GetterType::getIgnoreAnnotations)
+ .withGetConstraintTypes(GetterType::getConstraint).withGetValid(GetterType::getValid)
+ .withGetGroupConversions(GetterType::getConvertGroup)
+ .withGetContainerElementTypes(GetterType::getContainerElementType);
+ }
+ }
+
+ private abstract class ForExecutable<SELF extends ForExecutable<SELF, E, D>, E extends Executable, D>
+ extends NonRootLevel<SELF, D> implements MetadataBuilder.ForExecutable<E> {
+
+ Lazy<ReturnValueType> getReturnValue;
+ Lazy<CrossParameterType> getCrossParameter;
+ Lazy<List<ParameterType>> getParameters;
+
+ ForExecutable(D descriptor) {
+ super(descriptor);
+ }
+
+ @Override
+ public MetadataBuilder.ForElement<E> getCrossParameter(Meta<E> meta) {
+ final CrossParameterType cp = lazy(getCrossParameter, "getCrossParameter");
+ if (cp == null) {
+ return EmptyBuilder.instance().<E> forExecutable().getCrossParameter(meta);
+ }
+ return new XmlBuilder.ForCrossParameter<>(cp);
+ }
+
+ @Override
+ public MetadataBuilder.ForContainer<E> getReturnValue(Meta<E> meta) {
+ final ReturnValueType rv = lazy(getReturnValue, "getReturnValue");
+ if (rv == null) {
+ return EmptyBuilder.instance().<E> forExecutable().getReturnValue(meta);
+ }
+ return new XmlBuilder.ForReturnValue<>(rv);
+ }
+
+ @Override
+ public List<MetadataBuilder.ForContainer<Parameter>> getParameters(Meta<E> meta) {
+ return lazy(getParameters, "getParameters").stream().map(XmlBuilder.ForParameter::new)
+ .collect(Collectors.toList());
+ }
+
+ @SuppressWarnings("unchecked")
+ SELF withGetReturnValue(Function<D, ReturnValueType> getReturnValue) {
+ Validate.notNull(getReturnValue);
+ this.getReturnValue = new Lazy<>(() -> getReturnValue.apply(descriptor));
+ return (SELF) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ SELF withGetCrossParameter(Function<D, CrossParameterType> getCrossParameter) {
+ Validate.notNull(getCrossParameter);
+ this.getCrossParameter = new Lazy<>(() -> getCrossParameter.apply(descriptor));
+ return (SELF) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ SELF withGetParameters(Function<D, List<ParameterType>> getParameters) {
+ Validate.notNull(getParameters);
+ this.getParameters = new Lazy<>(() -> getParameters.apply(descriptor));
+ return (SELF) this;
+ }
+ }
+
+ private class ForConstructor<T> extends ForExecutable<ForConstructor<T>, Constructor<? extends T>, ConstructorType> {
+
+ ForConstructor(ConstructorType descriptor) {
+ super(descriptor);
+ this.withGetIgnoreAnnotations(ConstructorType::getIgnoreAnnotations)
+ .withGetReturnValue(ConstructorType::getReturnValue)
+ .withGetCrossParameter(ConstructorType::getCrossParameter)
+ .withGetParameters(ConstructorType::getParameter);
+ }
+ }
+
+ private class ForMethod extends ForExecutable<ForMethod, Method, MethodType> {
+
+ ForMethod(MethodType descriptor) {
+ super(descriptor);
+ this.withGetIgnoreAnnotations(MethodType::getIgnoreAnnotations)
+ .withGetReturnValue(MethodType::getReturnValue).withGetCrossParameter(MethodType::getCrossParameter)
+ .withGetParameters(MethodType::getParameter);
+ }
+ }
+
+ private class ForParameter extends ForContainer<ForParameter, Parameter, ParameterType> {
+
+ ForParameter(ParameterType descriptor) {
+ super(descriptor);
+ this.withGetIgnoreAnnotations(ParameterType::getIgnoreAnnotations)
+ .withGetConstraintTypes(ParameterType::getConstraint).withGetValid(ParameterType::getValid)
+ .withGetGroupConversions(ParameterType::getConvertGroup)
+ .withGetContainerElementTypes(ParameterType::getContainerElementType);
+ }
+ }
+
+ private class ForCrossParameter<E extends Executable>
+ extends ForElement<ForCrossParameter<E>, E, CrossParameterType> {
+
+ ForCrossParameter(CrossParameterType descriptor) {
+ super(descriptor);
+ this.withGetIgnoreAnnotations(CrossParameterType::getIgnoreAnnotations)
+ .withGetDeclaredConstraints(d -> d.getConstraint().stream()
+ .map(ct -> createConstraint(ct, ConstraintTarget.PARAMETERS)).toArray(Annotation[]::new));
+ }
+ }
+
+ private class ForReturnValue<E extends Executable> extends ForContainer<ForReturnValue<E>, E, ReturnValueType> {
+
+ ForReturnValue(ReturnValueType descriptor) {
+ super(descriptor);
+ this.withGetDeclaredConstraints(d -> d.getConstraint().stream()
+ .map(ct -> createConstraint(ct, ConstraintTarget.RETURN_VALUE)).toArray(Annotation[]::new))
+ .withGetIgnoreAnnotations(ReturnValueType::getIgnoreAnnotations).withGetValid(ReturnValueType::getValid)
+ .withGetGroupConversions(ReturnValueType::getConvertGroup)
+ .withGetContainerElementTypes(ReturnValueType::getContainerElementType);
+ }
+ }
+
+ private static final <T> T lazy(Lazy<T> lazy, String name) {
+ Validate.validState(lazy != null, "%s not set", name);
+ return lazy.get();
+ }
+
+ private final ConstraintMappingsType constraintMappings;
+ private final Version version;
+
+ public XmlBuilder(ConstraintMappingsType constraintMappings) {
+ super();
+ this.constraintMappings = constraintMappings;
+ Validate.notNull(constraintMappings, "constraintMappings");
+ this.version = Version.of(constraintMappings);
+ new MappingValidator(constraintMappings, this::resolveClass).validateMappings();
+ }
+
+ public Map<Class<?>, MetadataBuilder.ForBean<?>> forBeans() {
+ return constraintMappings.getBean().stream().map(XmlBuilder.ForBean::new)
+ .collect(ToUnmodifiable.map(XmlBuilder.ForBean::getBeanClass, Function.identity()));
+ }
+
+ public String getDefaultPackage() {
+ return constraintMappings.getDefaultPackage();
+ }
+
+ boolean atLeast(Version v) {
+ return version.compareTo(v) >= 0;
+ }
+
+ <T> Class<T> resolveClass(String className) {
+ return loadClass(toQualifiedClassName(className));
+ }
+
+ private String toQualifiedClassName(String className) {
+ if (isQualifiedClass(className)) {
+ return className;
+ }
+ if (className.startsWith("[L") && className.endsWith(";")) {
+ return "[L" + getDefaultPackage() + "." + className.substring(2);
+ }
+ return getDefaultPackage() + "." + className;
+ }
+
+ private boolean isQualifiedClass(String clazz) {
+ return clazz.indexOf('.') >= 0;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> Class<T> loadClass(final String fqn) {
+ ClassLoader loader = Reflection.getClassLoader(XmlBuilder.class);
+ if (loader == null) {
+ loader = getClass().getClassLoader();
+ }
+ try {
+ return (Class<T>) Class.forName(fqn, true, loader);
+ } catch (ClassNotFoundException ex) {
+ throw Exceptions.create(ValidationException::new, ex, "Unable to load class: %d", fqn);
+ }
+ }
+
+ private Class<?>[] loadClasses(Supplier<Stream<String>> classNames) {
+ return streamClasses(classNames).toArray(Class[]::new);
+ }
+
+ private Stream<Class<?>> streamClasses(Supplier<Stream<String>> classNames) {
+ return classNames.get().map(this::loadClass);
+ }
+
+ private <A extends Annotation, T> A createConstraint(final ConstraintType constraint) {
+ return createConstraint(constraint, ConstraintTarget.IMPLICIT);
+ }
+
+ private <A extends Annotation, T> A createConstraint(final ConstraintType constraint, ConstraintTarget target) {
+ final Class<A> annotationClass = this.<A> loadClass(toQualifiedClassName(constraint.getAnnotation()));
+ final AnnotationProxyBuilder<A> annoBuilder = new AnnotationProxyBuilder<A>(annotationClass);
+
+ if (constraint.getMessage() != null) {
+ annoBuilder.setMessage(constraint.getMessage());
+ }
+ annoBuilder.setGroups(getGroups(constraint.getGroups()));
+ annoBuilder.setPayload(getPayload(constraint.getPayload()));
+
+ if (ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO.analyze(annotationClass).isValid()) {
+ annoBuilder.setValidationAppliesTo(target);
+ }
+ for (final ElementType elementType : constraint.getElement()) {
+ final String name = elementType.getName();
+ final Class<?> returnType = getAnnotationParameterType(annotationClass, name);
+ final Object elementValue = getElementValue(elementType, returnType);
+ annoBuilder.setValue(name, elementValue);
+ }
+ return annoBuilder.createAnnotation();
+ }
+
+ private <A extends Annotation> Class<?> getAnnotationParameterType(final Class<A> annotationClass,
+ final String name) {
+ final Method m = Reflection.getPublicMethod(annotationClass, name);
+ Exceptions.raiseIf(m == null, ValidationException::new,
+ "Annotation of type %s does not contain a parameter %s.", annotationClass.getName(), name);
+ return m.getReturnType();
+ }
+
+ private Object getElementValue(ElementType elementType, Class<?> returnType) {
+ removeEmptyContentElements(elementType);
+
+ final List<Serializable> content = elementType.getContent();
+ final int sz = content.size();
+ if (returnType.isArray()) {
+ final Object result = Array.newInstance(returnType.getComponentType(), sz);
+ for (int i = 0; i < sz; i++) {
+ Array.set(result, i, getSingleValue(content.get(i), returnType.getComponentType()));
+ }
+ return result;
+ }
+ Exceptions.raiseIf(sz != 1, ValidationException::new,
+ "Attempt to specify an array where single value is expected.");
+
+ return getSingleValue(content.get(0), returnType);
+ }
+
+ private void removeEmptyContentElements(ElementType elementType) {
+ for (Iterator<Serializable> iter = elementType.getContent().iterator(); iter.hasNext();) {
+ final Serializable content = iter.next();
+ if (content instanceof String && ((String) content).matches("[\\n ].*")) {
+ iter.remove();
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private Object getSingleValue(Serializable serializable, Class<?> returnType) {
+ if (serializable instanceof String) {
+ return convertToResultType(returnType, (String) serializable);
+ }
+ if (serializable instanceof JAXBElement<?>) {
+ final JAXBElement<?> elem = (JAXBElement<?>) serializable;
+ if (String.class.equals(elem.getDeclaredType())) {
+ return convertToResultType(returnType, (String) elem.getValue());
+ }
+ if (AnnotationType.class.equals(elem.getDeclaredType())) {
+ AnnotationType annotationType = (AnnotationType) elem.getValue();
+ try {
+ return createAnnotation(annotationType, (Class<? extends Annotation>) returnType);
+ } catch (ClassCastException e) {
+ throw new ValidationException("Unexpected parameter value");
+ }
+ }
+ }
+ throw new ValidationException("Unexpected parameter value");
+ }
+
+ private Object convertToResultType(Class<?> returnType, String value) {
+ /**
+ * Class is represented by the fully qualified class name of the class. spec: Note that if the raw string is
+ * unqualified, default package is taken into account.
+ */
+ if (String.class.equals(returnType)) {
+ return value;
+ }
+ if (Class.class.equals(returnType)) {
+ return resolveClass(value);
+ }
+ if (returnType.isEnum()) {
+ try {
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ final Enum e = Enum.valueOf(returnType.asSubclass(Enum.class), value);
+ return e;
+ } catch (IllegalArgumentException e) {
+ throw new ConstraintDeclarationException(e);
+ }
+ }
+ try {
+ if (Byte.class.equals(returnType) || byte.class.equals(returnType)) {
+ // spec mandates it:
+ return Byte.parseByte(value);
+ }
+ if (Short.class.equals(returnType) || short.class.equals(returnType)) {
+ return Short.parseShort(value);
+ }
+ if (Integer.class.equals(returnType) || int.class.equals(returnType)) {
+ return Integer.parseInt(value);
+ }
+ if (Long.class.equals(returnType) || long.class.equals(returnType)) {
+ return Long.parseLong(value);
+ }
+ if (Float.class.equals(returnType) || float.class.equals(returnType)) {
+ return Float.parseFloat(value);
+ }
+ if (Double.class.equals(returnType) || double.class.equals(returnType)) {
+ return Double.parseDouble(value);
+ }
+ if (Boolean.class.equals(returnType) || boolean.class.equals(returnType)) {
+ return Boolean.parseBoolean(value);
+ }
+ } catch (Exception e) {
+ Exceptions.raise(ValidationException::new, e, "Unable to coerce value '%s' to %s", value, returnType);
+ }
+ if (Character.class.equals(returnType) || char.class.equals(returnType)) {
+ Exceptions.raiseIf(value.length() > 1, ConstraintDeclarationException::new,
+ "a char must have a length of 1");
+ return value.charAt(0);
+ }
+ return Exceptions.raise(ValidationException::new, "Unknown annotation value type %s", returnType.getName());
+ }
+
+ private <A extends Annotation> Annotation createAnnotation(AnnotationType annotationType, Class<A> returnType) {
+ final AnnotationProxyBuilder<A> metaAnnotation = new AnnotationProxyBuilder<>(returnType);
+ for (ElementType elementType : annotationType.getElement()) {
+ final String name = elementType.getName();
+ metaAnnotation.setValue(name, getElementValue(elementType, getAnnotationParameterType(returnType, name)));
+ }
+ return metaAnnotation.createAnnotation();
+ }
+
+ private Class<?>[] getGroups(GroupsType groupsType) {
+ if (groupsType == null) {
+ return ObjectUtils.EMPTY_CLASS_ARRAY;
+ }
+ return loadClasses(groupsType.getValue()::stream);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Class<? extends Payload>[] getPayload(PayloadType payloadType) {
+ if (payloadType == null) {
+ return (Class<? extends Payload>[]) ObjectUtils.EMPTY_CLASS_ARRAY;
+ }
+ return streamClasses(payloadType.getValue()::stream).peek(pc -> {
+ Exceptions.raiseUnless(Payload.class.isAssignableFrom(pc), ConstraintDeclarationException::new,
+ "Specified payload class %s does not implement %s", pc.getName(), Payload.class.getName());
+ }).<Class<? extends Payload>> map(pc -> pc.asSubclass(Payload.class)).toArray(Class[]::new);
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlValidationMappingProvider.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlValidationMappingProvider.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlValidationMappingProvider.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/metadata/XmlValidationMappingProvider.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,64 @@
+/*
+ * 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.metadata;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import javax.validation.ConstraintValidator;
+
+import org.apache.bval.jsr.xml.ValidatedByType;
+import org.apache.bval.util.Validate;
+
+public class XmlValidationMappingProvider extends ClassLoadingValidatorMappingProvider {
+ private static final Logger log = Logger.getLogger(XmlValidationMappingProvider.class.getName());
+
+ private final Map<Class<? extends Annotation>, ValidatedByType> config;
+ private final Function<String, String> classNameTransformer;
+
+ public XmlValidationMappingProvider(Map<Class<? extends Annotation>, ValidatedByType> validatorMappings,
+ Function<String, String> classNameTransformer) {
+ super();
+ this.config = Validate.notNull(validatorMappings, "validatorMappings");
+ this.classNameTransformer = Validate.notNull(classNameTransformer, "classNameTransformer");
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public <A extends Annotation> ValidatorMapping<A> doGetValidatorMapping(Class<A> constraintType) {
+ final ValidatedByType validatedByType = config.get(constraintType);
+ if (validatedByType == null) {
+ return null;
+ }
+ return new ValidatorMapping<>("XML descriptor",
+ load(validatedByType.getValue().stream().map(String::trim).map(classNameTransformer),
+ (Class<ConstraintValidator<A, ?>>) (Class) ConstraintValidator.class,
+ e -> log.log(Level.SEVERE, "exception loading XML-declared constraint validators", e))
+ .collect(Collectors.toList()),
+ toAnnotationBehavior(validatedByType));
+ }
+
+ private AnnotationBehavior toAnnotationBehavior(ValidatedByType validatedByType) {
+ final Boolean includeExistingValidators = validatedByType.getIncludeExistingValidators();
+ return includeExistingValidators == null ? AnnotationBehavior.ABSTAIN
+ : includeExistingValidators.booleanValue() ? AnnotationBehavior.INCLUDE : AnnotationBehavior.EXCLUDE;
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,46 @@
+/*
+ * 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.parameter;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.ParameterNameProvider;
+
+public class DefaultParameterNameProvider implements ParameterNameProvider {
+
+ private static List<String> parameterNames(Executable exe) {
+ return Stream.of(exe.getParameters()).map(Parameter::getName).collect(Collectors.toList());
+ }
+
+ @Override
+ public List<String> getParameterNames(Constructor<?> constructor) {
+ return parameterNames(constructor);
+ }
+
+ @Override
+ public List<String> getParameterNames(Method method) {
+ return parameterNames(method);
+ }
+}