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 [6/22] - in /tomee/deps/branches/bval-2: ./ bundle/
bundle/src/ bundle/src/main/ bundle/src/main/appended-resources/
bundle/src/main/appended-resources/META-INF/ bval-extras/ bval-extras/src/
bval-extras/src/main/ bval-extras/src/m...
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,122 @@
+/**
+ * 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;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Valid;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+
+import java.util.Set;
+
+/**
+ * Per the bean validation spec, {@link Valid} is not honored by the
+ * {@link #validateProperty(Object, String, Class...)} and
+ * {@link #validateValue(Class, String, Object, Class...)} methods. The
+ * {@link CascadingPropertyValidator} interface thus defines a {@link Validator} that
+ * provides corresponding methods that <em>may</em> honor {@link Valid}.
+ * It should be noted that {@link Validator#validateProperty(Object, String, Class...)}
+ * and {@link Validator#validateValue(Class, String, Object, Class...)} are assumed
+ * semantically equivalent to calling the {@link CascadingPropertyValidator}-defined
+ * methods with {@code cascade == false}.
+ *
+ * @version $Rev: 993539 $ $Date: 2010-09-07 16:27:50 -0500 (Tue, 07 Sep 2010) $
+ */
+public interface CascadingPropertyValidator extends Validator {
+
+ /**
+ * {@inheritDoc} Validates all constraints placed on the property of {@code object} named {@code propertyName}.
+ *
+ * @param object object to validate
+ * @param propertyName property to validate (i.e. field and getter constraints). Nested
+ * properties may be referenced (e.g. prop[2].subpropA.subpropB)
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code object} is {@code null}, if {@code propertyName null},
+ * empty or not a valid object property or if {@code null} is
+ * passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
+ */
+ @Override
+ default <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) {
+ return validateProperty(object, propertyName, false, groups);
+ }
+
+ /**
+ * Validates all constraints placed on the property of {@code object} named {@code propertyName}.
+ *
+ * @param object object to validate
+ * @param propertyName property to validate (i.e. field and getter constraints). Nested
+ * properties may be referenced (e.g. prop[2].subpropA.subpropB)
+ * @param cascade whether to cascade along {@link Valid} properties
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code object} is {@code null}, if {@code propertyName null},
+ * empty or not a valid object property or if {@code null} is
+ * passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
+ */
+ <T> Set<javax.validation.ConstraintViolation<T>> validateProperty(T object, String propertyName, boolean cascade,
+ Class<?>... groups);
+
+ /**
+ * {@inheritDoc} Validates all constraints placed on the property named {@code propertyName} of the class
+ * {@code beanType} would the property value be {@code value}.
+ * <p/>
+ * {@link ConstraintViolation} objects return {@code null} for {@link ConstraintViolation#getRootBean()} and
+ * {@link ConstraintViolation#getLeafBean()}.
+ *
+ * @param beanType the bean type
+ * @param propertyName property to validate
+ * @param value property value to validate
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code beanType} is {@code null}, if
+ * {@code propertyName null}, empty or not a valid object
+ * property or if {@code null} is passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
+ */
+ @Override
+ default <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
+ Class<?>... groups) {
+ return validateValue(beanType, propertyName, value, false, groups);
+ }
+
+ /**
+ * {@inheritDoc} Validates all constraints placed on the property named {@code propertyName} of the class
+ * {@code beanType} would the property value be {@code value}.
+ * <p/>
+ * {@link ConstraintViolation} objects return {@code null} for {@link ConstraintViolation#getRootBean()} and
+ * {@link ConstraintViolation#getLeafBean()}.
+ *
+ * @param beanType the bean type
+ * @param propertyName property to validate
+ * @param value property value to validate
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code beanType} is {@code null}, if
+ * {@code propertyName null}, empty or not a valid object
+ * property or if {@code null} is passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
+ */
+ <T> Set<javax.validation.ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
+ boolean cascade, Class<?>... groups);
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,494 @@
+/*
+ * 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;
+
+import java.io.Closeable;
+import java.io.InputStream;
+import java.time.Clock;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import javax.validation.BootstrapConfiguration;
+import javax.validation.ClockProvider;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.MessageInterpolator;
+import javax.validation.ParameterNameProvider;
+import javax.validation.TraversableResolver;
+import javax.validation.ValidationException;
+import javax.validation.ValidationProviderResolver;
+import javax.validation.ValidatorFactory;
+import javax.validation.spi.BootstrapState;
+import javax.validation.spi.ConfigurationState;
+import javax.validation.spi.ValidationProvider;
+import javax.validation.valueextraction.ValueExtractor;
+
+import org.apache.bval.jsr.parameter.DefaultParameterNameProvider;
+import org.apache.bval.jsr.resolver.DefaultTraversableResolver;
+import org.apache.bval.jsr.util.IOs;
+import org.apache.bval.jsr.valueextraction.ValueExtractors;
+import org.apache.bval.jsr.xml.ValidationParser;
+import org.apache.bval.util.CloseableAble;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Lazy;
+import org.apache.commons.weaver.privilizer.Privileged;
+
+/**
+ * Description: used to configure apache-validation for jsr.
+ * Implementation of Configuration that also implements ConfigurationState,
+ * hence this can be passed to buildValidatorFactory(ConfigurationState).
+ * <br/>
+ */
+public class ConfigurationImpl implements ApacheValidatorConfiguration, ConfigurationState, CloseableAble {
+
+ private class LazyParticipant<T> extends Lazy<T> {
+ private boolean locked;
+
+ private LazyParticipant(Supplier<T> init) {
+ super(init);
+ }
+
+ ConfigurationImpl override(T value) {
+ if (value != null) {
+ synchronized (this) {
+ if (!locked) {
+ try {
+ reset(() -> value);
+ } finally {
+ ConfigurationImpl.this.prepared = false;
+ }
+ }
+ }
+ }
+ return ConfigurationImpl.this;
+ }
+
+ synchronized ConfigurationImpl externalOverride(T value) {
+ locked = false;
+ try {
+ return override(value);
+ } finally {
+ locked = true;
+ }
+ }
+ }
+
+ /**
+ * Configured {@link ValidationProvider}
+ */
+ //couldn't this be parameterized <ApacheValidatorConfiguration> or <? super ApacheValidatorConfiguration>?
+ private final ValidationProvider<ApacheValidatorConfiguration> provider;
+
+ /**
+ * Configured {@link ValidationProviderResolver}
+ */
+ private final ValidationProviderResolver providerResolver;
+
+ /**
+ * Configured {@link ValidationProvider} class
+ */
+ private Class<? extends ValidationProvider<?>> providerClass;
+
+ private final MessageInterpolator defaultMessageInterpolator = new DefaultMessageInterpolator();
+
+ private final LazyParticipant<MessageInterpolator> messageInterpolator =
+ new LazyParticipant<>(this::getDefaultMessageInterpolator);
+
+ private final ConstraintValidatorFactory defaultConstraintValidatorFactory =
+ new DefaultConstraintValidatorFactory();
+
+ private final LazyParticipant<ConstraintValidatorFactory> constraintValidatorFactory =
+ new LazyParticipant<>(this::getDefaultConstraintValidatorFactory);
+
+ private final TraversableResolver defaultTraversableResolver = new DefaultTraversableResolver();
+
+ private final LazyParticipant<TraversableResolver> traversableResolver =
+ new LazyParticipant<>(this::getDefaultTraversableResolver);
+
+ private final ParameterNameProvider defaultParameterNameProvider = new DefaultParameterNameProvider();
+
+ private final LazyParticipant<ParameterNameProvider> parameterNameProvider =
+ new LazyParticipant<>(this::getDefaultParameterNameProvider);
+
+ private final ClockProvider defaultClockProvider = Clock::systemDefaultZone;
+
+ private final LazyParticipant<ClockProvider> clockProvider = new LazyParticipant<>(this::getDefaultClockProvider);
+
+ private final ValueExtractors bootstrapValueExtractors = ValueExtractors.EMPTY.createChild();
+ private final ValueExtractors valueExtractors = bootstrapValueExtractors.createChild();
+
+ private final Lazy<BootstrapConfiguration> bootstrapConfiguration = new Lazy<>(this::createBootstrapConfiguration);
+
+ private final Set<InputStream> mappingStreams = new HashSet<>();
+ private final Map<String, String> properties = new HashMap<>();
+
+ private boolean beforeCdi = false;
+ private ClassLoader loader;
+
+ // BEGIN DEFAULTS
+ /**
+ * false = dirty flag (to prevent from multiple parsing validation.xml)
+ */
+ private boolean prepared = false;
+ // END DEFAULTS
+
+ private boolean ignoreXmlConfiguration = false;
+
+ private ParticipantFactory participantFactory;
+
+ /**
+ * Create a new ConfigurationImpl instance.
+ * @param aState bootstrap state
+ * @param aProvider provider
+ */
+ public ConfigurationImpl(BootstrapState aState, ValidationProvider<ApacheValidatorConfiguration> aProvider) {
+ Exceptions.raiseIf(aProvider == null && aState == null, ValidationException::new,
+ "one of provider or state is required");
+
+ if (aProvider == null) {
+ this.provider = null;
+ if (aState.getValidationProviderResolver() == null) {
+ providerResolver = aState.getDefaultValidationProviderResolver();
+ } else {
+ providerResolver = aState.getValidationProviderResolver();
+ }
+ } else {
+ this.provider = aProvider;
+ this.providerResolver = null;
+ }
+ initializePropertyDefaults();
+ }
+
+ /**
+ * {@inheritDoc}
+ * Ignore data from the <i>META-INF/validation.xml</i> file if this
+ * method is called.
+ *
+ * @return this
+ */
+ @Override
+ public ApacheValidatorConfiguration ignoreXmlConfiguration() {
+ ignoreXmlConfiguration = true;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ConfigurationImpl messageInterpolator(MessageInterpolator resolver) {
+ return messageInterpolator.externalOverride(resolver);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ApacheValidatorConfiguration traversableResolver(TraversableResolver resolver) {
+ return traversableResolver.externalOverride(resolver);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ConfigurationImpl constraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
+ return this.constraintValidatorFactory.externalOverride(constraintValidatorFactory);
+ }
+
+ @Override
+ public ApacheValidatorConfiguration parameterNameProvider(ParameterNameProvider parameterNameProvider) {
+ return this.parameterNameProvider.externalOverride(parameterNameProvider);
+ }
+
+ @Override
+ public ApacheValidatorConfiguration clockProvider(ClockProvider clockProvider) {
+ return this.clockProvider.externalOverride(clockProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ * Add a stream describing constraint mapping in the Bean Validation
+ * XML format.
+ *
+ * @return this
+ */
+ @Override
+ public ApacheValidatorConfiguration addMapping(InputStream stream) {
+ if (stream != null) {
+ mappingStreams.add(IOs.convertToMarkableInputStream(stream));
+ }
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ * Add a provider specific property. This property is equivalent to
+ * XML configuration properties.
+ * If we do not know how to handle the property, we silently ignore it.
+ *
+ * @return this
+ */
+ @Override
+ public ApacheValidatorConfiguration addProperty(String name, String value) {
+ properties.put(name, value);
+ return this;
+ }
+
+ @Override
+ public MessageInterpolator getDefaultMessageInterpolator() {
+ return defaultMessageInterpolator;
+ }
+
+ @Override
+ public TraversableResolver getDefaultTraversableResolver() {
+ return defaultTraversableResolver;
+ }
+
+ @Override
+ public ConstraintValidatorFactory getDefaultConstraintValidatorFactory() {
+ return defaultConstraintValidatorFactory;
+ }
+
+ @Override
+ public ParameterNameProvider getDefaultParameterNameProvider() {
+ return defaultParameterNameProvider;
+ }
+
+ @Override
+ public ClockProvider getDefaultClockProvider() {
+ return defaultClockProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ * Return a map of non type-safe custom properties.
+ *
+ * @return null
+ */
+ @Override
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ * Returns true if Configuration.ignoreXMLConfiguration() has been called.
+ * In this case, we ignore META-INF/validation.xml
+ *
+ * @return true
+ */
+ @Override
+ public boolean isIgnoreXmlConfiguration() {
+ return ignoreXmlConfiguration;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<InputStream> getMappingStreams() {
+ return mappingStreams;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public MessageInterpolator getMessageInterpolator() {
+ return messageInterpolator.get();
+ }
+
+ @Override
+ public BootstrapConfiguration getBootstrapConfiguration() {
+ return bootstrapConfiguration.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ * main factory method to build a ValidatorFactory
+ *
+ * @throws ValidationException if the ValidatorFactory cannot be built
+ */
+ @Override
+ public ValidatorFactory buildValidatorFactory() {
+ return doBuildValidatorFactory();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @return the constraint validator factory of this configuration.
+ */
+ @Override
+ public ConstraintValidatorFactory getConstraintValidatorFactory() {
+ return constraintValidatorFactory.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public TraversableResolver getTraversableResolver() {
+ return traversableResolver.get();
+ }
+
+ @Override
+ public ParameterNameProvider getParameterNameProvider() {
+ return parameterNameProvider.get();
+ }
+
+ @Override
+ public ClockProvider getClockProvider() {
+ return clockProvider.get();
+ }
+
+ @Override
+ public ApacheValidatorConfiguration addValueExtractor(ValueExtractor<?> extractor) {
+ valueExtractors.add(extractor);
+ return this;
+ }
+
+ @Override
+ public Set<ValueExtractor<?>> getValueExtractors() {
+ return Collections.unmodifiableSet(new LinkedHashSet<>(valueExtractors.getValueExtractors().values()));
+ }
+
+ public void deferBootstrapOverrides() {
+ beforeCdi = true;
+ }
+
+ public void releaseDeferredBootstrapOverrides() {
+ if (beforeCdi) {
+ beforeCdi = false;
+ performBootstrapOverrides();
+ }
+ }
+
+ @Override
+ public Closeable getCloseable() {
+ if (participantFactory == null) {
+ return () -> {
+ };
+ }
+ return participantFactory;
+ }
+
+ @Privileged
+ private ValidatorFactory doBuildValidatorFactory() {
+ prepare();
+ return Optional.<ValidationProvider<?>> ofNullable(provider).orElseGet(this::findProvider)
+ .buildValidatorFactory(this);
+ }
+
+ private void prepare() {
+ if (!prepared) {
+ applyBootstrapConfiguration();
+ prepared = true;
+ }
+ }
+
+ private BootstrapConfiguration createBootstrapConfiguration() {
+ try {
+ if (!ignoreXmlConfiguration) {
+ loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = ValidationParser.class.getClassLoader();
+ }
+ final BootstrapConfiguration xmlBootstrap =
+ ValidationParser.processValidationConfig(getProperties().get(Properties.VALIDATION_XML_PATH), this);
+ if (xmlBootstrap != null) {
+ return xmlBootstrap;
+ }
+ }
+ loader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ loader = ApacheValidatorFactory.class.getClassLoader();
+ }
+ return BootstrapConfigurationImpl.DEFAULT;
+ } finally {
+ participantFactory = new ParticipantFactory(loader);
+ }
+ }
+
+ private void applyBootstrapConfiguration() {
+ final BootstrapConfiguration bootstrapConfig = bootstrapConfiguration.get();
+
+ if (bootstrapConfig.getDefaultProviderClassName() != null) {
+ this.providerClass = loadClass(bootstrapConfig.getDefaultProviderClassName());
+ }
+ bootstrapConfig.getProperties().forEach(this::addProperty);
+ bootstrapConfig.getConstraintMappingResourcePaths().stream().map(ValidationParser::open)
+ .forEach(this::addMapping);
+
+ if (!beforeCdi) {
+ performBootstrapOverrides();
+ }
+ }
+
+ private void performBootstrapOverrides() {
+ final BootstrapConfiguration bootstrapConfig = bootstrapConfiguration.get();
+ override(messageInterpolator, bootstrapConfig::getMessageInterpolatorClassName);
+ override(traversableResolver, bootstrapConfig::getTraversableResolverClassName);
+ override(constraintValidatorFactory, bootstrapConfig::getConstraintValidatorFactoryClassName);
+ override(parameterNameProvider, bootstrapConfig::getParameterNameProviderClassName);
+ override(clockProvider, bootstrapConfig::getClockProviderClassName);
+
+ bootstrapConfig.getValueExtractorClassNames().stream().<ValueExtractor<?>> map(participantFactory::create)
+ .forEach(bootstrapValueExtractors::add);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> Class<T> loadClass(final String className) {
+ try {
+ return (Class<T>) Class.forName(className, true, loader);
+ } catch (final ClassNotFoundException ex) {
+ throw new ValidationException(ex);
+ }
+ }
+
+ private void initializePropertyDefaults() {
+ properties.put(Properties.CONSTRAINTS_CACHE_SIZE, Integer.toString(50));
+ }
+
+ private ValidationProvider<?> findProvider() {
+ if (providerClass == null) {
+ return providerResolver.getValidationProviders().get(0);
+ }
+ final Optional<ValidationProvider<?>> knownProvider =
+ providerResolver.getValidationProviders().stream().filter(providerClass::isInstance).findFirst();
+ if (knownProvider.isPresent()) {
+ return knownProvider.get();
+ }
+ try {
+ return providerClass.getConstructor().newInstance();
+ } catch (Exception e) {
+ throw Exceptions.create(ValidationException::new, "Unable to find/create %s of type %s",
+ ValidationProvider.class.getSimpleName(), providerClass);
+ }
+ }
+
+ private <T> void override(LazyParticipant<T> participant, Supplier<String> getClassName) {
+ Optional.ofNullable(getClassName.get()).<T> map(participantFactory::create).ifPresent(participant::override);
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,242 @@
+/**
+ * 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;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Predicate;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintTarget;
+import javax.validation.Payload;
+
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.ObjectUtils;
+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;
+
+/**
+ * Defines the well-known attributes of {@link Constraint} annotations.
+ *
+ * @version $Rev: 1165923 $ $Date: 2011-09-06 18:07:53 -0500 (Tue, 06 Sep 2011) $
+ */
+@Privilizing(@CallTo(Reflection.class))
+public enum ConstraintAnnotationAttributes {
+ /**
+ * "message"
+ */
+ MESSAGE("message", m -> true),
+
+ /**
+ * "groups"
+ */
+ GROUPS("groups", ObjectUtils::isEmptyArray),
+
+ /**
+ * "payload"
+ */
+ PAYLOAD("payload", ObjectUtils::isEmptyArray),
+
+ /**
+ * "validationAppliesTo"
+ */
+ VALIDATION_APPLIES_TO("validationAppliesTo", Predicate.isEqual(ConstraintTarget.IMPLICIT)),
+
+ /**
+ * "value" for multi-valued constraints
+ */
+ VALUE("value", ObjectUtils::isEmptyArray);
+
+ @SuppressWarnings("unused")
+ private static class Types {
+ String message;
+ Class<?>[] groups;
+ Class<? extends Payload>[] payload;
+ Annotation[] value;
+ ConstraintTarget validationAppliesTo;
+ }
+
+ private static final Set<ConstraintAnnotationAttributes> MANDATORY =
+ Collections.unmodifiableSet(EnumSet.of(ConstraintAnnotationAttributes.MESSAGE,
+ ConstraintAnnotationAttributes.GROUPS, ConstraintAnnotationAttributes.PAYLOAD));
+
+ private final Class<?> type;
+ private final String attributeName;
+ private final Predicate<Object> validateDefaultValue;
+
+ private ConstraintAnnotationAttributes(final String name, Predicate<Object> validateDefaultValue) {
+ this.attributeName = name;
+ try {
+ this.type = Types.class.getDeclaredField(getAttributeName()).getType();
+ } catch (Exception e) {
+ // should never happen
+ throw new RuntimeException(e);
+ }
+ this.validateDefaultValue = Validate.notNull(validateDefaultValue, "validateDefaultValue");
+ }
+
+ /**
+ * Get the expected type of the represented attribute.
+ */
+ public Class<?> getType() {
+ return type;
+ }
+
+ /**
+ * Get the attribute name represented.
+ *
+ * @return String
+ */
+ public String getAttributeName() {
+ return attributeName;
+ }
+
+ @Override
+ public String toString() {
+ return attributeName;
+ }
+
+ /**
+ * Put <code>value</code> into a map with <code>this.attributeName</code> as
+ * key.
+ *
+ * @param <V>
+ * @param map
+ * @param value
+ * @return previous value mapped to <code>this.attributeName</code>
+ */
+ public <V> Object put(Map<? super String, ? super V> map, V value) {
+ return map.put(getAttributeName(), value);
+ }
+
+ /**
+ * Get the value of <code>this.attributeName</code> from <code>map</code>.
+ *
+ * @param <V>
+ * @param map
+ * @return V if you say so
+ */
+ public <V> V get(Map<? super String, ? super V> map) {
+ @SuppressWarnings("unchecked")
+ final V result = (V) map.get(getAttributeName());
+ if (!TypeUtils.isInstance(result, getType())) {
+ Exceptions.raise(IllegalStateException::new, "Invalid '%s' value: %s", getAttributeName(), result);
+ }
+ return result;
+ }
+
+ public <C extends Annotation> Worker<C> analyze(final Class<C> clazz) {
+ if (clazz.getName().startsWith("javax.validation.constraint.")) { // cache only APIs classes to avoid memory leaks
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ final Worker<C> w = (Worker<C>) WORKER_CACHE.computeIfAbsent(clazz, c -> new Worker((c)));
+ return w;
+ }
+ return new Worker<C>(clazz);
+ }
+
+ public boolean isMandatory() {
+ return MANDATORY.contains(this);
+ }
+
+ public boolean isValidDefaultValue(Object o) {
+ return validateDefaultValue.test(o);
+ }
+
+ // this is static but related to Worker
+ private static final ConcurrentMap<Class<?>, Worker<?>> WORKER_CACHE = new ConcurrentHashMap<>();
+ private static final ConcurrentMap<Class<?>, ConcurrentMap<String, Method>> METHOD_BY_NAME_AND_CLASS =
+ new ConcurrentHashMap<>();
+ private static final Method NULL_METHOD;
+ static {
+ try {
+ NULL_METHOD = Object.class.getMethod("hashCode"); // whatever, the only constraint here is to not use a constraint method, this value is used to cache null
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Impossible normally");
+ }
+ }
+
+ @Privilizing(@CallTo(Reflection.class))
+ public class Worker<C extends Annotation> {
+
+ public final Method method;
+
+ /**
+ * Create a new Worker instance.
+ * @param constraintType to handle
+ */
+ Worker(final Class<C> constraintType) {
+ method = findMethod(constraintType, attributeName);
+ }
+
+ private Method findMethod(final Class<C> constraintType, final String attributeName) {
+ ConcurrentMap<String, Method> cache =
+ METHOD_BY_NAME_AND_CLASS.computeIfAbsent(constraintType, t -> new ConcurrentHashMap<>());
+
+ final Method found = cache.get(attributeName);
+ if (found != null) {
+ return found;
+ }
+ final Method m = Reflection.getPublicMethod(constraintType, attributeName);
+ if (m == null) {
+ cache.putIfAbsent(attributeName, NULL_METHOD);
+ return null;
+ }
+ return cache.computeIfAbsent(attributeName, s -> m);
+ }
+
+ public boolean isValid() {
+ return method != null && method != NULL_METHOD && TypeUtils.isAssignable(method.getReturnType(), type);
+ }
+
+ /**
+ * @since 2.0
+ * @return {@link Type}
+ */
+ public Type getSpecificType() {
+ return isValid() ? method.getGenericReturnType() : type;
+ }
+
+ public <T> T read(final Annotation constraint) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) doInvoke(constraint);
+ return result;
+ }
+
+ private Object doInvoke(final Annotation constraint) {
+ final boolean unset = Reflection.setAccessible(method, true);
+ try {
+ return method.invoke(constraint);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (unset) {
+ Reflection.setAccessible(method, false);
+ }
+ }
+ }
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,144 @@
+/*
+ * 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;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.validation.ConstraintDefinitionException;
+import javax.validation.ConstraintValidator;
+import javax.validation.constraintvalidation.SupportedValidationTarget;
+import javax.validation.constraintvalidation.ValidationTarget;
+
+import org.apache.bval.jsr.metadata.AnnotationDeclaredValidatorMappingProvider;
+import org.apache.bval.jsr.metadata.CompositeValidatorMappingProvider;
+import org.apache.bval.jsr.metadata.DualValidationMappingProvider;
+import org.apache.bval.jsr.metadata.ValidatorMappingProvider;
+import org.apache.bval.jsr.util.ToUnmodifiable;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.Validate;
+
+/**
+ * Description: hold the relationship annotation->validatedBy[]
+ * ConstraintValidator classes that are already parsed in a cache.<br/>
+ */
+public class ConstraintCached {
+
+ /**
+ * Describes a {@link ConstraintValidator} implementation type.
+ *
+ * @since 2.0
+ */
+ public static final class ConstraintValidatorInfo<T extends Annotation> {
+ private static final Set<ValidationTarget> DEFAULT_VALIDATION_TARGETS =
+ Collections.singleton(ValidationTarget.ANNOTATED_ELEMENT);
+
+ private final Class<? extends ConstraintValidator<T, ?>> type;
+ private Set<ValidationTarget> supportedTargets;
+
+ ConstraintValidatorInfo(Class<? extends ConstraintValidator<T, ?>> type) {
+ super();
+ this.type = Validate.notNull(type);
+ final SupportedValidationTarget svt = type.getAnnotation(SupportedValidationTarget.class);
+
+ supportedTargets = svt == null ? DEFAULT_VALIDATION_TARGETS
+ : Collections.unmodifiableSet(EnumSet.copyOf(Arrays.asList(svt.value())));
+
+ if (supportedTargets.isEmpty()) {
+ Exceptions.raise(ConstraintDefinitionException::new, "Illegally specified 0-length %s value on %s",
+ SupportedValidationTarget.class.getSimpleName(), type);
+ }
+ }
+
+ public Class<? extends ConstraintValidator<T, ?>> getType() {
+ return type;
+ }
+
+ public Set<ValidationTarget> getSupportedTargets() {
+ return supportedTargets;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this
+ || obj instanceof ConstraintValidatorInfo<?> && ((ConstraintValidatorInfo<?>) obj).type.equals(type);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type);
+ }
+ }
+
+ private final Map<Class<? extends Annotation>, Set<ConstraintValidatorInfo<?>>> constraintValidatorInfo =
+ new HashMap<>();
+
+ private final List<ValidatorMappingProvider> customValidatorMappingProviders = new ArrayList<>();
+ private final Lazy<ValidatorMappingProvider> validatorMappingProvider =
+ new Lazy<>(this::createValidatorMappingProvider);
+
+ public void add(ValidatorMappingProvider validatorMappingProvider) {
+ customValidatorMappingProviders.add(validatorMappingProvider);
+ this.validatorMappingProvider.reset(this::createValidatorMappingProvider);
+ }
+
+ public <A extends Annotation> List<Class<? extends ConstraintValidator<A, ?>>> getConstraintValidatorClasses(
+ Class<A> constraintType) {
+ final Set<ConstraintValidatorInfo<A>> infos = infos(constraintType);
+ return infos == null ? Collections.emptyList()
+ : infos.stream().map(ConstraintValidatorInfo::getType).collect(ToUnmodifiable.list());
+ }
+
+ public <A extends Annotation> Set<ConstraintValidatorInfo<A>> getConstraintValidatorInfo(Class<A> constraintType) {
+ return Collections.unmodifiableSet(infos(constraintType));
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private <A extends Annotation> Set<ConstraintValidatorInfo<A>> infos(Class<A> constraintType) {
+ return (Set) constraintValidatorInfo.computeIfAbsent(constraintType,
+ c -> validatorMappingProvider.get().getValidatorMapping(c).getValidatorTypes().stream()
+ .map(ConstraintValidatorInfo::new).collect(Collectors.toSet()));
+ }
+
+ private ValidatorMappingProvider createValidatorMappingProvider() {
+ final ValidatorMappingProvider configured;
+ if (customValidatorMappingProviders.isEmpty()) {
+ configured = AnnotationDeclaredValidatorMappingProvider.INSTANCE;
+ } else {
+ final ValidatorMappingProvider custom;
+ if (customValidatorMappingProviders.size() == 1) {
+ custom = customValidatorMappingProviders.get(0);
+ } else {
+ custom = new CompositeValidatorMappingProvider(customValidatorMappingProviders);
+ }
+ configured = new DualValidationMappingProvider(AnnotationDeclaredValidatorMappingProvider.INSTANCE, custom);
+ }
+ return new DualValidationMappingProvider(ConstraintDefaults.INSTANCE, configured);
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,90 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.ConstraintValidator;
+
+import org.apache.bval.jsr.metadata.ClassLoadingValidatorMappingProvider;
+import org.apache.bval.jsr.metadata.ValidatorMapping;
+import org.apache.bval.util.StringUtils;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+/**
+ * Description: Provides access to the default constraints/validator
+ * implementation classes built into the framework. These are configured in
+ * DefaultConstraints.properties.<br/>
+ */
+@Privilizing(@CallTo(Reflection.class))
+public class ConstraintDefaults extends ClassLoadingValidatorMappingProvider {
+ public static final ConstraintDefaults INSTANCE = new ConstraintDefaults();
+
+ private static final Logger log = Logger.getLogger(ConstraintDefaults.class.getName());
+ private static final String DEFAULT_CONSTRAINTS = "org/apache/bval/jsr/DefaultConstraints.properties";
+
+ private final Properties properties;
+
+ /**
+ * Create a new ConstraintDefaults instance.
+ */
+ private ConstraintDefaults() {
+ this.properties = loadProperties(DEFAULT_CONSTRAINTS);
+ }
+
+ private Properties loadProperties(String resource) {
+ final Properties result = new Properties();
+ final ClassLoader classloader = getClassLoader();
+ try (final InputStream stream = classloader.getResourceAsStream(resource)) {
+ if (stream == null) {
+ log.log(Level.WARNING, String.format("Cannot find %s", resource));
+ } else {
+ result.load(stream);
+ }
+ } catch (IOException e) {
+ log.log(Level.SEVERE, String.format("Cannot load %s", resource), e);
+ }
+ return result;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public <A extends Annotation> ValidatorMapping<A> doGetValidatorMapping(Class<A> constraintType) {
+
+ final String validators = properties.getProperty(constraintType.getName());
+
+ if (StringUtils.isBlank(validators)) {
+ return null;
+ }
+ return new ValidatorMapping<>("built-in",
+ load(Stream.of(StringUtils.split(validators, ',')).map(String::trim),
+ (Class<ConstraintValidator<A, ?>>) (Class) ConstraintValidator.class,
+ e -> log.log(Level.SEVERE, "exception loading default constraint validators", e))
+ .collect(Collectors.toList()));
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.bval.jsr;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Path;
+import javax.validation.ValidationException;
+import javax.validation.metadata.ConstraintDescriptor;
+
+import org.apache.bval.util.Exceptions;
+
+import java.io.Serializable;
+import java.lang.annotation.ElementType;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Description: Describe a constraint validation defect.<br/>
+ * From rootBean and propertyPath, it is possible to rebuild the context of the
+ * failure
+ */
+public class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable {
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ private final String messageTemplate;
+ private final String message;
+ /** root bean validation was invoked on. */
+ private final T rootBean;
+ private final Class<T> rootBeanClass;
+ /** last bean validated. */
+ private final Object leafBean;
+ private final Object value;
+ private final Path propertyPath;
+ private final ElementType elementType;
+ private final ConstraintDescriptor<?> constraintDescriptor;
+ private final Object returnValue;
+ private final Object[] parameters;
+ private final int hashCode;
+
+ /**
+ * Create a new ConstraintViolationImpl instance.
+ *
+ * @param messageTemplate
+ * - message reason (raw message)
+ * @param message
+ * - interpolated message (locale specific)
+ * @param rootBean
+ * @param leafBean
+ * @param propertyPath
+ * @param value
+ * @param constraintDescriptor
+ * @param rootBeanClass
+ * @param elementType
+ * @param returnValue
+ * @param parameters
+ */
+ public ConstraintViolationImpl(String messageTemplate, String message, T rootBean, Object leafBean,
+ Path propertyPath, Object value, ConstraintDescriptor<?> constraintDescriptor, Class<T> rootBeanClass,
+ ElementType elementType, Object returnValue, Object[] parameters) {
+ this.messageTemplate = messageTemplate;
+ this.message = message;
+ this.rootBean = rootBean;
+ this.rootBeanClass = rootBeanClass;
+ this.propertyPath = propertyPath;
+ this.leafBean = leafBean;
+ this.value = value;
+ this.constraintDescriptor = constraintDescriptor;
+ this.elementType = elementType;
+ this.returnValue = returnValue;
+ this.parameters = parameters;
+ this.hashCode = Arrays.deepHashCode(new Object[] { messageTemplate, message, rootBean, rootBeanClass, leafBean,
+ value, propertyPath, elementType, constraintDescriptor, returnValue, parameters });
+ }
+
+ /**
+ * {@inheritDoc} former name getInterpolatedMessage()
+ *
+ * @return The interpolated error message for this constraint violation.
+ */
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getMessageTemplate() {
+ return messageTemplate;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return Root bean being validated
+ */
+ @Override
+ public T getRootBean() {
+ return rootBean;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class<T> getRootBeanClass() {
+ return rootBeanClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getLeafBean() {
+ return leafBean;
+ }
+
+ @Override
+ public Object[] getExecutableParameters() {
+ return parameters;
+ }
+
+ @Override
+ public Object getExecutableReturnValue() {
+ return returnValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return The value failing to pass the constraint
+ */
+ @Override
+ public Object getInvalidValue() {
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return the property path to the value from <code>rootBean</code> Null if
+ * the value is the rootBean itself
+ */
+ @Override
+ public Path getPropertyPath() {
+ return propertyPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ConstraintDescriptor<?> getConstraintDescriptor() {
+ return constraintDescriptor;
+ }
+
+ @Override
+ public <U> U unwrap(Class<U> type) {
+ if (!type.isInstance(this)) {
+ Exceptions.raise(ValidationException::new, "Type %s is not supported", type);
+ }
+ return type.cast(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return String.format("%s{rootBean=%s, propertyPath='%s', message='%s', leafBean=%s, value=%s}",
+ ConstraintViolationImpl.class.getSimpleName(), rootBean, propertyPath, message, leafBean, value);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || !getClass().equals(o.getClass())) {
+ return false;
+ }
+
+ @SuppressWarnings("rawtypes")
+ final ConstraintViolationImpl that = (ConstraintViolationImpl) o;
+
+ return Objects.equals(constraintDescriptor, that.constraintDescriptor) && elementType == that.elementType
+ && Objects.equals(leafBean, that.leafBean) && Objects.equals(message, that.message)
+ && Objects.equals(messageTemplate, that.messageTemplate) && Arrays.equals(parameters, that.parameters)
+ && Objects.equals(propertyPath, that.propertyPath) && Objects.equals(returnValue, that.returnValue)
+ && Objects.equals(rootBean, that.rootBean) && Objects.equals(rootBeanClass, that.rootBeanClass)
+ && Objects.equals(value, that.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+import org.apache.bval.cdi.BValExtension;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.ValidationException;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Description: create constraint instances with the default / no-arg constructor <br/>
+ */
+public class DefaultConstraintValidatorFactory implements ConstraintValidatorFactory, Closeable {
+ private final Collection<BValExtension.Releasable<?>> releasables = new CopyOnWriteArrayList<>();
+ private volatile Boolean useCdi = null; // store it to avoid NoClassDefFoundError when cdi is not present (it is slow) + lazily (to wait cdi is started)
+
+ /**
+ * Instantiate a Constraint.
+ *
+ * @return Returns a new Constraint instance
+ * The ConstraintFactory is <b>not</b> responsible for calling Constraint#initialize
+ */
+ @Override
+ public <T extends ConstraintValidator<?, ?>> T getInstance(final Class<T> constraintClass) {
+ if (useCdi == null) {
+ synchronized (this) {
+ if (useCdi == null) {
+ try {
+ useCdi = BValExtension.getBeanManager() != null;
+ } catch (NoClassDefFoundError | Exception error) {
+ useCdi = Boolean.FALSE;
+ }
+ }
+ }
+ }
+
+ // 2011-03-27 jw: Do not use PrivilegedAction.
+ // Otherwise any user code would be executed with the privileges of this class.
+ try {
+ if (useCdi) {
+ try {
+ final BValExtension.Releasable<T> instance = BValExtension.inject(constraintClass);
+ if (instance != null) {
+ releasables.add(instance);
+ return instance.getInstance();
+ }
+ throw new IllegalStateException("Can't create " + constraintClass.getName());
+ } catch (Exception | NoClassDefFoundError e) {
+ }
+ }
+ return constraintClass.getConstructor().newInstance();
+ } catch (final Exception ex) {
+ throw new ValidationException("Cannot instantiate : " + constraintClass, ex);
+ }
+ }
+
+ @Override
+ public void releaseInstance(final ConstraintValidator<?, ?> instance) {
+ // no-op
+ }
+
+ @Override
+ public void close() throws IOException {
+ for (final BValExtension.Releasable<?> releasable : releasables) {
+ // ensure to call this callback
+ releaseInstance(ConstraintValidator.class.cast(releasable.getInstance()));
+ releasable.release();
+ }
+ releasables.clear();
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,300 @@
+/*
+ * 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;
+
+import org.apache.bval.el.MessageEvaluator;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+
+import javax.validation.MessageInterpolator;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Description: Resource bundle backed message interpolator.
+ * This message resolver resolve message descriptors
+ * into human-readable messages. It uses ResourceBundles to find the messages.
+ * This class is threadsafe.<br/>
+ */
+@Privilizing(@CallTo(Reflection.class))
+public class DefaultMessageInterpolator implements MessageInterpolator {
+ private static final Logger log = Logger.getLogger(DefaultMessageInterpolator.class.getName());
+ private static final boolean LOG_FINEST = log.isLoggable(Level.FINEST);
+ private static final String DEFAULT_VALIDATION_MESSAGES = "org.apache.bval.jsr.ValidationMessages";
+ private static final String USER_VALIDATION_MESSAGES = "ValidationMessages";
+
+ /** Regular expression used to do message interpolation. */
+ private static final Pattern messageParameterPattern = Pattern.compile("(\\{[\\w\\.]+\\})");
+
+ /** The default locale for the current user. */
+ private Locale defaultLocale;
+
+ /** User specified resource bundles hashed against their locale. */
+ private final Map<Locale, ResourceBundle> userBundlesMap = new ConcurrentHashMap<>();
+
+ /** Builtin resource bundles hashed against their locale. */
+ private final Map<Locale, ResourceBundle> defaultBundlesMap = new ConcurrentHashMap<>();
+
+ private final MessageEvaluator evaluator;
+
+ /**
+ * Create a new DefaultMessageInterpolator instance.
+ */
+ public DefaultMessageInterpolator() {
+ this(null);
+ }
+
+ /**
+ * Create a new DefaultMessageInterpolator instance.
+ * @param resourceBundle
+ */
+ public DefaultMessageInterpolator(ResourceBundle resourceBundle) {
+ defaultLocale = Locale.getDefault();
+
+ // feed the cache with defaults at least
+ findDefaultResourceBundle(defaultLocale);
+ if (resourceBundle == null) {
+ findUserResourceBundle(defaultLocale);
+ } else {
+ userBundlesMap.put(defaultLocale, resourceBundle);
+ }
+
+ MessageEvaluator ev;
+ try {
+ ev = MessageEvaluator.class
+ .cast(getClass().getClassLoader().loadClass("org.apache.bval.el.ELFacade")
+ .getConstructor().newInstance());
+ } catch (final Throwable e) { // can be exception or error
+ ev = null;
+ }
+ evaluator = ev;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String interpolate(String message, Context context) {
+ // probably no need for caching, but it could be done by parameters since the map
+ // is immutable and uniquely built per Validation definition, the comparison has to be based on == and not equals though
+ return interpolate(message, context, defaultLocale);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String interpolate(String message, Context context, Locale locale) {
+ return interpolateMessage(message, context.getConstraintDescriptor().getAttributes(), locale,
+ context.getValidatedValue());
+ }
+
+ /**
+ * Runs the message interpolation according to algorithm specified in JSR 303.
+ * <br/>
+ * Note:
+ * <br/>
+ * Lookups in user bundles are recursive whereas lookups in default bundle are not!
+ *
+ * @param message the message to interpolate
+ * @param annotationParameters the parameters of the annotation for which to interpolate this message
+ * @param locale the <code>Locale</code> to use for the resource bundle.
+ * @return the interpolated message.
+ */
+ private String interpolateMessage(String message, Map<String, Object> annotationParameters, Locale locale,
+ Object validatedValue) {
+ ResourceBundle userResourceBundle = findUserResourceBundle(locale);
+ ResourceBundle defaultResourceBundle = findDefaultResourceBundle(locale);
+
+ String userBundleResolvedMessage;
+ String resolvedMessage = message;
+ boolean evaluatedDefaultBundleOnce = false;
+ do {
+ // search the user bundle recursive (step1)
+ userBundleResolvedMessage = replaceVariables(resolvedMessage, userResourceBundle, locale, true);
+
+ // exit condition - we have at least tried to validate against the default bundle and there were no
+ // further replacements
+ if (evaluatedDefaultBundleOnce && !hasReplacementTakenPlace(userBundleResolvedMessage, resolvedMessage)) {
+ break;
+ }
+
+ // search the default bundle non recursive (step2)
+ resolvedMessage = replaceVariables(userBundleResolvedMessage, defaultResourceBundle, locale, false);
+
+ evaluatedDefaultBundleOnce = true;
+ } while (true);
+
+ // resolve annotation attributes (step 4)
+ resolvedMessage = replaceAnnotationAttributes(resolvedMessage, annotationParameters);
+
+ // EL handling
+ if (evaluator != null) {
+ resolvedMessage = evaluator.interpolate(resolvedMessage, annotationParameters, validatedValue);
+ }
+
+ // curly braces need to be scaped in the original msg, so unescape them now
+ resolvedMessage =
+ resolvedMessage.replace("\\{", "{").replace("\\}", "}").replace("\\\\", "\\").replace("\\$", "$");
+
+ return resolvedMessage;
+ }
+
+ private boolean hasReplacementTakenPlace(String origMessage, String newMessage) {
+ return !origMessage.equals(newMessage);
+ }
+
+ /**
+ * Search current thread classloader for the resource bundle. If not found, search validator (this) classloader.
+ *
+ * @param locale The locale of the bundle to load.
+ * @return the resource bundle or <code>null</code> if none is found.
+ */
+ private ResourceBundle getFileBasedResourceBundle(Locale locale) {
+ ResourceBundle rb;
+ final ClassLoader classLoader = Reflection.getClassLoader(DefaultMessageInterpolator.class);
+ if (classLoader != null) {
+ rb = loadBundle(classLoader, locale, USER_VALIDATION_MESSAGES + " not found by thread local classloader");
+ } else {
+ // 2011-03-27 jw: No privileged action required.
+ // A class can always access the classloader of itself and of subclasses.
+ rb = loadBundle(getClass().getClassLoader(), locale,
+ USER_VALIDATION_MESSAGES + " not found by validator classloader");
+ }
+ if (LOG_FINEST) {
+ if (rb == null) {
+ log.log(Level.FINEST, String.format("%s not found. Delegating to %s", USER_VALIDATION_MESSAGES,
+ DEFAULT_VALIDATION_MESSAGES));
+ } else {
+ log.log(Level.FINEST, String.format("%s found", USER_VALIDATION_MESSAGES));
+ }
+ }
+ return rb;
+ }
+
+ private ResourceBundle loadBundle(ClassLoader classLoader, Locale locale, String message) {
+ try {
+ return ResourceBundle.getBundle(USER_VALIDATION_MESSAGES, locale, classLoader);
+ } catch (final MissingResourceException e) {
+ log.fine(message);
+ }
+ return null;
+ }
+
+ private String replaceVariables(String message, ResourceBundle bundle, Locale locale, boolean recurse) {
+ final Matcher matcher = messageParameterPattern.matcher(message);
+ final StringBuffer sb = new StringBuffer(64);
+ while (matcher.find()) {
+ final String parameter = matcher.group(1);
+ String resolvedParameterValue = resolveParameter(parameter, bundle, locale, recurse);
+ matcher.appendReplacement(sb, sanitizeForAppendReplacement(resolvedParameterValue));
+ }
+ matcher.appendTail(sb);
+ return sb.toString();
+ }
+
+ private String replaceAnnotationAttributes(final String message, final Map<String, Object> annotationParameters) {
+ Matcher matcher = messageParameterPattern.matcher(message);
+ StringBuffer sb = new StringBuffer(64);
+ while (matcher.find()) {
+ String resolvedParameterValue;
+ String parameter = matcher.group(1);
+ Object variable = annotationParameters.get(removeCurlyBrace(parameter));
+ if (variable != null) {
+ if (variable.getClass().isArray()) {
+ resolvedParameterValue = Arrays.toString((Object[]) variable);
+ } else {
+ resolvedParameterValue = variable.toString();
+ }
+ } else {
+ resolvedParameterValue = parameter;
+ }
+ matcher.appendReplacement(sb, sanitizeForAppendReplacement(resolvedParameterValue));
+ }
+ matcher.appendTail(sb);
+ return sb.toString();
+ }
+
+ private String resolveParameter(String parameterName, ResourceBundle bundle, Locale locale, boolean recurse) {
+ String parameterValue;
+ try {
+ if (bundle == null) {
+ parameterValue = parameterName;
+ } else {
+ parameterValue = bundle.getString(removeCurlyBrace(parameterName));
+ if (recurse) {
+ parameterValue = replaceVariables(parameterValue, bundle, locale, recurse);
+ }
+ }
+ } catch (final MissingResourceException e) {
+ // return parameter itself
+ parameterValue = parameterName;
+ }
+
+ return parameterValue;
+ }
+
+ private String removeCurlyBrace(String parameter) {
+ return parameter.substring(1, parameter.length() - 1);
+ }
+
+ private ResourceBundle findDefaultResourceBundle(Locale locale) {
+ ResourceBundle bundle = defaultBundlesMap.get(locale);
+ if (bundle == null) {
+ bundle = ResourceBundle.getBundle(DEFAULT_VALIDATION_MESSAGES, locale);
+ defaultBundlesMap.put(locale, bundle);
+ }
+ return bundle;
+ }
+
+ private ResourceBundle findUserResourceBundle(Locale locale) {
+ ResourceBundle bundle = userBundlesMap.get(locale);
+ if (bundle == null) {
+ bundle = getFileBasedResourceBundle(locale);
+ if (bundle != null) {
+ userBundlesMap.put(locale, bundle);
+ }
+ }
+ return bundle;
+ }
+
+ /**
+ * Set the default locale used by this {@link DefaultMessageInterpolator}.
+ * @param locale
+ */
+ public void setLocale(Locale locale) {
+ defaultLocale = locale;
+ }
+
+ /**
+ * Escapes the string to comply with
+ * {@link Matcher#appendReplacement(StringBuffer, String)} requirements.
+ *
+ * @param src
+ * The original string.
+ * @return The sanitized string.
+ */
+ private String sanitizeForAppendReplacement(String src) {
+ return src.replace("\\", "\\\\").replace("$", "\\$");
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,84 @@
+/*
+ * 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;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.validation.ValidationException;
+import javax.validation.ValidationProviderResolver;
+import javax.validation.spi.ValidationProvider;
+
+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 DefaultValidationProviderResolver implements ValidationProviderResolver {
+
+ //TODO - Spec recommends caching per classloader
+ private static final String SPI_CFG = "META-INF/services/javax.validation.spi.ValidationProvider";
+
+ private static ClassLoader getCurrentClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ return cl == null ? DefaultValidationProviderResolver.class.getClassLoader() : cl;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<ValidationProvider<?>> getValidationProviders() {
+ List<ValidationProvider<?>> providers = new ArrayList<ValidationProvider<?>>();
+ try {
+ // get our classloader
+ ClassLoader cl = getCurrentClassLoader();
+ // find all service provider cfgs
+ Enumeration<URL> cfgs = cl.getResources(SPI_CFG);
+ while (cfgs.hasMoreElements()) {
+ final URL url = cfgs.nextElement();
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()), 256)) {
+ br.lines().filter(s -> s.charAt(0) != '#').map(String::trim).forEach(line -> {
+ // cfgs may contain multiple providers and/or comments
+ try {
+ // try loading the specified class
+ @SuppressWarnings("rawtypes")
+ final Class<? extends ValidationProvider> providerType =
+ cl.loadClass(line).asSubclass(ValidationProvider.class);
+ // create an instance to return
+ providers.add(Reflection.newInstance(providerType));
+ } catch (ClassNotFoundException e) {
+ throw new ValidationException(
+ "Failed to load provider " + line + " configured in file " + url, e);
+ }
+ });
+ } catch (IOException e) {
+ throw new ValidationException("Error trying to read " + url, e);
+ }
+ }
+ } catch (IOException e) {
+ throw new ValidationException("Error trying to read a " + SPI_CFG, e);
+ }
+ // caller must handle the case of no providers found
+ return providers;
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/GraphContext.java Fri Oct 12 15:00:48 2018
@@ -0,0 +1,153 @@
+/*
+ * 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;
+
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.validation.Path;
+import javax.validation.ValidationException;
+
+import org.apache.bval.jsr.metadata.ContainerElementKey;
+import org.apache.bval.jsr.util.NodeImpl;
+import org.apache.bval.jsr.util.PathImpl;
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.TypeUtils;
+
+public class GraphContext {
+
+ private final ApacheFactoryContext validatorContext;
+ private final PathImpl path;
+ private final Object value;
+ private final GraphContext parent;
+
+ public GraphContext(ApacheFactoryContext validatorContext, PathImpl path, Object value) {
+ this(validatorContext, path, value, null);
+ }
+
+ private GraphContext(ApacheFactoryContext validatorContext, PathImpl path, Object value, GraphContext parent) {
+ super();
+ this.validatorContext = Validate.notNull(validatorContext, "validatorContext");
+ this.path = Validate.notNull(path, "path");
+ this.value = value;
+ this.parent = parent;
+ }
+
+ public ApacheFactoryContext getValidatorContext() {
+ return validatorContext;
+ }
+
+ public PathImpl getPath() {
+ return PathImpl.copy(path);
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public GraphContext child(NodeImpl node, Object value) {
+ Validate.notNull(node, "node");
+ final PathImpl p = PathImpl.copy(path);
+ p.addNode(node);
+ return new GraphContext(validatorContext, p, value, this);
+ }
+
+ public GraphContext child(Path p, Object value) {
+ Validate.notNull(p, "Path");
+ final PathImpl impl = PathImpl.of(p);
+ Validate.isTrue(impl.isSubPathOf(path), "%s is not a subpath of %s", p, path);
+ return new GraphContext(validatorContext, impl == p ? PathImpl.copy(impl) : impl, value, this);
+ }
+
+ public boolean isRoot() {
+ return parent == null;
+ }
+
+ public boolean isRecursive() {
+ GraphContext c = parent;
+ while (c != null) {
+ if (c.value == value) {
+ return true;
+ }
+ c = c.parent;
+ }
+ return false;
+ }
+
+ public GraphContext getParent() {
+ return parent;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s: %s at '%s'", getClass().getSimpleName(), value, path);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null || !obj.getClass().equals(getClass())) {
+ return false;
+ }
+ final GraphContext other = (GraphContext) obj;
+ return other.validatorContext == validatorContext && other.value == value && other.getPath().equals(path);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(validatorContext, value, path);
+ }
+
+ public ContainerElementKey runtimeKey(ContainerElementKey key) {
+ Validate.notNull(key);
+ if (value != null) {
+ final Class<?> containerClass = key.getContainerClass();
+ final Class<? extends Object> runtimeType = value.getClass();
+ if (!runtimeType.equals(containerClass)) {
+ Exceptions.raiseUnless(containerClass.isAssignableFrom(runtimeType), ValidationException::new,
+ "Value %s is not assignment-compatible with %s", value, containerClass);
+
+ if (key.getTypeArgumentIndex() == null) {
+ return new ContainerElementKey(runtimeType, null);
+ }
+ final Map<TypeVariable<?>, Type> typeArguments =
+ TypeUtils.getTypeArguments(runtimeType, containerClass);
+
+ Type type =
+ typeArguments.get(containerClass.getTypeParameters()[key.getTypeArgumentIndex().intValue()]);
+
+ while (type instanceof TypeVariable<?>) {
+ final TypeVariable<?> var = (TypeVariable<?>) type;
+ final Type nextType = typeArguments.get(var);
+ if (nextType instanceof TypeVariable<?>) {
+ type = nextType;
+ } else {
+ return ContainerElementKey.forTypeVariable(var);
+ }
+ }
+ }
+ }
+ return key;
+ }
+}
Added: tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ParticipantFactory.java
URL: http://svn.apache.org/viewvc/tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ParticipantFactory.java?rev=1843674&view=auto
==============================================================================
--- tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ParticipantFactory.java (added)
+++ tomee/deps/branches/bval-2/bval-jsr/src/main/java/org/apache/bval/jsr/ParticipantFactory.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.jsr;
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import javax.validation.ValidationException;
+
+import org.apache.bval.cdi.BValExtension;
+import org.apache.bval.jsr.util.ToUnmodifiable;
+import org.apache.bval.util.Validate;
+import org.apache.commons.weaver.privilizer.Privileged;
+
+/**
+ * Factory object for helper/participant classes. The typical pattern is that this factory loads an instance of a class
+ * by name, taking into account whether Apache BVal is operating in a CDI environment.
+ */
+class ParticipantFactory implements Closeable {
+ private static final Logger log = Logger.getLogger(ParticipantFactory.class.getName());
+ private static final String META_INF_SERVICES = "META-INF/services/";
+
+ private final Collection<BValExtension.Releasable<?>> releasables = new CopyOnWriteArrayList<>();
+ private final List<ClassLoader> loaders;
+
+ ParticipantFactory(ClassLoader... loaders) {
+ super();
+ this.loaders = Collections.unmodifiableList(Arrays.asList(Validate
+ .noNullElements(loaders, "null %s specified at index %d", ClassLoader.class.getSimpleName()).clone()));
+ }
+
+ @Override
+ public void close() throws IOException {
+ for (final BValExtension.Releasable<?> releasable : releasables) {
+ releasable.release();
+ }
+ releasables.clear();
+ }
+
+ <T> T create(String classname) {
+ return newInstance(loadClass(classname));
+ }
+
+ <T> Set<T> loadServices(Class<T> type) {
+ Validate.notNull(type);
+ final Set<URL> resources = new LinkedHashSet<>();
+ final String resourceName = META_INF_SERVICES + type.getName();
+ for (ClassLoader loader : loaders) {
+ try {
+ for (Enumeration<URL> urls = loader.getResources(resourceName); urls.hasMoreElements();) {
+ resources.add(urls.nextElement());
+ }
+ } catch (IOException e) {
+ log.log(Level.SEVERE, "Error searching for resource(s) " + resourceName, e);
+ }
+ }
+ return resources.stream().map(this::read).flatMap(Collection::stream).<T> map(this::create)
+ .collect(ToUnmodifiable.set());
+ }
+
+ private Set<String> read(URL url) {
+ try (BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream()))) {
+ return r.lines().map(String::trim).filter(line -> line.charAt(0) != '#').collect(Collectors.toSet());
+ } catch (IOException e) {
+ log.log(Level.SEVERE, "Unable to read resource " + url, e);
+ return Collections.emptySet();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> Class<T> loadClass(final String className) {
+ for (ClassLoader loader : loaders) {
+ try {
+ return (Class<T>) Class.forName(className, true, loader);
+ } catch (final ClassNotFoundException ex) {
+ }
+ }
+ throw new ValidationException("Unable to load class " + className);
+ }
+
+ @Privileged
+ private <T> T newInstance(final Class<T> cls) {
+ try {
+ final BValExtension.Releasable<T> releasable = BValExtension.inject(cls);
+ releasables.add(releasable);
+ return releasable.getInstance();
+ } catch (Exception | NoClassDefFoundError e) {
+ }
+ try {
+ return cls.getConstructor().newInstance();
+ } catch (final Exception e) {
+ throw new ValidationException(e.getMessage(), e);
+ }
+ }
+}