You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by rm...@apache.org on 2013/08/26 15:59:20 UTC

svn commit: r1517540 [10/15] - in /bval/branches/bval-11/bval-jsr: ./ src/ src/main/ src/main/appended-resources/ src/main/appended-resources/META-INF/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/bval/ src/main/...

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationMappingParser.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,787 @@
+/*
+ *  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 org.apache.bval.jsr.ApacheValidatorFactory;
+import org.apache.bval.jsr.ConstraintAnnotationAttributes;
+import org.apache.bval.jsr.util.EnumerationConverter;
+import org.apache.bval.jsr.util.IOs;
+import org.apache.bval.util.FieldAccess;
+import org.apache.bval.util.MethodAccess;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.beanutils.ConvertUtils;
+import org.apache.commons.beanutils.Converter;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintValidator;
+import javax.validation.Payload;
+import javax.validation.ValidationException;
+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 java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Uses JAXB to parse constraints.xml based on validation-mapping-1.0.xsd.<br>
+ */
+@SuppressWarnings("restriction")
+public class ValidationMappingParser {
+    //    private static final Log log = LogFactory.getLog(ValidationMappingParser.class);
+    private static final String VALIDATION_MAPPING_XSD = "META-INF/validation-mapping-1.1.xsd";
+
+    private static final Set<ConstraintAnnotationAttributes> RESERVED_PARAMS = Collections.unmodifiableSet(EnumSet.of(
+        ConstraintAnnotationAttributes.GROUPS, ConstraintAnnotationAttributes.MESSAGE,
+        ConstraintAnnotationAttributes.PAYLOAD, ConstraintAnnotationAttributes.VALIDATION_APPLIES_TO));
+
+    private final Set<Class<?>> processedClasses;
+    private final ApacheValidatorFactory factory;
+
+    public ValidationMappingParser(ApacheValidatorFactory factory) {
+        this.factory = factory;
+        this.processedClasses = new HashSet<Class<?>>();
+    }
+
+    /**
+     * Parse files with constraint mappings and collect information in the factory.
+     *  
+     * @param xmlStreams - one or more contraints.xml file streams to parse
+     */
+    public void processMappingConfig(Set<InputStream> xmlStreams) throws ValidationException {
+        for (final InputStream xmlStream : xmlStreams) {
+            ConstraintMappingsType mapping = parseXmlMappings(xmlStream);
+
+            final String defaultPackage = mapping.getDefaultPackage();
+            processConstraintDefinitions(mapping.getConstraintDefinition(), defaultPackage);
+            for (final BeanType bean : mapping.getBean()) {
+                Class<?> beanClass = loadClass(bean.getClazz(), defaultPackage);
+                if (!processedClasses.add(beanClass)) {
+                    // spec: A given class must not be described more than once amongst all
+                    //  the XML mapping descriptors.
+                    throw new ValidationException(
+                          beanClass.getName() + " has already be configured in xml.");
+                }
+
+                boolean ignoreAnnotations = bean.getIgnoreAnnotations() == null ? true : bean.getIgnoreAnnotations();
+                factory.getAnnotationIgnores().setDefaultIgnoreAnnotation(beanClass, ignoreAnnotations);
+                processClassLevel(bean.getClassType(), beanClass, defaultPackage);
+                processConstructorLevel(bean.getConstructor(), beanClass, defaultPackage, ignoreAnnotations);
+                processFieldLevel(bean.getField(), beanClass, defaultPackage, ignoreAnnotations);
+                final Collection<String> potentialMethodName = processPropertyLevel(bean.getGetter(), beanClass, defaultPackage, ignoreAnnotations);
+                processMethodLevel(bean.getMethod(), beanClass, defaultPackage, ignoreAnnotations, potentialMethodName);
+                processedClasses.add(beanClass);
+            }
+        }
+    }
+
+    /** @param in XML stream to parse using the validation-mapping-1.0.xsd */
+    private ConstraintMappingsType parseXmlMappings(final InputStream in) {
+        ConstraintMappingsType mappings;
+        try {
+            final JAXBContext jc = JAXBContext.newInstance(ConstraintMappingsType.class);
+            final Unmarshaller unmarshaller = jc.createUnmarshaller();
+            unmarshaller.setSchema(getSchema());
+            final StreamSource stream = new StreamSource(in);
+            final JAXBElement<ConstraintMappingsType> root = unmarshaller.unmarshal(stream, ConstraintMappingsType.class);
+            mappings = root.getValue();
+        } catch (final JAXBException e) {
+            throw new ValidationException("Failed to parse XML deployment descriptor file.", e);
+        } finally {
+            IOs.closeQuietly(in);
+            try {
+                in.reset(); // can be read several times + we ensured it was re-readable in addMapping()
+            } catch (final IOException e) {
+                // no-op
+            }
+        }
+        return mappings;
+    }
+
+    /** @return validation-mapping-1.0.xsd based schema */
+    private Schema getSchema() {
+        return ValidationParser.getSchema(VALIDATION_MAPPING_XSD);
+    }
+
+    private void processClassLevel(ClassType classType, Class<?> beanClass,
+                                   String defaultPackage) {
+        if (classType == null) {
+            return;
+        }
+
+        // ignore annotation
+        if (classType.getIgnoreAnnotations() != null) {
+            factory.getAnnotationIgnores().setIgnoreAnnotationsOnClass(beanClass, classType.getIgnoreAnnotations());
+        }
+
+        // group sequence
+        Class<?>[] groupSequence =
+              createGroupSequence(classType.getGroupSequence(), defaultPackage);
+        if (groupSequence != null) {
+            factory.addDefaultSequence(beanClass, groupSequence);
+        }
+
+        // constraints
+        for (ConstraintType constraint : classType.getConstraint()) {
+            MetaConstraint<?, ?> metaConstraint =
+                  createConstraint(constraint, beanClass, null, defaultPackage);
+            factory.addMetaConstraint(beanClass, metaConstraint);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private <A extends Annotation, T> MetaConstraint<?, ?> createConstraint(
+            final ConstraintType constraint, final Class<T> beanClass,
+            final Member member, final String defaultPackage) {
+
+        final Class<A> annotationClass = (Class<A>) loadClass(constraint.getAnnotation(), defaultPackage);
+        final AnnotationProxyBuilder<A> annoBuilder = new AnnotationProxyBuilder<A>(annotationClass);
+
+        if (constraint.getMessage() != null) {
+            annoBuilder.setMessage(constraint.getMessage());
+        }
+        annoBuilder.setGroups(getGroups(constraint.getGroups(), defaultPackage));
+        annoBuilder.setPayload(getPayload(constraint.getPayload(), defaultPackage));
+
+        for (final ElementType elementType : constraint.getElement()) {
+            final String name = elementType.getName();
+            checkValidName(name);
+
+            final Class<?> returnType = getAnnotationParameterType(annotationClass, name);
+            final Object elementValue = getElementValue(elementType, returnType, defaultPackage);
+            annoBuilder.putValue(name, elementValue);
+        }
+        return new MetaConstraint<T, A>(beanClass, member, annoBuilder.createAnnotation());
+    }
+
+    private void checkValidName(String name) {
+        for (ConstraintAnnotationAttributes attr : RESERVED_PARAMS) {
+            if (attr.getAttributeName().equals(name)) {
+                throw new ValidationException(name + " is a reserved parameter name.");
+            }
+        }
+    }
+
+    private <A extends Annotation> Class<?> getAnnotationParameterType(
+          final Class<A> annotationClass, final String name) {
+        final Method m = Reflection.INSTANCE.getPublicMethod(annotationClass, name);
+        if (m == null) {
+            throw new ValidationException("Annotation of type " + annotationClass.getName() +
+                  " does not contain a parameter " + name + ".");
+        }
+        return m.getReturnType();
+    }
+
+    private Object getElementValue(ElementType elementType, Class<?> returnType,
+                                   String defaultPackage) {
+        removeEmptyContentElements(elementType);
+
+        boolean isArray = returnType.isArray();
+        if (!isArray) {
+            if (elementType.getContent().size() != 1) {
+                throw new ValidationException(
+                      "Attempt to specify an array where single value is expected.");
+            }
+            return getSingleValue(elementType.getContent().get(0), returnType, defaultPackage);
+        } else {
+            List<Object> values = new ArrayList<Object>();
+            for (Serializable s : elementType.getContent()) {
+                values.add(getSingleValue(s, returnType.getComponentType(), defaultPackage));
+            }
+            return values.toArray(
+                  (Object[]) Array.newInstance(returnType.getComponentType(), values.size()));
+        }
+    }
+
+    private void removeEmptyContentElements(ElementType elementType) {
+        List<Serializable> contentToDelete = new ArrayList<Serializable>();
+        for (Serializable content : elementType.getContent()) {
+            if (content instanceof String && ((String) content).matches("[\\n ].*")) {
+                contentToDelete.add(content);
+            }
+        }
+        elementType.getContent().removeAll(contentToDelete);
+    }
+
+    @SuppressWarnings("unchecked")
+    private Object getSingleValue(Serializable serializable, Class<?> returnType,
+                                  String defaultPackage) {
+
+        Object returnValue;
+        if (serializable instanceof String) {
+            String value = (String) serializable;
+            returnValue = convertToResultType(returnType, value, defaultPackage);
+        } else if (serializable instanceof JAXBElement<?> &&
+              ((JAXBElement<?>) serializable).getDeclaredType()
+                    .equals(String.class)) {
+            JAXBElement<?> elem = (JAXBElement<?>) serializable;
+            String value = (String) elem.getValue();
+            returnValue = convertToResultType(returnType, value, defaultPackage);
+        } else if (serializable instanceof JAXBElement<?> &&
+              ((JAXBElement<?>) serializable).getDeclaredType()
+                    .equals(AnnotationType.class)) {
+            JAXBElement<?> elem = (JAXBElement<?>) serializable;
+            AnnotationType annotationType = (AnnotationType) elem.getValue();
+            try {
+                Class<? extends Annotation> annotationClass = (Class<? extends Annotation>) returnType;
+                returnValue =
+                      createAnnotation(annotationType, annotationClass, defaultPackage);
+            } catch (ClassCastException e) {
+                throw new ValidationException("Unexpected parameter value");
+            }
+        } else {
+            throw new ValidationException("Unexpected parameter value");
+        }
+        return returnValue;
+
+    }
+
+    private Object convertToResultType(Class<?> returnType, String value,
+                                       String defaultPackage) {
+        /**
+         * Class is represented by the fully qualified class name of the class.
+         * spec: Note that if the raw string is unqualified,
+         * default package is taken into account.
+         */
+        if (returnType.equals(Class.class)) {
+            value = toQualifiedClassName(value, defaultPackage);
+        } else if (Byte.class.equals(returnType) || byte.class.equals(returnType)) { // spec mandates it
+            return Byte.parseByte(value);
+        } else if (Short.class.equals(returnType) || short.class.equals(returnType)) {
+            return Short.parseShort(value);
+        } else if (Integer.class.equals(returnType) || int.class.equals(returnType)) {
+            return Integer.parseInt(value);
+        } else if (Long.class.equals(returnType) || long.class.equals(returnType)) {
+            return Long.parseLong(value);
+        } else if (Float.class.equals(returnType) || float.class.equals(returnType)) {
+            return Float.parseFloat(value);
+        } else if (Double.class.equals(returnType) || double.class.equals(returnType)) {
+            return Double.parseDouble(value);
+        } else if (Boolean.class.equals(returnType) || boolean.class.equals(returnType)) {
+            return Boolean.parseBoolean(value);
+        } else if (Character.class.equals(returnType) || char.class.equals(returnType)) {
+            if (value.length() > 1) {
+                throw new IllegalArgumentException("a char has a length of 1");
+            }
+            return value.charAt(0);
+        }
+
+        /* Converter lookup */
+        Converter converter = ConvertUtils.lookup(returnType);
+        if (converter == null && returnType.isEnum()) {
+            converter = EnumerationConverter.getInstance();
+        }
+
+        if (converter != null) {
+            return converter.convert(returnType, value);
+        } else {
+            return converter;
+        }
+    }
+
+    private <A extends Annotation> Annotation createAnnotation(AnnotationType annotationType,
+                                                               Class<A> returnType,
+                                                               String defaultPackage) {
+        AnnotationProxyBuilder<A> metaAnnotation = new AnnotationProxyBuilder<A>(returnType);
+        for (ElementType elementType : annotationType.getElement()) {
+            String name = elementType.getName();
+            Class<?> parameterType = getAnnotationParameterType(returnType, name);
+            Object elementValue = getElementValue(elementType, parameterType, defaultPackage);
+            metaAnnotation.putValue(name, elementValue);
+        }
+        return metaAnnotation.createAnnotation();
+    }
+
+    private Class<?>[] getGroups(GroupsType groupsType, String defaultPackage) {
+        if (groupsType == null) {
+            return new Class[]{};
+        }
+
+        List<Class<?>> groupList = new ArrayList<Class<?>>();
+        for (String groupClass : groupsType.getValue()) {
+            groupList.add(loadClass(groupClass, defaultPackage));
+        }
+        return groupList.toArray(new Class[groupList.size()]);
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private Class<? extends Payload>[] getPayload(PayloadType payloadType,
+                                                  String defaultPackage) {
+        if (payloadType == null) {
+            return new Class[]{};
+        }
+
+        List<Class<? extends Payload>> payloadList = new ArrayList<Class<? extends Payload>>();
+        for (String groupClass : payloadType.getValue()) {
+            Class<?> payload = loadClass(groupClass, defaultPackage);
+            if (!Payload.class.isAssignableFrom(payload)) {
+                throw new ValidationException("Specified payload class " + payload.getName() +
+                      " does not implement javax.validation.Payload");
+            } else {
+                payloadList.add((Class<? extends Payload>) payload);
+            }
+        }
+        return payloadList.toArray(new Class[payloadList.size()]);
+    }
+
+    private Class<?>[] createGroupSequence(GroupSequenceType groupSequenceType,
+                                               String defaultPackage) {
+        if (groupSequenceType != null) {
+            Class<?>[] groupSequence = new Class<?>[groupSequenceType.getValue().size()];
+            int i=0;
+            for (String groupName : groupSequenceType.getValue()) {
+                Class<?> group = loadClass(groupName, defaultPackage);
+                groupSequence[i++] = group;
+            }
+            return groupSequence;
+        } else {
+            return null;
+        }
+    }
+
+    private <A> void processMethodLevel(final List<MethodType> methods, final Class<A> beanClass, final String defaultPackage, final boolean parentIgnoreAnn, final Collection<String> getters) {
+        final List<String> methodNames = new ArrayList<String>();
+        for (final MethodType methodType : methods) {
+            final String methodName = methodType.getName();
+            if (methodNames.contains(methodName) || getters.contains(methodName)) {
+                throw new ValidationException(methodName + " is defined more than once in mapping xml for bean " + beanClass.getName());
+            } else {
+                methodNames.add(methodName);
+            }
+            final Method method = Reflection.INSTANCE.getDeclaredMethod(beanClass, methodName, toTypes(methodType.getParameter(), defaultPackage));
+            if (method == null) {
+                throw new ValidationException(beanClass.getName() + " does not contain the method  " + methodName);
+            }
+
+            // ignore annotations
+            final boolean ignoreMethodAnnotation = methodType.getIgnoreAnnotations() == null ? parentIgnoreAnn : methodType.getIgnoreAnnotations();
+            factory.getAnnotationIgnores().setIgnoreAnnotationsOnMember(method, ignoreMethodAnnotation);
+
+            final boolean ignoreAnn;
+            if (methodType.getIgnoreAnnotations() != null) {
+                ignoreAnn = methodType.getIgnoreAnnotations();
+            } else {
+                ignoreAnn = parentIgnoreAnn;
+            }
+
+            // constraints
+            int i = 0;
+            for (final ParameterType p : methodType.getParameter()) {
+                for (final ConstraintType constraintType : p.getConstraint()) {
+                    final MetaConstraint<?, ?> constraint = createConstraint(constraintType, beanClass, method, defaultPackage);
+                    constraint.setIndex(i);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+                if (p.getValid() != null) {
+                    final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, method, AnnotationProxyBuilder.ValidAnnotation.INSTANCE);
+                    constraint.setIndex(i);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+
+                if (p.getConvertGroup() != null) {
+                    for (final GroupConversionType groupConversion : p.getConvertGroup()) {
+                        final Class<?> from = loadClass(groupConversion.getFrom(), defaultPackage);
+                        final Class<?> to = loadClass(groupConversion.getTo(), defaultPackage);
+                        final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, method, new AnnotationProxyBuilder.ConverGroupAnnotation(from, to));
+                        constraint.setIndex(i);
+                        factory.addMetaConstraint(beanClass, constraint);
+                    }
+                }
+
+                boolean ignoreParametersAnnotation = p.getIgnoreAnnotations() == null ? ignoreMethodAnnotation : p.getIgnoreAnnotations();
+                factory.getAnnotationIgnores().setIgnoreAnnotationsOnParameter(method, i, ignoreParametersAnnotation);
+
+                i++;
+            }
+
+            final ReturnValueType returnValue = methodType.getReturnValue();
+            if (returnValue != null) {
+                for (final ConstraintType constraintType : returnValue.getConstraint()) {
+                    final MetaConstraint<?, ?> constraint = createConstraint(constraintType, beanClass, method, defaultPackage);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+                if (returnValue.getValid() != null) {
+                    final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, method, AnnotationProxyBuilder.ValidAnnotation.INSTANCE);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+
+                if (returnValue.getConvertGroup() != null) {
+                    for (final GroupConversionType groupConversion : returnValue.getConvertGroup()) {
+                        final Class<?> from = loadClass(groupConversion.getFrom(), defaultPackage);
+                        final Class<?> to = loadClass(groupConversion.getTo(), defaultPackage);
+                        final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, method, new AnnotationProxyBuilder.ConverGroupAnnotation(from, to));
+                        factory.addMetaConstraint(beanClass, constraint);
+                    }
+                }
+                factory.getAnnotationIgnores().setIgnoreAnnotationOnReturn(method, returnValue.getIgnoreAnnotations() == null ? ignoreAnn : returnValue.getIgnoreAnnotations());
+            }
+
+            final CrossParameterType crossParameter = methodType.getCrossParameter();
+            if (crossParameter != null) {
+                for (final ConstraintType constraintType : crossParameter.getConstraint()) {
+                    final MetaConstraint<?, ?> constraint = createConstraint(constraintType, beanClass, method, defaultPackage);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+                factory.getAnnotationIgnores().setIgnoreAnnotationOnCrossParameter(method, crossParameter.getIgnoreAnnotations() != null ? crossParameter.getIgnoreAnnotations() : ignoreAnn);
+            }
+        }
+    }
+
+    private <A> void processConstructorLevel(final List<ConstructorType> constructors, final Class<A> beanClass, final String defaultPackage, final boolean parentIgnore) {
+        for (final ConstructorType constructorType : constructors) {
+            final Constructor<?> constructor = Reflection.INSTANCE.getDeclaredConstructor(beanClass, toTypes(constructorType.getParameter(), defaultPackage));
+            if (constructor == null) {
+                throw new ValidationException(beanClass.getName() + " does not contain the constructor  " + constructorType);
+            }
+
+            // ignore annotations
+            final boolean ignoreMethodAnnotation = constructorType.getIgnoreAnnotations() == null ? parentIgnore : constructorType.getIgnoreAnnotations();
+            factory.getAnnotationIgnores().setIgnoreAnnotationsOnMember(constructor, ignoreMethodAnnotation);
+
+            final boolean ignoreAnn;
+            if (constructorType.getIgnoreAnnotations() != null) {
+                ignoreAnn = constructorType.getIgnoreAnnotations();
+            } else {
+                ignoreAnn = parentIgnore;
+            }
+
+            // constraints
+            int i = 0;
+            for (final ParameterType p : constructorType.getParameter()) {
+                for (final ConstraintType constraintType : p.getConstraint()) {
+                    final MetaConstraint<?, ?> constraint = createConstraint(constraintType, beanClass, constructor, defaultPackage);
+                    constraint.setIndex(i);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+                if (p.getValid() != null) {
+                    final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, constructor, AnnotationProxyBuilder.ValidAnnotation.INSTANCE);
+                    constraint.setIndex(i);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+
+                if (p.getConvertGroup() != null) {
+                    for (final GroupConversionType groupConversion : p.getConvertGroup()) {
+                        final Class<?> from = loadClass(groupConversion.getFrom(), defaultPackage);
+                        final Class<?> to = loadClass(groupConversion.getTo(), defaultPackage);
+                        final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, constructor, new AnnotationProxyBuilder.ConverGroupAnnotation(from, to));
+                        constraint.setIndex(i);
+                        factory.addMetaConstraint(beanClass, constraint);
+                    }
+                }
+
+                boolean ignoreParametersAnnotation = p.getIgnoreAnnotations() == null ? ignoreMethodAnnotation : p.getIgnoreAnnotations();
+                if (ignoreParametersAnnotation || (ignoreMethodAnnotation && p.getIgnoreAnnotations() == null)) {
+
+                }
+                factory.getAnnotationIgnores().setIgnoreAnnotationsOnParameter(constructor, i, p.getIgnoreAnnotations() != null ? p.getIgnoreAnnotations() : ignoreAnn);
+
+                i++;
+            }
+
+            final ReturnValueType returnValue = constructorType.getReturnValue();
+            if (returnValue != null) {
+                for (final ConstraintType constraintType : returnValue.getConstraint()) {
+                    final MetaConstraint<?, ?> constraint = createConstraint(constraintType, beanClass, constructor, defaultPackage);
+                    constraint.setIndex(-1);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+                if (returnValue.getValid() != null) {
+                    final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, constructor, AnnotationProxyBuilder.ValidAnnotation.INSTANCE);
+                    constraint.setIndex(-1);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+
+                if (returnValue.getConvertGroup() != null) {
+                    for (final GroupConversionType groupConversion : returnValue.getConvertGroup()) {
+                        final Class<?> from = loadClass(groupConversion.getFrom(), defaultPackage);
+                        final Class<?> to = loadClass(groupConversion.getTo(), defaultPackage);
+                        final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, constructor, new AnnotationProxyBuilder.ConverGroupAnnotation(from, to));
+                        constraint.setIndex(-1);
+                        factory.addMetaConstraint(beanClass, constraint);
+                    }
+                }
+                factory.getAnnotationIgnores().setIgnoreAnnotationOnReturn(constructor, returnValue.getIgnoreAnnotations() != null ? returnValue.getIgnoreAnnotations() : ignoreAnn);
+            }
+
+            final CrossParameterType crossParameter = constructorType.getCrossParameter();
+            if (crossParameter != null) {
+                for (final ConstraintType constraintType : crossParameter.getConstraint()) {
+                    final MetaConstraint<?, ?> constraint = createConstraint(constraintType, beanClass, constructor, defaultPackage);
+                    factory.addMetaConstraint(beanClass, constraint);
+                }
+                factory.getAnnotationIgnores().setIgnoreAnnotationOnCrossParameter(constructor, crossParameter.getIgnoreAnnotations() != null ? crossParameter.getIgnoreAnnotations() : ignoreAnn);
+            }
+        }
+    }
+
+    private Class<?>[] toTypes(final List<ParameterType> parameter, final String defaultPck) {
+        if (parameter == null) {
+            return null;
+        }
+        final Class<?>[] types = new Class<?>[parameter.size()];
+        int i = 0;
+        for (final ParameterType type : parameter) {
+            types[i++] = loadClass(type.getType(), defaultPck);
+        }
+        return types;
+    }
+
+    private <A> void processFieldLevel(List<FieldType> fields, Class<A> beanClass,
+                                       String defaultPackage, boolean ignoreAnnotations) {
+        final List<String> fieldNames = new ArrayList<String>();
+        for (FieldType fieldType : fields) {
+            String fieldName = fieldType.getName();
+            if (fieldNames.contains(fieldName)) {
+                throw new ValidationException(fieldName +
+                      " is defined more than once in mapping xml for bean " +
+                      beanClass.getName());
+            } else {
+                fieldNames.add(fieldName);
+            }
+            final Field field = Reflection.INSTANCE.getDeclaredField(beanClass, fieldName);
+            if (field == null) {
+                throw new ValidationException(
+                      beanClass.getName() + " does not contain the fieldType  " + fieldName);
+            }
+
+            // ignore annotations
+            final boolean ignoreFieldAnnotation = fieldType.getIgnoreAnnotations() == null ? ignoreAnnotations : fieldType.getIgnoreAnnotations();
+            factory.getAnnotationIgnores().setIgnoreAnnotationsOnMember(field, ignoreFieldAnnotation);
+
+            // valid
+            if (fieldType.getValid() != null) {
+                factory.addValid(beanClass, new FieldAccess(field));
+            }
+
+            for (final GroupConversionType conversion : fieldType.getConvertGroup()) {
+                final Class<?> from = loadClass(conversion.getFrom(), defaultPackage);
+                final Class<?> to = loadClass(conversion.getTo(), defaultPackage);
+                final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, field, new AnnotationProxyBuilder.ConverGroupAnnotation(from, to));
+                factory.addMetaConstraint(beanClass, constraint);
+            }
+
+            // constraints
+            for (ConstraintType constraintType : fieldType.getConstraint()) {
+                MetaConstraint<?, ?> constraint =
+                      createConstraint(constraintType, beanClass, field, defaultPackage);
+                factory.addMetaConstraint(beanClass, constraint);
+            }
+        }
+    }
+
+    private <A> Collection<String> processPropertyLevel(List<GetterType> getters, Class<A> beanClass,
+                                      String defaultPackage, boolean ignoreAnnotatino) {
+        List<String> getterNames = new ArrayList<String>();
+        for (GetterType getterType : getters) {
+            final String getterName = getterType.getName();
+            final String methodName = "get" + StringUtils.capitalize(getterType.getName());
+            if (getterNames.contains(methodName)) {
+                throw new ValidationException(getterName +
+                      " is defined more than once in mapping xml for bean " +
+                      beanClass.getName());
+            } else {
+                getterNames.add(methodName);
+            }
+            final Method method = getGetter(beanClass, getterName);
+            if (method == null) {
+                throw new ValidationException(
+                      beanClass.getName() + " does not contain the property  " + getterName);
+            }
+
+            // ignore annotations
+            final boolean ignoreGetterAnnotation = getterType.getIgnoreAnnotations() == null ? ignoreAnnotatino : getterType.getIgnoreAnnotations();
+            factory.getAnnotationIgnores().setIgnoreAnnotationsOnMember(method, ignoreGetterAnnotation);
+
+            // valid
+            if (getterType.getValid() != null) {
+                factory.addValid(beanClass, new MethodAccess(getterName, method));
+            }
+
+            // ConvertGroup
+            for (final GroupConversionType conversion : getterType.getConvertGroup()) {
+                final Class<?> from = loadClass(conversion.getFrom(), defaultPackage);
+                final Class<?> to = loadClass(conversion.getTo(), defaultPackage);
+                final MetaConstraint<?, ?> constraint = new MetaConstraint<A, Annotation>(beanClass, method, new AnnotationProxyBuilder.ConverGroupAnnotation(from, to));
+                factory.addMetaConstraint(beanClass, constraint);
+            }
+
+            // constraints
+            for (ConstraintType constraintType : getterType.getConstraint()) {
+                MetaConstraint<?, ?> metaConstraint =
+                      createConstraint(constraintType, beanClass, method, defaultPackage);
+                factory.addMetaConstraint(beanClass, metaConstraint);
+            }
+        }
+
+        return getterNames;
+    }
+
+    @SuppressWarnings("unchecked")
+    private void processConstraintDefinitions(
+          List<ConstraintDefinitionType> constraintDefinitionList, String defaultPackage) {
+        for (ConstraintDefinitionType constraintDefinition : constraintDefinitionList) {
+            String annotationClassName = constraintDefinition.getAnnotation();
+
+            Class<?> clazz = loadClass(annotationClassName, defaultPackage);
+            if (!clazz.isAnnotation()) {
+                throw new ValidationException(annotationClassName + " is not an annotation");
+            }
+            Class<? extends Annotation> annotationClass = (Class<? extends Annotation>) clazz;
+
+            ValidatedByType validatedByType = constraintDefinition.getValidatedBy();
+            List<Class<? extends ConstraintValidator<?, ?>>> classes =
+                new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
+            /*
+             If include-existing-validator is set to false,
+             ConstraintValidator defined on the constraint annotation are ignored.
+              */
+            if (validatedByType.getIncludeExistingValidators() != null &&
+                  validatedByType.getIncludeExistingValidators()) {
+                /*
+                 If set to true, the list of ConstraintValidators described in XML
+                 are concatenated to the list of ConstraintValidator described on the
+                 annotation to form a new array of ConstraintValidator evaluated.
+                 */
+                classes.addAll(findConstraintValidatorClasses(annotationClass));
+            }
+            for (String validatorClassName : validatedByType.getValue()) {
+                Class<? extends ConstraintValidator<?, ?>> validatorClass;
+                validatorClass = (Class<? extends ConstraintValidator<?, ?>>)
+                      loadClass(validatorClassName);
+
+
+                if (!ConstraintValidator.class.isAssignableFrom(validatorClass)) {
+                    throw new ValidationException(
+                          validatorClass + " is not a constraint validator class");
+                }
+
+                /*
+                Annotation based ConstraintValidator come before XML based
+                ConstraintValidator in the array. The new list is returned
+                by ConstraintDescriptor.getConstraintValidatorClasses().
+                 */
+                if (!classes.contains(validatorClass)) classes.add(validatorClass);
+            }
+            if (factory.getConstraintsCache().containsConstraintValidator(annotationClass)) {
+                throw new ValidationException("Constraint validator for " +
+                      annotationClass.getName() + " already configured.");
+            } else {
+                factory.getConstraintsCache().putConstraintValidator(annotationClass,
+                      classes.toArray(new Class[classes.size()]));
+            }
+        }
+    }
+
+    private List<Class<? extends ConstraintValidator<? extends Annotation, ?>>> findConstraintValidatorClasses(
+          Class<? extends Annotation> annotationType) {
+        List<Class<? extends ConstraintValidator<? extends Annotation, ?>>> classes =
+              new ArrayList<Class<? extends ConstraintValidator<? extends Annotation, ?>>>();
+
+        Class<? extends ConstraintValidator<?, ?>>[] validator =
+              factory.getDefaultConstraints().getValidatorClasses(annotationType);
+        if (validator != null) {
+            classes
+                  .addAll(Arrays.asList(validator));
+        } else {
+            Class<? extends ConstraintValidator<?, ?>>[] validatedBy = annotationType
+                  .getAnnotation(Constraint.class)
+                  .validatedBy();
+            classes.addAll(Arrays.asList(validatedBy));
+        }
+        return classes;
+    }
+
+    private Class<?> loadClass(String className, String defaultPackage) {
+        return loadClass(toQualifiedClassName(className, defaultPackage));
+    }
+
+    private String toQualifiedClassName(String className, String defaultPackage) {
+        if (!isQualifiedClass(className)) {
+            if (className.startsWith("[L") && className.endsWith(";")) {
+                className = "[L" + defaultPackage + "." + className.substring(2);
+            } else {
+                className = defaultPackage + "." + className;
+            }
+        }
+        return className;
+    }
+
+    private boolean isQualifiedClass(String clazz) {
+        return clazz.contains(".");
+    }
+
+    private static Method getGetter(final Class<?> clazz, final String propertyName) {
+        if (System.getSecurityManager() == null) {
+            return doGetGetter(propertyName, clazz);
+        }
+        return AccessController.doPrivileged(new PrivilegedAction<Method>() {
+            public Method run() {
+                return doGetGetter(propertyName, clazz);
+            }
+        });
+
+    }
+
+    private static Method doGetGetter(String propertyName, Class<?> clazz) {
+        try {
+            final String p = StringUtils.capitalize(propertyName);
+            try {
+                return clazz.getMethod("get" + p);
+            } catch (NoSuchMethodException e) {
+                return clazz.getMethod("is" + p);
+            }
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+
+    private Class<?> loadClass(final String className) {
+        ClassLoader loader = Reflection.INSTANCE.getClassLoader(ValidationMappingParser.class);
+        if (loader == null)
+            loader = getClass().getClassLoader();
+
+        try {
+            return Class.forName(className, true, loader);
+        } catch (ClassNotFoundException ex) {
+            throw new ValidationException("Unable to load class: " + className, ex);
+        }
+    }
+
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/xml/ValidationParser.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,412 @@
+/*
+ * 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 org.apache.bval.cdi.BValExtension;
+import org.apache.bval.jsr.BootstrapConfigurationImpl;
+import org.apache.bval.jsr.ConfigurationImpl;
+import org.apache.bval.jsr.util.IOs;
+import org.apache.bval.util.reflection.Reflection;
+import org.xml.sax.SAXException;
+
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.MessageInterpolator;
+import javax.validation.ParameterNameProvider;
+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 java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Description: uses jaxb to parse validation.xml<br/>
+ */
+@SuppressWarnings("restriction")
+public class ValidationParser implements Closeable {
+    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 Collection<BValExtension.Releasable> releasables = new CopyOnWriteArrayList<BValExtension.Releasable>();
+
+    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;
+    }
+
+    public static String getValidationXmlFile(String file) {
+        if (file == null) {
+            return DEFAULT_VALIDATION_XML_FILE;
+        }
+        return file;
+    }
+
+    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.getExecutableValidation() == null) {
+                final ExecutableValidationType value = new ExecutableValidationType();
+                value.setEnabled(true);
+
+                final DefaultValidatedExecutableTypesType defaultValidatedExecutableTypes = new DefaultValidatedExecutableTypesType();
+                value.setDefaultValidatedExecutableTypes(defaultValidatedExecutableTypes);
+                defaultValidatedExecutableTypes.getExecutableType().add(ExecutableType.CONSTRUCTORS);
+                defaultValidatedExecutableTypes.getExecutableType().add(ExecutableType.NON_GETTER_METHODS);
+
+                parser.xmlConfig.setExecutableValidation(value);
+            }
+
+            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()));
+            return parser;
+        } 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);
+        }
+
+        return parser;
+    }
+
+    private static Map<String, String> toMap(final List<PropertyType> property) {
+        final Map<String, String> map = new HashMap<String, String>();
+        if (property != null) {
+            for (final PropertyType p : property) {
+                map.put(p.getName(), p.getValue());
+            }
+        }
+        return map;
+    }
+
+    private static ValidationConfigType parseXmlConfig(final String validationXmlFile) {
+        InputStream inputStream = null;
+        try {
+            inputStream = getInputStream(getValidationXmlFile(validationXmlFile));
+            if (inputStream == null) {
+            	log.log(Level.FINEST, String.format("No %s found. Using annotation based configuration only.", validationXmlFile));
+                return null;
+            }
+
+            log.log(Level.FINEST, String.format("%s found.", validationXmlFile));
+
+            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) {
+            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.INSTANCE.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.INSTANCE.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;
+        }
+    }
+
+    public static void applySimpleConfig(ValidationConfigType xmlConfig, ConfigurationImpl targetConfig) {
+        applyExecutableValidation(xmlConfig, targetConfig);
+    }
+
+    private static void applyProperties(ValidationConfigType xmlConfig, ConfigurationImpl target) {
+        for (final PropertyType property : xmlConfig.getProperty()) {
+            target.addProperty(property.getName(), property.getValue());
+        }
+    }
+
+    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());
+        }
+
+        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
+            executableTypes.clear();
+        }
+
+        targetConfig.setExecutableValidation(executableTypes);
+    }
+
+    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<? extends ParameterNameProvider> clazz = Class.class.cast(loadClass(parameterNameProvider));
+                targetConfig.parameterNameProvider(newInstance(clazz));
+                log.log(Level.INFO, String.format("Using %s as validation provider.", parameterNameProvider));
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void applyProviderClass(ValidationConfigType xmlConfig, ConfigurationImpl target) {
+        String providerClassName = xmlConfig.getDefaultProvider();
+        if (providerClassName != null) {
+            Class<? extends ValidationProvider<?>> clazz =
+                (Class<? extends ValidationProvider<?>>) loadClass(providerClassName);
+            target.setProviderClass(clazz);
+            log.log(Level.INFO, String.format("Using %s as validation provider.", providerClassName));
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    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.messageInterpolator(newInstance(clazz));
+                log.log(Level.INFO, String.format("Using %s as message interpolator.", messageInterpolatorClass));
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void applyTraversableResolver(ValidationConfigType xmlConfig,
+                                          ConfigurationImpl target) {
+        String traversableResolverClass = xmlConfig.getTraversableResolver();
+        if (target.getTraversableResolver() == target.getDefaultTraversableResolver()) { // ref ==
+            if (traversableResolverClass != null) {
+                Class<TraversableResolver> clazz = (Class<TraversableResolver>)
+                        loadClass(traversableResolverClass);
+                target.traversableResolver(newInstance(clazz));
+                log.log(Level.INFO, String.format("Using %s as traversable resolver.", traversableResolverClass));
+            }
+        }
+    }
+
+    private <T> T newInstance(final Class<T> cls) {
+        if (System.getSecurityManager() == null) {
+            return doNewInstance(cls);
+        }
+        return AccessController.doPrivileged(new PrivilegedAction<T>() {
+            public T run() {
+                return doNewInstance(cls);
+            }
+        });
+    }
+
+    private <T> T doNewInstance(final Class<T> cls) {
+        try {
+            try {
+                final BValExtension.Releasable<T> releasable = BValExtension.inject(cls);
+                releasables.add(releasable);
+                return releasable.getInstance();
+            } catch (final Exception e) {
+                return cls.newInstance();
+            } catch (final NoClassDefFoundError error) {
+                return cls.newInstance();
+            }
+        } catch (final Exception ex) {
+            exceptions.add(new ValidationException("Cannot instantiate : " + cls, ex));
+            return null; // ensure BootstrapConfiguration can be read even if class can't be instantiated
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void applyConstraintFactory(ValidationConfigType xmlConfig,
+                                        ConfigurationImpl target) {
+        String constraintFactoryClass = xmlConfig.getConstraintValidatorFactory();
+        if (target.getConstraintValidatorFactory() == target.getDefaultConstraintValidatorFactory()) { // ref ==
+            if (constraintFactoryClass != null) {
+                Class<ConstraintValidatorFactory> clazz = (Class<ConstraintValidatorFactory>)
+                        loadClass(constraintFactoryClass);
+                target.constraintValidatorFactory(newInstance(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);
+        }
+    }
+
+    private Class<?> loadClass(final String className) {
+        final ClassLoader loader = Reflection.INSTANCE.getClassLoader(ValidationParser.class);
+        try {
+            return Class.forName(className, true, loader);
+        } catch (final ClassNotFoundException ex) {
+            // TCK check BootstrapConfig is present in all cases
+            // so throw next exception later
+            exceptions.add(new ValidationException("Unable to load class: " + className, ex));
+            return null;
+        }
+    }
+
+    public void ensureValidatorFactoryCanBeBuilt() {
+        if (!exceptions.isEmpty()) {
+            throw  exceptions.iterator().next();
+        }
+    }
+
+    public void close() throws IOException {
+        for (final BValExtension.Releasable<?> releasable : releasables) {
+            releasable.release();
+        }
+        releasables.clear();
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/beans.xml
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/beans.xml?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/beans.xml (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/beans.xml Mon Aug 26 13:59:15 2013
@@ -0,0 +1,17 @@
+<?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.
+-->
+<beans />

Added: bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Mon Aug 26 13:59:15 2013
@@ -0,0 +1 @@
+org.apache.bval.cdi.BValExtension
\ No newline at end of file

Added: bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/META-INF/services/javax.validation.spi.ValidationProvider Mon Aug 26 13:59:15 2013
@@ -0,0 +1,17 @@
+# 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.
+org.apache.bval.jsr.ApacheValidationProvider

Added: bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/DefaultConstraints.properties
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/DefaultConstraints.properties?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/DefaultConstraints.properties (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/DefaultConstraints.properties Mon Aug 26 13:59:15 2013
@@ -0,0 +1,53 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# configuration for mapping of javax.validation.constraints to ConstraintValidator implementations
+# the annotations from the JSR303 validation-api are mentioned here, but you could
+# also extend the configuration to get a default implementation for other constraint-annotations.
+# format: key=constraint-annotation-class value=constraint-validator-class (multiple classes: comma-separated)
+
+javax.validation.constraints.AssertFalse=org.apache.bval.constraints.AssertFalseValidator
+javax.validation.constraints.AssertTrue=org.apache.bval.constraints.AssertTrueValidator
+javax.validation.constraints.DecimalMax=org.apache.bval.constraints.DecimalMaxValidatorForNumber,\
+  org.apache.bval.constraints.DecimalMaxValidatorForString
+javax.validation.constraints.DecimalMin=org.apache.bval.constraints.DecimalMinValidatorForNumber,\
+  org.apache.bval.constraints.DecimalMinValidatorForString
+javax.validation.constraints.Digits=org.apache.bval.constraints.DigitsValidatorForNumber,\
+  org.apache.bval.constraints.DigitsValidatorForString
+javax.validation.constraints.Future=org.apache.bval.constraints.FutureValidatorForDate,\
+  org.apache.bval.constraints.FutureValidatorForCalendar
+javax.validation.constraints.Max=org.apache.bval.constraints.MaxValidatorForNumber,\
+  org.apache.bval.constraints.MaxValidatorForString
+javax.validation.constraints.Min=org.apache.bval.constraints.MinValidatorForNumber,\
+  org.apache.bval.constraints.MinValidatorForString
+javax.validation.constraints.NotNull=org.apache.bval.constraints.NotNullValidator
+javax.validation.constraints.Null=org.apache.bval.constraints.NullValidator
+javax.validation.constraints.Past=org.apache.bval.constraints.PastValidatorForDate,\
+  org.apache.bval.constraints.PastValidatorForCalendar
+javax.validation.constraints.Size=org.apache.bval.constraints.SizeValidatorForCharSequence,\
+  org.apache.bval.constraints.SizeValidatorForMap,\
+  org.apache.bval.constraints.SizeValidatorForCollection,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfBoolean,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfByte,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfChar,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfDouble,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfFloat,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfInt,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfLong,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfObject,\
+  org.apache.bval.constraints.SizeValidatorForArrayOfShort
+javax.validation.constraints.Pattern=org.apache.bval.constraints.PatternValidator

Added: bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages.properties
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages.properties?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages.properties (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages.properties Mon Aug 26 13:59:15 2013
@@ -0,0 +1,37 @@
+# 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.
+
+# The properties listed below are resolved by the default message resolver.
+
+# standard
+javax.validation.constraints.Null.message=must be null
+javax.validation.constraints.NotNull.message=may not be null
+javax.validation.constraints.AssertTrue.message=must be true
+javax.validation.constraints.AssertFalse.message=must be false
+javax.validation.constraints.Min.message=must be greater than or equal to {value}
+javax.validation.constraints.Max.message=must be less than or equal to {value}
+javax.validation.constraints.Size.message=size must be between {min} and {max}
+javax.validation.constraints.Digits.message=numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected)
+javax.validation.constraints.Past.message=must be a past date
+javax.validation.constraints.Future.message=must be a future date
+javax.validation.constraints.Pattern.message=must match the following regular expression: {regexp}
+javax.validation.constraints.DecimalMax.message=must be less than or equal to {value}
+javax.validation.constraints.DecimalMin.message=must be greater than or equal to {value}
+
+# additional built-ins
+org.apache.bval.constraints.NotEmpty.message=may not be empty
+org.apache.bval.constraints.Email.message=not a well-formed email address

Added: bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_de.properties
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_de.properties?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_de.properties (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_de.properties Mon Aug 26 13:59:15 2013
@@ -0,0 +1,37 @@
+# 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.
+
+# The properties listed below are resolved by the default message resolver.
+
+# standard
+javax.validation.constraints.Null.message=muss "null" sein
+javax.validation.constraints.NotNull.message=darf nicht "null" sein
+javax.validation.constraints.AssertTrue.message=muss "true" sein
+javax.validation.constraints.AssertFalse.message=muss "false" sein
+javax.validation.constraints.Min.message=muss gr\u00F6\u00DFer oder gleich {value} sein
+javax.validation.constraints.Max.message=muss kleiner oder gleich {value} sein
+javax.validation.constraints.Size.message=Gr\u00F6\u00DFe muss zwischen {min} und {max} liegen
+javax.validation.constraints.Digits.message=numerischer Wert au\u00DFerhalb des G\u00FCltigkeitsbereiches (erwarte: <{integer} digits>.<{fraction} digits>)
+javax.validation.constraints.Past.message=muss Datum in der Vergangenheit sein
+javax.validation.constraints.Future.message=muss Datum in der Zukunft sein
+javax.validation.constraints.Pattern.message=Muss mit regul\u00E4rem Ausdruck \u00FCbereinstimmen: {regexp}
+javax.validation.constraints.DecimalMax.message=muss kleiner oder gleich {value} sein
+javax.validation.constraints.DecimalMin.message=muss gr\u00F6\u00DFer oder gleich {value} sein
+
+# additional built-ins
+org.apache.bval.constraints.NotEmpty.message=darf nicht leer sein
+org.apache.bval.constraints.Email.message=muss g\u00FCltiges Format einer EMail-Adresse sein

Added: bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_en.properties
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_en.properties?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_en.properties (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_en.properties Mon Aug 26 13:59:15 2013
@@ -0,0 +1,20 @@
+# 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.
+
+# intentionally empty, because english messages are located in the default bundle.
+# this file ensures, that a lookup with an english locale uses the default bundle and not the
+# bundle of the default locale, which is platform specific
\ No newline at end of file

Added: bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_es.properties
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_es.properties?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_es.properties (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_es.properties Mon Aug 26 13:59:15 2013
@@ -0,0 +1,37 @@
+# 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.
+
+# The properties listed below are resolved by the default message resolver.
+
+# standard
+javax.validation.constraints.Null.message=tiene que ser null
+javax.validation.constraints.NotNull.message=no puede ser null
+javax.validation.constraints.AssertTrue.message=tiene que ser true
+javax.validation.constraints.AssertFalse.message=tiene que ser false
+javax.validation.constraints.Min.message=tiene que ser menor o igual que {value}
+javax.validation.constraints.Max.message=tiene que ser mayor o igual que {value}
+javax.validation.constraints.Size.message=el tamaño tiene que estar comprendido entre {min} y {max}
+javax.validation.constraints.Digits.message=valor numérico fuera de los límites (se espera <{integer} cifras>.<{fraction} cifras>)
+javax.validation.constraints.Past.message=tiene que ser una fecha en el pasado
+javax.validation.constraints.Future.message=tiene que ser una fecha en el futuro
+javax.validation.constraints.Pattern.message=tiene que corresponder a la expresión regular "{regexp}"
+javax.validation.constraints.DecimalMax.message=tiene que ser mayor o igual que {value}
+javax.validation.constraints.DecimalMin.message=tiene que ser menor o igual que {value}
+
+# additional built-ins
+org.apache.bval.constraints.NotEmpty.message=no puede ser vacio
+org.apache.bval.constraints.Email.message=tiene que ser un correo email bien formado

Added: bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_it.properties
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_it.properties?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_it.properties (added)
+++ bval/branches/bval-11/bval-jsr/src/main/resources/org/apache/bval/jsr/ValidationMessages_it.properties Mon Aug 26 13:59:15 2013
@@ -0,0 +1,37 @@
+# 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.
+
+# The properties listed below are resolved by the default message resolver.
+
+# standard
+javax.validation.constraints.Null.message=deve essere null
+javax.validation.constraints.NotNull.message=non pu\u00F2 essere null
+javax.validation.constraints.AssertTrue.message=deve essere true
+javax.validation.constraints.AssertFalse.message=deve essere false
+javax.validation.constraints.Min.message=deve essere minore o uguale di {value}
+javax.validation.constraints.Max.message=deve essere maggiore o uguale di {value}
+javax.validation.constraints.Size.message=le dimensioni devono essere tra {min} e {max}
+javax.validation.constraints.Digits.message=valore numerico fuori dai limiti (atteso <{integer} cifre>.<{fraction} cifre>)
+javax.validation.constraints.Past.message=deve essere una data nel passato
+javax.validation.constraints.Future.message=deve essere una data futura
+javax.validation.constraints.Pattern.message=deve corrispondere all'espressione regolare "{regexp}"
+javax.validation.constraints.DecimalMax.message=deve essere maggiore o uguale di {value}
+javax.validation.constraints.DecimalMin.message=deve essere minore o uguale di {value}
+
+# additional built-ins
+org.apache.bval.constraints.NotEmpty.message=non pu\u00F2 essere vuoto
+org.apache.bval.constraints.Email.message=non \u00E8 un indirizzo email ben formato

Added: bval/branches/bval-11/bval-jsr/src/main/xjb/binding-customization.xjb
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/xjb/binding-customization.xjb?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/xjb/binding-customization.xjb (added)
+++ bval/branches/bval-11/bval-jsr/src/main/xjb/binding-customization.xjb Mon Aug 26 13:59:15 2013
@@ -0,0 +1,38 @@
+<?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.
+-->
+<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:globalBindings>
+      <xjc:javaType name="java.lang.String" xmlType="xs:string"
+                    adapter="javax.xml.bind.annotation.adapters.CollapsedStringAdapter"/>
+    </jxb:globalBindings>
+
+    <jxb:bindings node="//xs:complexType[@name='beanType']/xs:sequence[1]/xs:element[1]">
+      <jxb:property name="classType"/>
+    </jxb:bindings>
+  </jxb:bindings>
+  <jxb:bindings schemaLocation="../xsd/validation-configuration-1.1.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"/>
+    </jxb:bindings>
+  </jxb:bindings>
+</jxb:bindings>

Added: bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.0.xsd
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.0.xsd?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.0.xsd (added)
+++ bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.0.xsd Mon Aug 26 13:59:15 2013
@@ -0,0 +1,45 @@
+<?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://jboss.org/xml/ns/javax/validation/configuration"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           version="1.0">
+    <xs:element name="validation-config" type="config:validation-configType"
+                xmlns:config="http://jboss.org/xml/ns/javax/validation/configuration"/>
+    <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="constraint-mapping" maxOccurs="unbounded" minOccurs="0"/>
+            <xs:element type="config:propertyType" name="property" maxOccurs="unbounded" minOccurs="0"
+                        xmlns:config="http://jboss.org/xml/ns/javax/validation/configuration"/>
+        </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:schema>

Added: bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.1.xsd
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.1.xsd?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.1.xsd (added)
+++ bval/branches/bval-11/bval-jsr/src/main/xsd/validation-configuration-1.1.xsd Mon Aug 26 13:59:15 2013
@@ -0,0 +1,74 @@
+<?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://jboss.org/xml/ns/javax/validation/configuration"
+           xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:config="http://jboss.org/xml/ns/javax/validation/configuration"
+           version="1.1">
+  <xs:element name="validation-config" type="config:validation-configType"
+              xmlns:config="http://jboss.org/xml/ns/javax/validation/configuration"/>
+  <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="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="1.1" /> <!-- 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>