You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2018/02/21 21:01:54 UTC
[04/17] bval git commit: BV2: xml processing changes
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java b/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java
index 7b9b14f..bed2e10 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java
@@ -22,12 +22,14 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
-import java.util.Enumeration;
+import java.util.Collections;
+import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
+import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Level;
@@ -40,59 +42,34 @@ import javax.validation.TraversableResolver;
import javax.validation.ValidationException;
import javax.validation.executable.ExecutableType;
import javax.validation.spi.ValidationProvider;
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
import org.apache.bval.jsr.BootstrapConfigurationImpl;
import org.apache.bval.jsr.ConfigurationImpl;
-import org.apache.bval.jsr.util.IOs;
+import org.apache.bval.jsr.metadata.XmlBuilder;
+import org.apache.bval.util.Exceptions;
import org.apache.bval.util.reflection.Reflection;
import org.apache.commons.weaver.privilizer.Privileged;
import org.apache.commons.weaver.privilizer.Privilizing;
import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
-import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
/**
* Description: uses jaxb to parse validation.xml<br/>
*/
@Privilizing(@CallTo(Reflection.class))
public class ValidationParser {
+
private static final String DEFAULT_VALIDATION_XML_FILE = "META-INF/validation.xml";
- private static final String VALIDATION_CONFIGURATION_XSD = "META-INF/validation-configuration-1.1.xsd";
private static final Logger log = Logger.getLogger(ValidationParser.class.getName());
- private static final ConcurrentMap<String, Schema> SCHEMA_CACHE = new ConcurrentHashMap<String, Schema>(1);
-
- private ValidationConfigType xmlConfig;
- private BootstrapConfigurationImpl bootstrap;
- private Collection<ValidationException> exceptions = new CopyOnWriteArrayList<ValidationException>();
-
- private ValidationParser() {
- // no-op
- }
- public void applyConfigWithInstantiation(ConfigurationImpl targetConfig) {
- if (xmlConfig == null) {
- return;
- }
-
- applyProviderClass(xmlConfig, targetConfig);
- applyMessageInterpolator(xmlConfig, targetConfig);
- applyTraversableResolver(xmlConfig, targetConfig);
- applyConstraintFactory(xmlConfig, targetConfig);
- applyParameterNameProvider(xmlConfig, targetConfig);
- applyMappingStreams(xmlConfig, targetConfig);
- applyProperties(xmlConfig, targetConfig);
- }
-
- public BootstrapConfigurationImpl getBootstrap() {
- return bootstrap;
- }
+ private static final SchemaManager SCHEMA_MANAGER = new SchemaManager.Builder()
+ .add(null, "http://jboss.org/xml/ns/javax/validation/configuration",
+ "META-INF/validation-configuration-1.0.xsd")
+ .add(XmlBuilder.Version.v11.getId(), "http://jboss.org/xml/ns/javax/validation/configuration",
+ "META-INF/validation-configuration-1.1.xsd")
+ .add(XmlBuilder.Version.v20.getId(), "http://xmlns.jcp.org/xml/ns/javax/validation/configuration",
+ "META-INF/validation-configuration-2.0.xsd")
+ .build();
public static String getValidationXmlFile(String file) {
if (file == null) {
@@ -101,19 +78,30 @@ public class ValidationParser {
return file;
}
- public static ValidationParser processValidationConfig(final String file, final ConfigurationImpl targetConfig, final boolean ignoreXml) {
+ public static ValidationParser processValidationConfig(final String file, final ConfigurationImpl targetConfig,
+ final boolean ignoreXml) {
final ValidationParser parser = new ValidationParser();
if (!ignoreXml) {
parser.xmlConfig = parseXmlConfig(file);
}
- if (parser.xmlConfig != null) {
+ if (parser.xmlConfig == null) { // default config
+ final CopyOnWriteArraySet<ExecutableType> executableTypes = new CopyOnWriteArraySet<>();
+ executableTypes.add(ExecutableType.CONSTRUCTORS);
+ executableTypes.add(ExecutableType.NON_GETTER_METHODS);
+
+ parser.bootstrap = new BootstrapConfigurationImpl(null, null, null, null, null, Collections.emptySet(),
+ true, executableTypes, Collections.emptyMap(), null, Collections.emptySet());
+
+ targetConfig.setExecutableValidation(executableTypes);
+ } else {
if (parser.xmlConfig.getExecutableValidation() == null) {
final ExecutableValidationType value = new ExecutableValidationType();
value.setEnabled(true);
- final DefaultValidatedExecutableTypesType defaultValidatedExecutableTypes = new DefaultValidatedExecutableTypesType();
+ final DefaultValidatedExecutableTypesType defaultValidatedExecutableTypes =
+ new DefaultValidatedExecutableTypesType();
value.setDefaultValidatedExecutableTypes(defaultValidatedExecutableTypes);
defaultValidatedExecutableTypes.getExecutableType().add(ExecutableType.CONSTRUCTORS);
defaultValidatedExecutableTypes.getExecutableType().add(ExecutableType.NON_GETTER_METHODS);
@@ -123,35 +111,19 @@ public class ValidationParser {
applySimpleConfig(parser.xmlConfig, targetConfig);
- parser.bootstrap = new BootstrapConfigurationImpl(
- parser.xmlConfig.getDefaultProvider(),
- parser.xmlConfig.getConstraintValidatorFactory(),
- parser.xmlConfig.getMessageInterpolator(),
- parser.xmlConfig.getTraversableResolver(),
- parser.xmlConfig.getParameterNameProvider(),
- new CopyOnWriteArraySet<String>(parser.xmlConfig.getConstraintMapping()),
- parser.xmlConfig.getExecutableValidation().getEnabled(),
- new CopyOnWriteArraySet<ExecutableType>(targetConfig.getExecutableValidation()),
- toMap(parser.xmlConfig.getProperty()));
- } else { // default config
- final CopyOnWriteArraySet<ExecutableType> executableTypes = new CopyOnWriteArraySet<ExecutableType>();
- executableTypes.add(ExecutableType.CONSTRUCTORS);
- executableTypes.add(ExecutableType.NON_GETTER_METHODS);
-
- parser.bootstrap = new BootstrapConfigurationImpl(
- null, null, null, null, null,
- new CopyOnWriteArraySet<String>(),
- true,
- executableTypes,
- new HashMap<String, String>());
-
- targetConfig.setExecutableValidation(executableTypes);
+ parser.bootstrap = new BootstrapConfigurationImpl(parser.xmlConfig.getDefaultProvider(),
+ parser.xmlConfig.getConstraintValidatorFactory(), parser.xmlConfig.getMessageInterpolator(),
+ parser.xmlConfig.getTraversableResolver(), parser.xmlConfig.getParameterNameProvider(),
+ new HashSet<>(parser.xmlConfig.getConstraintMapping()),
+ parser.xmlConfig.getExecutableValidation().getEnabled(),
+ new HashSet<>(targetConfig.getExecutableValidation()), toMap(parser.xmlConfig.getProperty()),
+ parser.xmlConfig.getClockProvider(), new HashSet<>(parser.xmlConfig.getValueExtractor()));
}
return parser;
}
private static Map<String, String> toMap(final List<PropertyType> property) {
- final Map<String, String> map = new HashMap<String, String>();
+ final Map<String, String> map = new HashMap<>();
if (property != null) {
for (final PropertyType p : property) {
map.put(p.getName(), p.getValue());
@@ -162,78 +134,26 @@ public class ValidationParser {
@Privileged
private static ValidationConfigType parseXmlConfig(final String validationXmlFile) {
- InputStream inputStream = null;
- try {
- inputStream = getInputStream(getValidationXmlFile(validationXmlFile));
+ try (InputStream inputStream = getInputStream(getValidationXmlFile(validationXmlFile))) {
if (inputStream == null) {
- log.log(Level.FINEST, String.format("No %s found. Using annotation based configuration only.", validationXmlFile));
+ log.log(Level.FINEST,
+ String.format("No %s found. Using annotation based configuration only.", validationXmlFile));
return null;
}
-
log.log(Level.FINEST, String.format("%s found.", validationXmlFile));
- Schema schema = getSchema();
- JAXBContext jc = JAXBContext.newInstance(ValidationConfigType.class);
- Unmarshaller unmarshaller = jc.createUnmarshaller();
- unmarshaller.setSchema(schema);
- StreamSource stream = new StreamSource(inputStream);
- JAXBElement<ValidationConfigType> root =
- unmarshaller.unmarshal(stream, ValidationConfigType.class);
- return root.getValue();
- } catch (JAXBException e) {
- throw new ValidationException("Unable to parse " + validationXmlFile, e);
- } catch (IOException e) {
+ return SCHEMA_MANAGER.unmarshal(new InputSource(inputStream), ValidationConfigType.class);
+ } catch (Exception e) {
throw new ValidationException("Unable to parse " + validationXmlFile, e);
- } finally {
- IOs.closeQuietly(inputStream);
}
}
protected static InputStream getInputStream(final String path) throws IOException {
final ClassLoader loader = Reflection.getClassLoader(ValidationParser.class);
- final InputStream inputStream = loader.getResourceAsStream(path);
-
- if (inputStream != null) {
- // spec says: If more than one META-INF/validation.xml file
- // is found in the classpath, a ValidationException is raised.
- final Enumeration<URL> urls = loader.getResources(path);
- if (urls.hasMoreElements()) {
- final String url = urls.nextElement().toString();
- while (urls.hasMoreElements()) {
- if (!url.equals(urls.nextElement().toString())) { // complain when first duplicate found
- throw new ValidationException("More than one " + path + " is found in the classpath");
- }
- }
- }
- }
-
- return IOs.convertToMarkableInputStream(inputStream);
- }
-
- private static Schema getSchema() {
- return getSchema(VALIDATION_CONFIGURATION_XSD);
- }
-
- static Schema getSchema(final String xsd) {
- final Schema schema = SCHEMA_CACHE.get(xsd);
- if (schema != null) {
- return schema;
- }
-
- final ClassLoader loader = Reflection.getClassLoader(ValidationParser.class);
- final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- final URL schemaUrl = loader.getResource(xsd);
- try {
- Schema s = sf.newSchema(schemaUrl);
- final Schema old = SCHEMA_CACHE.putIfAbsent(xsd, s);
- if (old != null) {
- s = old;
- }
- return s;
- } catch (SAXException e) {
- log.log(Level.WARNING, String.format("Unable to parse schema: %s", xsd), e);
- return null;
- }
+ final List<URL> urls = Collections.list(loader.getResources(path));
+ Exceptions.raiseIf(urls.stream().distinct().count() > 1, ValidationException::new,
+ "More than one %s is found in the classpath", path);
+ return urls.isEmpty() ? null : urls.get(0).openStream();
}
public static void applySimpleConfig(ValidationConfigType xmlConfig, ConfigurationImpl targetConfig) {
@@ -246,37 +166,84 @@ public class ValidationParser {
}
}
- private static void applyExecutableValidation(final ValidationConfigType xmlConfig, final ConfigurationImpl targetConfig) {
- final CopyOnWriteArrayList<ExecutableType> executableTypes = new CopyOnWriteArrayList<ExecutableType>();
- if (xmlConfig.getExecutableValidation() != null && xmlConfig.getExecutableValidation().getEnabled()
- && xmlConfig.getExecutableValidation().getDefaultValidatedExecutableTypes() != null) {
- executableTypes.addAll(xmlConfig.getExecutableValidation().getDefaultValidatedExecutableTypes().getExecutableType());
- }
+ private static void applyExecutableValidation(final ValidationConfigType xmlConfig,
+ final ConfigurationImpl targetConfig) {
+
+ final Set<ExecutableType> executableTypes = Optional.of(xmlConfig)
+ .map(ValidationConfigType::getExecutableValidation).filter(vc -> Boolean.TRUE.equals(vc.getEnabled()))
+ .map(ExecutableValidationType::getDefaultValidatedExecutableTypes)
+ .map(DefaultValidatedExecutableTypesType::getExecutableType).map(EnumSet::copyOf)
+ .orElseGet(() -> EnumSet.noneOf(ExecutableType.class));
if (executableTypes.contains(ExecutableType.ALL)) {
executableTypes.clear();
executableTypes.add(ExecutableType.CONSTRUCTORS);
executableTypes.add(ExecutableType.NON_GETTER_METHODS);
executableTypes.add(ExecutableType.GETTER_METHODS);
- } else if (executableTypes.contains(ExecutableType.NONE)) { // if both are present ALL gains
+ } else if (executableTypes.contains(ExecutableType.NONE)) { // if both are present ALL trumps NONE
executableTypes.clear();
}
+ targetConfig.setExecutableValidation(Collections.unmodifiableSet(executableTypes));
+ }
+
+ private static void applyMappingStreams(ValidationConfigType xmlConfig, ConfigurationImpl target) {
+ for (String rawMappingFileName : xmlConfig.getConstraintMapping()) {
+ String mappingFileName = rawMappingFileName;
+ if (mappingFileName.charAt(0) == '/') {
+ // Classloader needs a path without a starting /
+ mappingFileName = mappingFileName.substring(1);
+ }
+ log.log(Level.FINEST, String.format("Trying to open input stream for %s", mappingFileName));
+ try {
+ final InputStream in = getInputStream(mappingFileName);
+ Exceptions.raiseIf(in == null, ValidationException::new,
+ "Unable to open input stream for mapping file %s", mappingFileName);
+ target.addMapping(in);
+ } catch (IOException e) {
+ Exceptions.raise(ValidationException::new, e, "Unable to open input stream for mapping file %s",
+ mappingFileName);
+ }
+ }
+ }
+
+ private ValidationConfigType xmlConfig;
+ private BootstrapConfigurationImpl bootstrap;
+ private Collection<ValidationException> exceptions = new CopyOnWriteArrayList<ValidationException>();
+
+ private ValidationParser() {
+ // no-op
+ }
+
+ public void applyConfigWithInstantiation(ConfigurationImpl targetConfig) {
+ if (xmlConfig == null) {
+ return;
+ }
- targetConfig.setExecutableValidation(executableTypes);
+ applyProviderClass(xmlConfig, targetConfig);
+ applyMessageInterpolator(xmlConfig, targetConfig);
+ applyTraversableResolver(xmlConfig, targetConfig);
+ applyConstraintFactory(xmlConfig, targetConfig);
+ applyParameterNameProvider(xmlConfig, targetConfig);
+ applyMappingStreams(xmlConfig, targetConfig);
+ applyProperties(xmlConfig, targetConfig);
+ }
+
+ public BootstrapConfigurationImpl getBootstrap() {
+ return bootstrap;
}
- private void applyParameterNameProvider(final ValidationConfigType xmlConfig, final ConfigurationImpl targetConfig) {
+ private void applyParameterNameProvider(final ValidationConfigType xmlConfig,
+ final ConfigurationImpl targetConfig) {
final String parameterNameProvider = xmlConfig.getParameterNameProvider();
- if (targetConfig.getParameterNameProvider() == targetConfig.getDefaultParameterNameProvider()) { // ref ==
- if (parameterNameProvider != null) {
- final Class<?> loaded = loadClass(parameterNameProvider);
- if (loaded == null) {
- log.log(Level.SEVERE, "Can't load " + parameterNameProvider);
- } else {
- final Class<? extends ParameterNameProvider> clazz = loaded.asSubclass(ParameterNameProvider.class);
- targetConfig.parameterNameProviderClass(clazz);
- log.log(Level.INFO, String.format("Using %s as validation provider.", parameterNameProvider));
- }
+ if (targetConfig.getParameterNameProvider() == targetConfig.getDefaultParameterNameProvider()
+ && parameterNameProvider != null) {
+ final Class<?> loaded = loadClass(parameterNameProvider);
+ if (loaded == null) {
+ log.log(Level.SEVERE, "Can't load " + parameterNameProvider);
+ } else {
+ final Class<? extends ParameterNameProvider> clazz = loaded.asSubclass(ParameterNameProvider.class);
+ targetConfig.parameterNameProviderClass(clazz);
+ log.log(Level.INFO, String.format("Using %s as validation provider.", parameterNameProvider));
}
}
}
@@ -293,65 +260,36 @@ public class ValidationParser {
}
@SuppressWarnings("unchecked")
- private void applyMessageInterpolator(ValidationConfigType xmlConfig,
- ConfigurationImpl target) {
+ private void applyMessageInterpolator(ValidationConfigType xmlConfig, ConfigurationImpl target) {
String messageInterpolatorClass = xmlConfig.getMessageInterpolator();
- if (target.getMessageInterpolator() == target.getDefaultMessageInterpolator()) { // ref ==
- if (messageInterpolatorClass != null) {
- Class<MessageInterpolator> clazz = (Class<MessageInterpolator>)
- loadClass(messageInterpolatorClass);
- target.messageInterpolatorClass(clazz);
- log.log(Level.INFO, String.format("Using %s as message interpolator.", messageInterpolatorClass));
- }
+ if (target.getMessageInterpolator() == target.getDefaultMessageInterpolator()
+ && messageInterpolatorClass != null) {
+ Class<MessageInterpolator> clazz = (Class<MessageInterpolator>) loadClass(messageInterpolatorClass);
+ target.messageInterpolatorClass(clazz);
+ log.log(Level.INFO, String.format("Using %s as message interpolator.", messageInterpolatorClass));
}
}
@SuppressWarnings("unchecked")
- private void applyTraversableResolver(ValidationConfigType xmlConfig,
- ConfigurationImpl target) {
+ private void applyTraversableResolver(ValidationConfigType xmlConfig, ConfigurationImpl target) {
String traversableResolverClass = xmlConfig.getTraversableResolver();
- if (target.getTraversableResolver() == target.getDefaultTraversableResolver() && traversableResolverClass != null) {
- Class<TraversableResolver> clazz = (Class<TraversableResolver>)
- loadClass(traversableResolverClass);
- target.traversableResolverClass(clazz);
- log.log(Level.INFO, String.format("Using %s as traversable resolver.", traversableResolverClass));
- }
+ if (target.getTraversableResolver() == target.getDefaultTraversableResolver()
+ && traversableResolverClass != null) {
+ Class<TraversableResolver> clazz = (Class<TraversableResolver>) loadClass(traversableResolverClass);
+ target.traversableResolverClass(clazz);
+ log.log(Level.INFO, String.format("Using %s as traversable resolver.", traversableResolverClass));
+ }
}
@SuppressWarnings("unchecked")
- private void applyConstraintFactory(ValidationConfigType xmlConfig,
- ConfigurationImpl target) {
+ private void applyConstraintFactory(ValidationConfigType xmlConfig, ConfigurationImpl target) {
String constraintFactoryClass = xmlConfig.getConstraintValidatorFactory();
- if (target.getConstraintValidatorFactory() == target.getDefaultConstraintValidatorFactory() && constraintFactoryClass != null) {
- Class<ConstraintValidatorFactory> clazz = (Class<ConstraintValidatorFactory>)
- loadClass(constraintFactoryClass);
- target.constraintValidatorFactoryClass(clazz);
- log.log(Level.INFO, String.format("Using %s as constraint factory.", constraintFactoryClass));
- }
- }
-
- private static void applyMappingStreams(ValidationConfigType xmlConfig,
- ConfigurationImpl target) {
- for (String rawMappingFileName : xmlConfig.getConstraintMapping()) {
- String mappingFileName = rawMappingFileName;
- if (mappingFileName.startsWith("/")) {
- // Classloader needs a path without a starting /
- mappingFileName = mappingFileName.substring(1);
- }
- log.log(Level.FINEST, String.format("Trying to open input stream for %s", mappingFileName));
- InputStream in;
- try {
- in = getInputStream(mappingFileName);
- if (in == null) {
- throw new ValidationException(
- "Unable to open input stream for mapping file " +
- mappingFileName);
- }
- } catch (IOException e) {
- throw new ValidationException("Unable to open input stream for mapping file " +
- mappingFileName, e);
- }
- target.addMapping(in);
+ if (target.getConstraintValidatorFactory() == target.getDefaultConstraintValidatorFactory()
+ && constraintFactoryClass != null) {
+ Class<ConstraintValidatorFactory> clazz =
+ (Class<ConstraintValidatorFactory>) loadClass(constraintFactoryClass);
+ target.constraintValidatorFactoryClass(clazz);
+ log.log(Level.INFO, String.format("Using %s as constraint factory.", constraintFactoryClass));
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.java b/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.java
new file mode 100644
index 0000000..2826174
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/xml/XmlUtils.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.bval.jsr.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.helpers.DefaultValidationEventHandler;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.apache.bval.util.reflection.Reflection;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+class XmlUtils {
+ private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
+ private static final Logger log = Logger.getLogger(XmlUtils.class.getName());
+ private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+
+ static Schema loadSchema(String resource) {
+ final URL schemaUrl = Reflection.getClassLoader(XmlUtils.class).getResource(resource);
+ try {
+ return SCHEMA_FACTORY.newSchema(schemaUrl);
+ } catch (SAXException e) {
+ log.log(Level.WARNING, String.format("Unable to parse schema: %s", resource), e);
+ return null;
+ }
+ }
+
+ static Document parse(InputStream in) throws SAXException, IOException, ParserConfigurationException {
+ return DOCUMENT_BUILDER_FACTORY.newDocumentBuilder().parse(in);
+ }
+
+ static <T> T unmarshal(Document document, Schema schema, Class<T> type) throws JAXBException {
+ final JAXBContext jc = JAXBContext.newInstance(type);
+ final Unmarshaller unmarshaller = jc.createUnmarshaller();
+ unmarshaller.setSchema(schema);
+ unmarshaller.setEventHandler(new DefaultValidationEventHandler());
+ final JAXBElement<T> root = unmarshaller.unmarshal(document, type);
+ return root.getValue();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/main/xjb/binding-customization.xjb
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/xjb/binding-customization.xjb b/bval-jsr/src/main/xjb/binding-customization.xjb
index 598bd3c..762a058 100644
--- a/bval-jsr/src/main/xjb/binding-customization.xjb
+++ b/bval-jsr/src/main/xjb/binding-customization.xjb
@@ -19,7 +19,7 @@
-->
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
- <jxb:bindings schemaLocation="../xsd/validation-mapping-1.1.xsd" node="/xs:schema">
+ <jxb:bindings schemaLocation="../xsd/validation-mapping-2.0.xsd" node="/xs:schema">
<jxb:globalBindings>
<xjc:javaType name="java.lang.String" xmlType="xs:string"
adapter="javax.xml.bind.annotation.adapters.CollapsedStringAdapter"/>
@@ -29,7 +29,7 @@
<jxb:property name="classType"/>
</jxb:bindings>
</jxb:bindings>
- <jxb:bindings schemaLocation="../xsd/validation-configuration-1.1.xsd" node="/xs:schema">
+ <jxb:bindings schemaLocation="../xsd/validation-configuration-2.0.xsd" node="/xs:schema">
<jxb:bindings node="//xs:element[@name='executable-type']">
<jxb:javaType name="javax.validation.executable.ExecutableType"
parseMethod="javax.validation.executable.ExecutableType.valueOf"/>
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/main/xsd/validation-configuration-2.0.xsd
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/xsd/validation-configuration-2.0.xsd b/bval-jsr/src/main/xsd/validation-configuration-2.0.xsd
new file mode 100644
index 0000000..6fd7874
--- /dev/null
+++ b/bval-jsr/src/main/xsd/validation-configuration-2.0.xsd
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<xs:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://xmlns.jcp.org/xml/ns/javax/validation/configuration"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:config="http://xmlns.jcp.org/xml/ns/javax/validation/configuration"
+ version="2.0">
+ <xs:element name="validation-config" type="config:validation-configType" />
+ <xs:complexType name="validation-configType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="default-provider" minOccurs="0" />
+ <xs:element type="xs:string" name="message-interpolator" minOccurs="0" />
+ <xs:element type="xs:string" name="traversable-resolver" minOccurs="0" />
+ <xs:element type="xs:string" name="constraint-validator-factory" minOccurs="0" />
+ <xs:element type="xs:string" name="parameter-name-provider" minOccurs="0" />
+ <xs:element type="xs:string" name="clock-provider" minOccurs="0" />
+ <xs:element type="xs:string" name="value-extractor" maxOccurs="unbounded" minOccurs="0" />
+ <xs:element type="config:executable-validationType" name="executable-validation" minOccurs="0" />
+ <xs:element type="xs:string" name="constraint-mapping" maxOccurs="unbounded" minOccurs="0" />
+ <xs:element type="config:propertyType" name="property" maxOccurs="unbounded" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="version" type="config:versionType" fixed="2.0" /> <!-- use="required" -->
+ </xs:complexType>
+ <xs:complexType name="executable-validationType">
+ <xs:sequence>
+ <xs:element type="config:default-validated-executable-typesType" name="default-validated-executable-types" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="enabled" use="optional" type="xs:boolean" default="true" />
+ </xs:complexType>
+ <xs:complexType name="default-validated-executable-typesType">
+ <xs:sequence>
+ <xs:element name="executable-type" maxOccurs="unbounded" minOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NONE" />
+ <xs:enumeration value="CONSTRUCTORS" />
+ <xs:enumeration value="NON_GETTER_METHODS" />
+ <xs:enumeration value="GETTER_METHODS" />
+ <xs:enumeration value="ALL" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="propertyType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" use="required" type="xs:string" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:simpleType name="versionType">
+ <xs:restriction base="xs:token">
+ <xs:pattern value="[0-9]+(\.[0-9]+)*" />
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/main/xsd/validation-mapping-2.0.xsd
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/xsd/validation-mapping-2.0.xsd b/bval-jsr/src/main/xsd/validation-mapping-2.0.xsd
new file mode 100644
index 0000000..9d16bf3
--- /dev/null
+++ b/bval-jsr/src/main/xsd/validation-mapping-2.0.xsd
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<xs:schema attributeFormDefault="unqualified"
+ elementFormDefault="qualified"
+ targetNamespace="http://xmlns.jcp.org/xml/ns/javax/validation/mapping"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:map="http://xmlns.jcp.org/xml/ns/javax/validation/mapping"
+ version="2.0">
+ <xs:element name="constraint-mappings" type="map:constraint-mappingsType" />
+
+ <xs:complexType name="payloadType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="groupsType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="groupSequenceType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="groupConversionType">
+ <xs:attribute type="xs:string" name="from" use="required" />
+ <xs:attribute type="xs:string" name="to" use="required" />
+ </xs:complexType>
+ <xs:complexType name="constraint-mappingsType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="default-package" minOccurs="0" />
+ <xs:element type="map:beanType"
+ name="bean"
+ maxOccurs="unbounded"
+ minOccurs="0" />
+ <xs:element type="map:constraint-definitionType"
+ name="constraint-definition"
+ maxOccurs="unbounded"
+ minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="version" type="map:versionType" fixed="2.0" /> <!-- use="required" -->
+ </xs:complexType>
+ <xs:simpleType name="versionType">
+ <xs:restriction base="xs:token">
+ <xs:pattern value="[0-9]+(\.[0-9]+)*" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="validated-byType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute type="xs:boolean" name="include-existing-validators" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="constraintType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="message" minOccurs="0" />
+ <xs:element type="map:groupsType"
+ name="groups"
+ minOccurs="0" />
+ <xs:element type="map:payloadType"
+ name="payload"
+ minOccurs="0" />
+ <xs:element type="map:elementType"
+ name="element"
+ maxOccurs="unbounded"
+ minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="annotation" use="required" />
+ </xs:complexType>
+ <xs:complexType name="elementType" mixed="true">
+ <xs:sequence>
+ <xs:element type="xs:string" name="value" maxOccurs="unbounded" minOccurs="0" />
+ <xs:element type="map:annotationType"
+ name="annotation"
+ maxOccurs="unbounded"
+ minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="name" use="required" />
+ </xs:complexType>
+ <xs:complexType name="containerElementTypeType">
+ <xs:sequence>
+ <xs:element type="xs:string"
+ name="valid"
+ minOccurs="0"
+ fixed="" />
+ <xs:element type="map:groupConversionType"
+ name="convert-group"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:containerElementTypeType"
+ name="container-element-type"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:constraintType"
+ name="constraint"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="type-argument-index" use="optional">
+ <xs:simpleType>
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="0" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ <xs:complexType name="classType">
+ <xs:sequence>
+ <xs:element type="map:groupSequenceType"
+ name="group-sequence"
+ minOccurs="0" />
+ <xs:element type="map:constraintType"
+ name="constraint"
+ maxOccurs="unbounded"
+ minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="beanType">
+ <xs:sequence>
+ <xs:element type="map:classType"
+ name="class"
+ minOccurs="0">
+ </xs:element>
+ <xs:element type="map:fieldType"
+ name="field"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:getterType"
+ name="getter"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:constructorType"
+ name="constructor"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:methodType"
+ name="method"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="class" use="required" />
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" default="true" />
+ </xs:complexType>
+ <xs:complexType name="annotationType">
+ <xs:sequence>
+ <xs:element type="map:elementType"
+ name="element"
+ maxOccurs="unbounded"
+ minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="getterType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="valid" minOccurs="0" fixed="" />
+ <xs:element type="map:groupConversionType"
+ name="convert-group"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:containerElementTypeType"
+ name="container-element-type"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:constraintType"
+ name="constraint"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="name" use="required" />
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="methodType">
+ <xs:sequence>
+ <xs:element type="map:parameterType"
+ name="parameter"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:crossParameterType"
+ name="cross-parameter"
+ minOccurs="0"
+ maxOccurs="1" />
+ <xs:element type="map:returnValueType"
+ name="return-value"
+ minOccurs="0"
+ maxOccurs="1" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="name" use="required" />
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="constructorType">
+ <xs:sequence>
+ <xs:element type="map:parameterType"
+ name="parameter"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:crossParameterType"
+ name="cross-parameter"
+ minOccurs="0"
+ maxOccurs="1" />
+ <xs:element type="map:returnValueType"
+ name="return-value"
+ minOccurs="0"
+ maxOccurs="1" />
+ </xs:sequence>
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="parameterType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="valid" minOccurs="0" fixed="" />
+ <xs:element type="map:groupConversionType"
+ name="convert-group"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:containerElementTypeType"
+ name="container-element-type"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:constraintType"
+ name="constraint"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="type" use="required" />
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="returnValueType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="valid" minOccurs="0" fixed="" />
+ <xs:element type="map:groupConversionType"
+ name="convert-group"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:containerElementTypeType"
+ name="container-element-type"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:constraintType"
+ name="constraint"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="crossParameterType">
+ <xs:sequence>
+ <xs:element type="map:constraintType"
+ name="constraint"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+ <xs:complexType name="constraint-definitionType">
+ <xs:sequence>
+ <xs:element type="map:validated-byType"
+ name="validated-by" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="annotation" use="required" />
+ </xs:complexType>
+ <xs:complexType name="fieldType">
+ <xs:sequence>
+ <xs:element type="xs:string" name="valid" minOccurs="0" fixed="" />
+ <xs:element type="map:groupConversionType"
+ name="convert-group"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:containerElementTypeType"
+ name="container-element-type"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element type="map:constraintType"
+ name="constraint"
+ minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="name" use="required" />
+ <xs:attribute type="xs:boolean" name="ignore-annotations" use="optional" />
+ </xs:complexType>
+</xs:schema>
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/test/java/org/apache/bval/jsr/xml/Demo.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/test/java/org/apache/bval/jsr/xml/Demo.java b/bval-jsr/src/test/java/org/apache/bval/jsr/xml/Demo.java
new file mode 100644
index 0000000..02a07a8
--- /dev/null
+++ b/bval-jsr/src/test/java/org/apache/bval/jsr/xml/Demo.java
@@ -0,0 +1,40 @@
+package org.apache.bval.jsr.xml;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.UnmarshallerHandler;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+public class Demo {
+
+ @Test
+ public void test1() throws Exception {
+ JAXBContext jc = JAXBContext.newInstance(ObjectFactory.class);
+
+ // Set the parent XMLReader on the XMLFilter
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setNamespaceAware(true);
+ SAXParser sp = spf.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+
+ // Set UnmarshallerHandler as ContentHandler on XMLFilter
+
+ Unmarshaller unmarshaller = jc.createUnmarshaller();
+
+ UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
+ xr.setContentHandler(unmarshallerHandler);
+
+ // Parse the XML
+ InputSource xml = new InputSource(getClass().getResourceAsStream("/sample-validation2.xml"));
+ xr.parse(xml);
+ JAXBElement<ValidationConfigType> result = (JAXBElement<ValidationConfigType>) unmarshallerHandler.getResult();
+ System.out.println(ToStringBuilder.reflectionToString(result.getValue()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/test/java/org/apache/bval/jsr/xml/ValidationParserTest.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/test/java/org/apache/bval/jsr/xml/ValidationParserTest.java b/bval-jsr/src/test/java/org/apache/bval/jsr/xml/ValidationParserTest.java
index 827abae..41d4f13 100644
--- a/bval-jsr/src/test/java/org/apache/bval/jsr/xml/ValidationParserTest.java
+++ b/bval-jsr/src/test/java/org/apache/bval/jsr/xml/ValidationParserTest.java
@@ -19,6 +19,8 @@
package org.apache.bval.jsr.xml;
import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
@@ -84,6 +86,18 @@ public class ValidationParserTest implements ApacheValidatorConfiguration.Proper
}
@Test
+ public void testParseV11() {
+ ConfigurationImpl config = new ConfigurationImpl(null, new ApacheValidationProvider());
+ ValidationParser.processValidationConfig("sample-validation11.xml", config, false);
+ }
+
+ @Test
+ public void testParseV20() {
+ ConfigurationImpl config = new ConfigurationImpl(null, new ApacheValidationProvider());
+ ValidationParser.processValidationConfig("sample-validation2.xml", config, false);
+ }
+
+ @Test
public void testConfigureFromXml() {
ValidatorFactory factory = getFactory();
assertThat(factory.getMessageInterpolator(), instanceOf(TestMessageInterpolator.class));
@@ -105,8 +119,8 @@ public class ValidationParserTest implements ApacheValidatorConfiguration.Proper
bean.setValueCode("illegal");
Validator validator = getFactory().getValidator();
Set<ConstraintViolation<XmlEntitySampleBean>> results = validator.validate(bean);
- assertTrue(!results.isEmpty());
- assertTrue(results.size() == 3);
+ assertFalse(results.isEmpty());
+ assertEquals(3, results.size());
bean.setZipCode("123");
bean.setValueCode("20");
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/test/resources/sample-validation11.xml
----------------------------------------------------------------------
diff --git a/bval-jsr/src/test/resources/sample-validation11.xml b/bval-jsr/src/test/resources/sample-validation11.xml
new file mode 100644
index 0000000..648ba1c
--- /dev/null
+++ b/bval-jsr/src/test/resources/sample-validation11.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<validation-config
+ xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation=
+ "http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd"
+ version="1.1">
+ <default-provider>org.apache.bval.jsr.ApacheValidationProvider</default-provider>
+ <message-interpolator>org.apache.bval.jsr.xml.TestMessageInterpolator</message-interpolator>
+ <traversable-resolver>org.apache.bval.jsr.resolver.SimpleTraversableResolver</traversable-resolver>
+ <constraint-validator-factory>org.apache.bval.jsr.xml.TestConstraintValidatorFactory</constraint-validator-factory>
+ <constraint-mapping>sample-constraints.xml</constraint-mapping>
+ <property name="test-prop">test-prop-value</property>
+</validation-config>
http://git-wip-us.apache.org/repos/asf/bval/blob/5c09f0dd/bval-jsr/src/test/resources/sample-validation2.xml
----------------------------------------------------------------------
diff --git a/bval-jsr/src/test/resources/sample-validation2.xml b/bval-jsr/src/test/resources/sample-validation2.xml
new file mode 100644
index 0000000..4758454
--- /dev/null
+++ b/bval-jsr/src/test/resources/sample-validation2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<validation-config
+ xmlns="http://xmlns.jcp.org/xml/ns/javax/validation/configuration"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation=
+ "http://xmlns.jcp.org/xml/ns/javax/validation/configuration validation-configuration-2.0.xsd"
+ version="2.0">
+ <default-provider>org.apache.bval.jsr.ApacheValidationProvider</default-provider>
+ <message-interpolator>org.apache.bval.jsr.xml.TestMessageInterpolator</message-interpolator>
+ <traversable-resolver>org.apache.bval.jsr.resolver.SimpleTraversableResolver</traversable-resolver>
+ <constraint-validator-factory>org.apache.bval.jsr.xml.TestConstraintValidatorFactory</constraint-validator-factory>
+ <constraint-mapping>sample-constraints.xml</constraint-mapping>
+ <property name="test-prop">test-prop-value</property>
+</validation-config>