bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject svn commit: r1517540 [6/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/j...
Date Mon, 26 Aug 2013 13:59:20 GMT
Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr;
+
+import javax.validation.ConstraintValidator;
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Description: hold the relationship annotation->validatedBy[] ConstraintValidator classes
+ * that are already parsed in a cache.<br/>
+ */
+public class ConstraintCached {
+    private final Map<Class<? extends Annotation>, Class<? extends ConstraintValidator<?, ?>>[]> classes =
+          new HashMap<Class<? extends Annotation>, Class<? extends ConstraintValidator<?,?>>[]>();
+
+    /**
+     * Record the set of validator classes for a given constraint annotation.
+     * @param annotationClass
+     * @param definitionClasses
+     */
+    public <A extends Annotation> void putConstraintValidator(Class<A> annotationClass,
+                                                              Class<? extends ConstraintValidator<A, ?>>[] definitionClasses) {
+        classes.put(annotationClass, definitionClasses);
+    }
+
+    /**
+     * Learn whether we have cached the validator classes for the requested constraint annotation.
+     * @param annotationClass to look up
+     * @return boolean
+     */
+    public boolean containsConstraintValidator(Class<? extends Annotation> annotationClass) {
+        return classes.containsKey(annotationClass);
+    }
+
+    /**
+     * Get the cached validator classes for the requested constraint annotation.
+     * @param annotationClass to look up
+     * @return array of {@link ConstraintValidator} implementation types
+     */
+    @SuppressWarnings("unchecked")
+    public <A extends Annotation> Class<? extends ConstraintValidator<A, ?>>[] getConstraintValidators(
+          Class<A> annotationClass) {
+        return (Class<? extends ConstraintValidator<A, ?>>[]) classes.get(annotationClass);
+    }
+
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr;
+
+import javax.validation.ConstraintValidator;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Description: Provides access to the default constraints/validator implementation classes built into the framework.
+ * These are configured in DefaultConstraints.properties.<br/>
+ */
+public class ConstraintDefaults {
+    private static final Logger log = Logger.getLogger(ConstraintDefaults.class.getName());
+    private static final String DEFAULT_CONSTRAINTS =
+          "org/apache/bval/jsr/DefaultConstraints.properties";
+    
+    /**
+     * The default constraint data stored herein.
+     */
+    protected Map<String, Class<? extends ConstraintValidator<?, ?>>[]> defaultConstraints;
+
+    /**
+     * Create a new ConstraintDefaults instance.
+     */
+    public ConstraintDefaults() {
+        defaultConstraints = loadDefaultConstraints(DEFAULT_CONSTRAINTS);
+    }
+
+    /**
+     * Get the default constraint data.
+     * @return String-keyed map
+     */
+    public Map<String, Class<? extends ConstraintValidator<?, ?>>[]> getDefaultConstraints() {
+        return defaultConstraints;
+    }
+
+    /**
+     * Get the default validator implementation types for the specified constraint annotation type. 
+     * @param annotationType the annotation type
+     * @return array of {@link ConstraintValidator} implementation classes
+     */
+    @SuppressWarnings("unchecked")
+    public <A extends Annotation> Class<? extends ConstraintValidator<A, ?>>[] getValidatorClasses(
+          Class<A> annotationType) {
+        return (Class<? extends ConstraintValidator<A, ?>>[]) getDefaultConstraints().get(annotationType.getName());
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, Class<? extends ConstraintValidator<?, ?>>[]> loadDefaultConstraints(String resource) {
+        Properties constraintProperties = new Properties();
+        final ClassLoader classloader = getClassLoader();
+        InputStream stream = classloader.getResourceAsStream(resource);
+        if (stream != null) {
+            try {
+                constraintProperties.load(stream);
+            } catch (IOException e) {
+                log.log(Level.SEVERE, String.format("Cannot load %s", resource), e);
+            }
+        } else {
+            log.log(Level.WARNING, String.format("Cannot find %s", resource));
+        }
+
+        final Map<String, Class<? extends ConstraintValidator<?, ?>>[]> loadedConstraints = new HashMap<String, Class<? extends ConstraintValidator<?,?>>[]>();
+        for (final Map.Entry<Object, Object> entry : constraintProperties.entrySet()) {
+
+            final StringTokenizer tokens = new StringTokenizer((String) entry.getValue(), ", ");
+            final LinkedList<Class<?>> classes = new LinkedList<Class<?>>();
+            while (tokens.hasMoreTokens()) {
+                final String eachClassName = tokens.nextToken();
+
+                Class<?> constraintValidatorClass;
+                if (System.getSecurityManager() == null) {
+                    try {
+                        constraintValidatorClass = Class.forName(eachClassName, true, classloader);
+                    } catch (final ClassNotFoundException e) {
+                        log.log(Level.SEVERE, String.format("Cannot find class %s", eachClassName), e);
+                        constraintValidatorClass = null;
+                    }
+                } else {
+                    constraintValidatorClass = AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+                          public Class<?> run() {
+                              try {
+                                  return Class.forName(eachClassName, true, classloader);
+                              } catch (final ClassNotFoundException e) {
+                                  log.log(Level.SEVERE, String.format("Cannot find class %s", eachClassName), e);
+                                  return null;
+                              }
+                          }
+                      });
+                }
+
+                if (constraintValidatorClass != null) {
+                    classes.add(constraintValidatorClass);
+                }
+
+            }
+
+            loadedConstraints.put((String) entry.getKey(), classes.toArray(new Class[classes.size()]));
+        }
+        return loadedConstraints;
+    }
+
+    private ClassLoader getClassLoader() {
+        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+        if (classloader == null) classloader = getClass().getClassLoader();
+        return classloader;
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr;
+
+import javax.validation.ConstraintTarget;
+import javax.validation.Payload;
+import javax.validation.metadata.ConstraintDescriptor;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Description: immutable, serializable implementation of ConstraintDescriptor
+ * interface of JSR303<br>
+ * User: roman.stumm<br>
+ * Date: 22.04.2010<br>
+ * Time: 10:21:23<br>
+ */
+public class ConstraintDescriptorImpl<T extends Annotation> implements ConstraintDescriptor<T>, Serializable {
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    private final T annotation;
+    private final Set<Class<?>> groups;
+    private final Set<Class<? extends javax.validation.Payload>> payload;
+    private final List<java.lang.Class<? extends javax.validation.ConstraintValidator<T, ?>>> constraintValidatorClasses;
+    private final Map<String, Object> attributes;
+    private final Set<ConstraintDescriptor<?>> composingConstraints;
+    private final boolean reportAsSingleViolation;
+    private final ConstraintTarget validationAppliesTo;
+    private final String template;
+    private final int hashCode;
+
+    /**
+     * Create a new ConstraintDescriptorImpl instance.
+     * 
+     * @param descriptor
+     */
+    public ConstraintDescriptorImpl(final ConstraintDescriptor<T> descriptor) {
+        this(descriptor.getAnnotation(), descriptor.getGroups(), descriptor.getPayload(), descriptor
+            .getConstraintValidatorClasses(), descriptor.getAttributes(), descriptor.getComposingConstraints(),
+            descriptor.isReportAsSingleViolation(), descriptor.getValidationAppliesTo(), descriptor.getMessageTemplate());
+    }
+
+    /**
+     * Create a new ConstraintDescriptorImpl instance.
+     * 
+     * @param annotation
+     * @param groups
+     * @param payload
+     * @param constraintValidatorClasses
+     * @param attributes
+     * @param composingConstraints
+     * @param reportAsSingleViolation
+     */
+    public ConstraintDescriptorImpl(T annotation, Set<Class<?>> groups,
+        Set<Class<? extends javax.validation.Payload>> payload,
+        List<java.lang.Class<? extends javax.validation.ConstraintValidator<T, ?>>> constraintValidatorClasses,
+        Map<String, Object> attributes, Set<ConstraintDescriptor<?>> composingConstraints,
+        boolean reportAsSingleViolation, ConstraintTarget validationAppliesTo, String messageTemplate) {
+        this.annotation = annotation;
+        this.groups = groups;
+        this.payload = payload;
+        this.constraintValidatorClasses = constraintValidatorClasses;
+        this.attributes = attributes;
+        this.composingConstraints = composingConstraints;
+        this.reportAsSingleViolation = reportAsSingleViolation;
+        this.validationAppliesTo = validationAppliesTo;
+        this.template = messageTemplate;
+        this.hashCode = computeHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public T getAnnotation() {
+        return annotation;
+    }
+
+    public String getMessageTemplate() {
+        return template;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<Class<?>> getGroups() {
+        return groups;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<Class<? extends Payload>> getPayload() {
+        return payload;
+    }
+
+    public ConstraintTarget getValidationAppliesTo() {
+        return validationAppliesTo;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<java.lang.Class<? extends javax.validation.ConstraintValidator<T, ?>>> getConstraintValidatorClasses() {
+        return constraintValidatorClasses;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map<String, Object> getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<ConstraintDescriptor<?>> getComposingConstraints() {
+        return composingConstraints;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isReportAsSingleViolation() {
+        return reportAsSingleViolation;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final ConstraintDescriptorImpl that = (ConstraintDescriptorImpl) o;
+
+        if (reportAsSingleViolation != that.reportAsSingleViolation) return false;
+        if (!annotation.annotationType().equals(that.annotation.annotationType())) return false;
+        if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) return false;
+        if (composingConstraints != null ? !composingConstraints.equals(that.composingConstraints) : that.composingConstraints != null)
+            return false;
+        if (constraintValidatorClasses != null ? !constraintValidatorClasses.equals(that.constraintValidatorClasses) : that.constraintValidatorClasses != null)
+            return false;
+        if (groups != null ? !groups.equals(that.groups) : that.groups != null) return false;
+        if (payload != null ? !payload.equals(that.payload) : that.payload != null) return false;
+        if (template != null ? !template.equals(that.template) : that.template != null) return false;
+        if (validationAppliesTo != that.validationAppliesTo) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+
+    public int computeHashCode() {
+        int result = annotation.annotationType().hashCode();
+        result = 31 * result + (groups != null ? groups.hashCode() : 0);
+        result = 31 * result + (payload != null ? payload.hashCode() : 0);
+        result = 31 * result + (constraintValidatorClasses != null ? constraintValidatorClasses.hashCode() : 0);
+        result = 31 * result + (attributes != null ? attributes.hashCode() : 0);
+        result = 31 * result + (composingConstraints != null ? composingConstraints.hashCode() : 0);
+        result = 31 * result + (reportAsSingleViolation ? 1 : 0);
+        result = 31 * result + (validationAppliesTo != null ? validationAppliesTo.hashCode() : 0);
+        result = 31 * result + (template != null ? template.hashCode() : 0);
+        return result;
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr;
+
+import org.apache.bval.jsr.groups.Group;
+import org.apache.bval.jsr.groups.Groups;
+import org.apache.bval.jsr.groups.GroupsComputer;
+import org.apache.bval.model.MetaBean;
+
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.ElementDescriptor;
+import javax.validation.metadata.ElementDescriptor.ConstraintFinder;
+import javax.validation.metadata.Scope;
+import java.lang.annotation.ElementType;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Description: Implementation of the fluent {@link ConstraintFinder} interface.<br/>
+ */
+final class ConstraintFinderImpl implements ElementDescriptor.ConstraintFinder {
+    private final MetaBean metaBean;
+    private final Set<Scope> findInScopes;
+    private Set<ConstraintValidation<?>> constraintDescriptors;
+
+    /**
+     * Create a new ConstraintFinderImpl instance.
+     * 
+     * @param metaBean
+     * @param constraintDescriptors
+     */
+    ConstraintFinderImpl(MetaBean metaBean, Set<ConstraintValidation<?>> constraintDescriptors) {
+        this.metaBean = metaBean;
+        this.constraintDescriptors = constraintDescriptors;
+        this.findInScopes = new HashSet<Scope>(Arrays.asList(Scope.values()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ElementDescriptor.ConstraintFinder unorderedAndMatchingGroups(Class<?>... groups) {
+        Set<ConstraintValidation<?>> matchingDescriptors =
+            new HashSet<ConstraintValidation<?>>(constraintDescriptors.size());
+        Groups groupChain = new GroupsComputer().computeGroups(groups);
+        for (Group group : groupChain.getGroups()) {
+            if (group.isDefault()) {
+                // If group is default, check if it gets redefined
+                List<Group> expandedDefaultGroup = metaBean.getFeature(JsrFeatures.Bean.GROUP_SEQUENCE);
+                for (Group defaultGroupMember : expandedDefaultGroup) {
+                    for (ConstraintValidation<?> descriptor : constraintDescriptors) {
+                        if (isInScope(descriptor) && isInGroup(descriptor, defaultGroupMember)) {
+                            matchingDescriptors.add(descriptor);
+                        }
+                    }
+                }
+            } else {
+                for (ConstraintValidation<?> descriptor : constraintDescriptors) {
+                    if (isInScope(descriptor) && isInGroup(descriptor, group)) {
+                        matchingDescriptors.add(descriptor);
+                    }
+                }
+            }
+        }
+        return thisWith(matchingDescriptors);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ElementDescriptor.ConstraintFinder lookingAt(Scope scope) {
+        if (scope.equals(Scope.LOCAL_ELEMENT)) {
+            findInScopes.remove(Scope.HIERARCHY);
+            for (Iterator<ConstraintValidation<?>> it = constraintDescriptors.iterator(); it.hasNext();) {
+                ConstraintValidation<?> cv = it.next();
+                if (cv.getOwner() != metaBean.getBeanClass()) {
+                    it.remove();
+                }
+            }
+        }
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ElementDescriptor.ConstraintFinder declaredOn(ElementType... elementTypes) {
+        Set<ConstraintValidation<?>> matchingDescriptors =
+            new HashSet<ConstraintValidation<?>>(constraintDescriptors.size());
+        for (ElementType each : elementTypes) {
+            for (ConstraintValidation<?> descriptor : constraintDescriptors) {
+                if (isInScope(descriptor) && isAtElement(descriptor, each)) {
+                    matchingDescriptors.add(descriptor);
+                }
+            }
+        }
+        return thisWith(matchingDescriptors);
+    }
+
+    private boolean isAtElement(ConstraintValidation<?> descriptor, ElementType each) {
+        return descriptor.getAccess().getElementType() == each;
+    }
+
+    private boolean isInScope(ConstraintValidation<?> descriptor) {
+        if (findInScopes.size() == Scope.values().length)
+            return true; // all scopes
+        if (metaBean != null) {
+            Class<?> owner = descriptor.getOwner();
+            for (Scope scope : findInScopes) {
+                switch (scope) {
+                case LOCAL_ELEMENT:
+                    if (owner.equals(metaBean.getBeanClass()))
+                        return true;
+                    break;
+                case HIERARCHY:
+                    if (!owner.equals(metaBean.getBeanClass()))
+                        return true;
+                    break;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isInGroup(ConstraintValidation<?> descriptor, Group group) {
+        return descriptor.getGroups().contains(group.getGroup());
+    }
+
+    private ElementDescriptor.ConstraintFinder thisWith(Set<ConstraintValidation<?>> matchingDescriptors) {
+        constraintDescriptors = matchingDescriptors;
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<ConstraintDescriptor<?>> getConstraintDescriptors() {
+        if (constraintDescriptors.isEmpty()) {
+            return Collections.emptySet();
+        }
+        return Collections.<ConstraintDescriptor<?>>unmodifiableSet(constraintDescriptors);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasConstraints() {
+        return !constraintDescriptors.isEmpty();
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,585 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr;
+
+import org.apache.bval.jsr.util.NodeImpl;
+import org.apache.bval.jsr.util.PathImpl;
+import org.apache.bval.model.Validation;
+import org.apache.bval.model.ValidationContext;
+import org.apache.bval.model.ValidationListener;
+import org.apache.bval.util.AccessStrategy;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.reflect.TypeUtils;
+
+import javax.validation.ConstraintDefinitionException;
+import javax.validation.ConstraintTarget;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.Payload;
+import javax.validation.UnexpectedTypeException;
+import javax.validation.ValidationException;
+import javax.validation.constraintvalidation.SupportedValidationTarget;
+import javax.validation.constraintvalidation.ValidationTarget;
+import javax.validation.metadata.ConstraintDescriptor;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Description: Adapter between Constraint (JSR303) and Validation (Core)<br/>
+ * this instance is immutable!<br/>
+ */
+public class ConstraintValidation<T extends Annotation> implements Validation, ConstraintDescriptor<T> {
+    private final ConstraintValidatorFactory factory;
+    private final AccessStrategy access;
+    private final boolean reportFromComposite;
+    private final Map<String, Object> attributes;
+    private T annotation; // for metadata request API
+    private ConstraintValidator<T, ?> validator;
+
+    private Set<ConstraintValidation<?>> composedConstraints;
+
+    private boolean validated = false;
+
+    /**
+     * the owner is the type where the validation comes from. it is used to
+     * support implicit grouping.
+     */
+    private final Class<?> owner;
+    private Set<Class<?>> groups;
+    private Set<Class<? extends Payload>> payload;
+    private Class<? extends ConstraintValidator<T, ?>>[] validatorClasses;
+    private ConstraintTarget validationAppliesTo = null;
+
+    public ConstraintValidation(ConstraintValidatorFactory factory,
+                                Class<? extends ConstraintValidator<T, ?>>[] validatorClasses,
+                                T annotation, Class<?> owner, AccessStrategy access,
+                                boolean reportFromComposite, ConstraintTarget target) {
+        this.factory = factory;
+        this.attributes = new HashMap<String, Object>();
+        this.validatorClasses = ArrayUtils.clone(validatorClasses);
+        this.annotation = annotation;
+        this.owner = owner;
+        this.access = access;
+        this.reportFromComposite = reportFromComposite;
+        this.validationAppliesTo = target;
+    }
+
+    /**
+     * Return a {@link Serializable} {@link ConstraintDescriptor} capturing a
+     * snapshot of current state.
+     *
+     * @return {@link ConstraintDescriptor}
+     */
+    public ConstraintDescriptor<T> asSerializableDescriptor() {
+        return new ConstraintDescriptorImpl<T>(this);
+    }
+
+    void setGroups(final Set<Class<?>> groups) {
+        this.groups = groups;
+        ConstraintAnnotationAttributes.GROUPS.put(attributes, groups.toArray(new Class<?>[groups.size()]));
+    }
+
+    void setGroups(final Class<?>[] groups) {
+        this.groups = new HashSet<Class<?>>();
+        Collections.addAll(this.groups, groups);
+        ConstraintAnnotationAttributes.GROUPS.put(attributes, groups);
+    }
+
+    void setPayload(Set<Class<? extends Payload>> payload) {
+        this.payload = payload;
+        ConstraintAnnotationAttributes.PAYLOAD.put(attributes, payload.toArray(new Class[payload.size()]));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isReportAsSingleViolation() {
+        return reportFromComposite;
+    }
+
+    /**
+     * Add a composing constraint.
+     *
+     * @param aConstraintValidation to add
+     */
+    public void addComposed(ConstraintValidation<?> aConstraintValidation) {
+        if (composedConstraints == null) {
+            composedConstraints = new HashSet<ConstraintValidation<?>>();
+        }
+        composedConstraints.add(aConstraintValidation);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <L extends ValidationListener> void validate(ValidationContext<L> context) {
+        validate((GroupValidationContext<?>) context);
+    }
+
+    /**
+     * Validate a {@link GroupValidationContext}.
+     *
+     * @param context root
+     */
+    public void validate(final GroupValidationContext<?> context) {
+        if (validator == null) {
+            synchronized (this) {
+                if (validator == null) {
+                    try {
+                        validator = getConstraintValidator(annotation, validatorClasses, owner, access);
+                        if (validator != null) {
+                            validator.initialize(annotation);
+                        }
+                    } catch (final RuntimeException re) {
+                        if (ValidationException.class.isInstance(re)) {
+                            throw re;
+                        }
+                        throw new ConstraintDefinitionException(re);
+                    }
+                }
+            }
+        }
+
+        context.setConstraintValidation(this);
+        /**
+         * execute unless the given validation constraint has already been
+         * processed during this validation routine (as part of a previous group
+         * match)
+         */
+        if (!isMemberOf(context.getCurrentGroup().getGroup())) {
+            return; // do not validate in the current group
+        }
+        if (context.getCurrentOwner() != null && this.owner != context.getCurrentOwner()) {
+            return;
+        }
+        if (validator != null && !context.collectValidated(validator))
+            return; // already done
+
+        if (context.getMetaProperty() != null && !isReachable(context)) {
+            return;
+        }
+
+        // process composed constraints
+        if (isReportAsSingleViolation()) {
+            ConstraintValidationListener<?> listener = context.getListener();
+            listener.beginReportAsSingle();
+
+            boolean failed = listener.hasViolations();
+            try {
+                // stop validating when already failed and
+                // ReportAsSingleInvalidConstraint = true ?
+                for (Iterator<ConstraintValidation<?>> composed = getComposingValidations().iterator(); !failed && composed.hasNext(); ) {
+                    composed.next().validate(context);
+                    failed = listener.hasViolations();
+                }
+            } finally {
+                listener.endReportAsSingle();
+                // Restore current constraint validation
+                context.setConstraintValidation(this);
+            }
+
+            if (failed) {
+                // TODO RSt - how should the composed constraint error report look like?
+                ConstraintValidatorContextImpl jsrContext = new ConstraintValidatorContextImpl(context, this);
+                addErrors(context, jsrContext); // add defaultErrorMessage only
+                return;
+            }
+        } else {
+            for (ConstraintValidation<?> composed : getComposingValidations()) {
+                composed.validate(context);
+            }
+
+            // Restore current constraint validation
+            context.setConstraintValidation(this);
+        }
+
+        if (validator != null) {
+            ConstraintValidatorContextImpl jsrContext = new ConstraintValidatorContextImpl(context, this);
+            @SuppressWarnings("unchecked")
+            final ConstraintValidator<T, Object> objectValidator = (ConstraintValidator<T, Object>) validator;
+            if (!objectValidator.isValid(context.getValidatedValue(), jsrContext)) {
+                addErrors(context, jsrContext);
+            }
+        }
+    }
+
+    private <A extends Annotation, T> ConstraintValidator<A, ? super T> getConstraintValidator(A annotation,
+                                                                                               Class<? extends ConstraintValidator<A, ?>>[] constraintClasses, Class<?> owner, AccessStrategy access) {
+        if (constraintClasses != null && constraintClasses.length > 0) {
+            Type type = determineTargetedType(owner, access);
+
+            /**
+             * spec says in chapter 3.5.3.: The ConstraintValidator chosen to
+             * validate a declared type T is the one where the type supported by
+             * the ConstraintValidator is a supertype of T and where there is no
+             * other ConstraintValidator whose supported type is a supertype of
+             * T and not a supertype of the chosen ConstraintValidator supported
+             * type.
+             */
+            final Map<Type, Collection<Class<? extends ConstraintValidator<A, ?>>>> validatorTypes = getValidatorsTypes(constraintClasses);
+            reduceTarget(validatorTypes, access);
+
+            final List<Type> assignableTypes = new ArrayList<Type>(constraintClasses.length);
+            fillAssignableTypes(type, validatorTypes.keySet(), assignableTypes);
+            reduceAssignableTypes(assignableTypes);
+            checkOneType(assignableTypes, type, owner, annotation, access);
+
+            if ((type == Object.class || type == Object[].class) && validatorTypes.containsKey(Object.class) && validatorTypes.containsKey(Object[].class)) {
+                throw new ConstraintDefinitionException("Only a validator for Object or Object[] should be provided for cross parameter validators");
+            }
+
+            final Collection<Class<? extends ConstraintValidator<A, ?>>> key = validatorTypes.get(assignableTypes.get(0));
+            if (key.size() > 1) {
+                final String message = "Factory returned " + key.size() + " validators";
+                if (ParametersAccess.class.isInstance(access)) { // cross parameter
+                    throw new ConstraintDefinitionException(message);
+                }
+                throw new UnexpectedTypeException(message);
+            }
+
+            @SuppressWarnings("unchecked")
+            final ConstraintValidator<A, ? super T> validator = (ConstraintValidator<A, ? super T>) factory.getInstance(key.iterator().next());
+            if (validator == null) {
+                throw new ValidationException("Factory returned null validator for: " + key);
+
+            }
+            return validator;
+            // NOTE: validator initialization deferred until append phase
+        }
+        return null;
+    }
+
+    private <A extends Annotation> void reduceTarget(final Map<Type, Collection<Class<? extends ConstraintValidator<A, ?>>>> validator, final AccessStrategy access) {
+        for (final Map.Entry<Type, Collection<Class<? extends ConstraintValidator<A, ?>>>> entry : validator.entrySet()) {
+            final Collection<Class<? extends ConstraintValidator<A, ?>>> validators = entry.getValue();
+            final Iterator<Class<? extends ConstraintValidator<A, ?>>> it = validators.iterator();
+            while (it.hasNext()) {
+                final Type v = it.next();
+                if (!Class.class.isInstance(v)) {
+                    continue; // TODO: handle this case
+                }
+
+                final Class<?> clazz = Class.class.cast(v);
+                final SupportedValidationTarget target = clazz.getAnnotation(SupportedValidationTarget.class);
+                if (target != null) {
+                    final Collection<ValidationTarget> targets = Arrays.asList(target.value());
+                    final boolean isParameter = ParameterAccess.class.isInstance(access) || ParametersAccess.class.isInstance(access);
+                    if ((isParameter && !targets.contains(ValidationTarget.PARAMETERS))
+                        || (!isParameter && !targets.contains(ValidationTarget.ANNOTATED_ELEMENT))) {
+                        it.remove();
+                    }
+                }
+            }
+            if (validators.isEmpty()) {
+                validator.remove(entry.getKey());
+            }
+        }
+    }
+
+    private static void checkOneType(List<Type> types, Type targetType, Class<?> owner, Annotation anno,
+                                     AccessStrategy access) {
+
+        if (types.isEmpty()) {
+            final String message = "No validator could be found for type " + stringForType(targetType)
+                + ". See: @" + anno.annotationType().getSimpleName() + " at " + stringForLocation(owner, access);
+            if (Object[].class.equals(targetType)) { // cross parameter
+                throw new ConstraintDefinitionException(message);
+            }
+            throw new UnexpectedTypeException(message);
+        } else if (types.size() > 1) {
+            StringBuilder buf = new StringBuilder();
+            buf.append("Ambiguous validators for type ");
+            buf.append(stringForType(targetType));
+            buf.append(". See: @").append(anno.annotationType().getSimpleName()).append(" at ").append(
+                stringForLocation(owner, access));
+            buf.append(". Validators are: ");
+            boolean comma = false;
+            for (Type each : types) {
+                if (comma)
+                    buf.append(", ");
+                comma = true;
+                buf.append(each);
+            }
+            throw new UnexpectedTypeException(buf.toString());
+        }
+    }
+
+    private static String stringForType(Type clazz) {
+        if (clazz instanceof Class<?>) {
+            if (((Class<?>) clazz).isArray()) {
+                return ((Class<?>) clazz).getComponentType().getName() + "[]";
+            } else {
+                return ((Class<?>) clazz).getName();
+            }
+        } else {
+            return clazz.toString();
+        }
+    }
+
+    private static String stringForLocation(Class<?> owner, AccessStrategy access) {
+        if (access != null) {
+            return access.toString();
+        } else {
+            return owner.getName();
+        }
+    }
+
+    private static void fillAssignableTypes(Type type, Set<Type> validatorsTypes, List<Type> suitableTypes) {
+        for (final Type validatorType : validatorsTypes) {
+            if (org.apache.commons.lang3.reflect.TypeUtils.isAssignable(type, validatorType)
+                && !suitableTypes.contains(validatorType)) {
+                suitableTypes.add(validatorType);
+            }
+        }
+    }
+
+    /**
+     * Tries to reduce all assignable classes down to a single class.
+     *
+     * @param assignableTypes The set of all classes which are assignable to the class of
+     *                        the value to be validated and which are handled by at least
+     *                        one of the validators for the specified constraint.
+     */
+    private static void reduceAssignableTypes(List<Type> assignableTypes) {
+        if (assignableTypes.size() <= 1) {
+            return; // no need to reduce
+        }
+        boolean removed;
+        do {
+            removed = false;
+            final Type type = assignableTypes.get(0);
+            for (int i = 1; i < assignableTypes.size(); i++) {
+                Type nextType = assignableTypes.get(i);
+                if (TypeUtils.isAssignable(nextType, type)) {
+                    assignableTypes.remove(0);
+                    i--;
+                    removed = true;
+                } else if (TypeUtils.isAssignable(type, nextType)) {
+                    assignableTypes.remove(i--);
+                    removed = true;
+                }
+            }
+        } while (removed && assignableTypes.size() > 1);
+
+    }
+
+    private static <A extends Annotation> Map<Type, Collection<Class<? extends ConstraintValidator<A, ?>>>> getValidatorsTypes(
+        Class<? extends ConstraintValidator<A, ?>>[] constraintValidatorClasses) {
+        final Map<Type, Collection<Class<? extends ConstraintValidator<A, ?>>>> validatorsTypes = new HashMap<Type, Collection<Class<? extends ConstraintValidator<A, ?>>>>();
+        for (Class<? extends ConstraintValidator<A, ?>> validatorType : constraintValidatorClasses) {
+            Type validatedType = TypeUtils.getTypeArguments(validatorType, ConstraintValidator.class).get(ConstraintValidator.class.getTypeParameters()[1]);
+            if (validatedType == null) {
+                throw new ValidationException(String.format("Could not detect validated type for %s", validatorType));
+            }
+            if (validatedType instanceof GenericArrayType) {
+                Type componentType = TypeUtils.getArrayComponentType(validatedType);
+                if (componentType instanceof Class<?>) {
+                    validatedType = Array.newInstance((Class<?>) componentType, 0).getClass();
+                }
+            }
+            if (!validatorsTypes.containsKey(validatedType)) {
+                validatorsTypes.put(validatedType, new ArrayList<Class<? extends ConstraintValidator<A, ?>>>());
+            }
+            validatorsTypes.get(validatedType).add(validatorType);
+        }
+        return validatorsTypes;
+    }
+
+    /**
+     * implements spec chapter 3.5.3. ConstraintValidator resolution algorithm.
+     */
+    private static Type determineTargetedType(Class<?> owner, AccessStrategy access) {
+        // if the constraint declaration is hosted on a class or an interface,
+        // the targeted type is the class or the interface.
+        if (access == null)
+            return owner;
+        Type type = access.getJavaType();
+        if (type == null)
+            return Object.class;
+        if (type instanceof Class<?>)
+            type = ClassUtils.primitiveToWrapper((Class<?>) type);
+        return type;
+    }
+
+    /**
+     * Initialize the validator (if not <code>null</code>) with the stored
+     * annotation.
+     */
+    public void initialize() {
+        if (null != validator) {
+            try {
+                validator.initialize(annotation);
+            } catch (RuntimeException e) {
+                // Either a "legit" problem initializing the validator or a
+                // ClassCastException if the validator associated annotation is
+                // not a supertype of the validated annotation.
+                throw new ConstraintDefinitionException("Incorrect validator ["
+                    + validator.getClass().getCanonicalName() + "] for annotation "
+                    + annotation.annotationType().getCanonicalName(), e);
+            }
+        }
+    }
+
+    private boolean isReachable(GroupValidationContext<?> context) {
+        final PathImpl path = context.getPropertyPath();
+        final NodeImpl node = path.getLeafNode();
+        PathImpl beanPath = path.getPathWithoutLeafNode();
+        if (beanPath == null) {
+            beanPath = PathImpl.create();
+        }
+        try {
+            if (!context.getTraversableResolver().isReachable(context.getBean(), node,
+                context.getRootMetaBean().getBeanClass(), beanPath, access.getElementType()))
+                return false;
+        } catch (RuntimeException e) {
+            throw new ValidationException("Error in TraversableResolver.isReachable() for " + context.getBean(), e);
+        }
+
+        return true;
+    }
+
+    private void addErrors(GroupValidationContext<?> context, ConstraintValidatorContextImpl jsrContext) {
+        for (ValidationListener.Error each : jsrContext.getErrorMessages()) {
+            context.getListener().addError(each, context);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return "ConstraintValidation{" + validator + '}';
+    }
+
+    /**
+     * Get the message template used by this constraint.
+     *
+     * @return String
+     */
+    public String getMessageTemplate() {
+        return ConstraintAnnotationAttributes.MESSAGE.get(attributes);
+    }
+
+    public ConstraintValidator<T, ?> getValidator() {
+        return validator;
+    }
+
+    protected boolean isMemberOf(Class<?> reqGroup) {
+        return groups.contains(reqGroup);
+    }
+
+    public Class<?> getOwner() {
+        return owner;
+    }
+
+    public T getAnnotation() {
+        return annotation;
+    }
+
+    public AccessStrategy getAccess() {
+        return access;
+    }
+
+    public void setAnnotation(T annotation) {
+        this.annotation = annotation;
+    }
+
+    // ///////////////////////// ConstraintDescriptor implementation
+
+    /**
+     * {@inheritDoc}
+     */
+    public Map<String, Object> getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
+    public Set<ConstraintDescriptor<?>> getComposingConstraints() {
+        return composedConstraints == null ? Collections.EMPTY_SET : composedConstraints;
+    }
+
+    /**
+     * Get the composing {@link ConstraintValidation} objects. This is
+     * effectively an implementation-specific analogue to
+     * {@link #getComposingConstraints()}.
+     *
+     * @return {@link Set} of {@link ConstraintValidation}
+     */
+    @SuppressWarnings("unchecked")
+    Set<ConstraintValidation<?>> getComposingValidations() {
+        return composedConstraints == null ? Collections.EMPTY_SET : composedConstraints;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<Class<?>> getGroups() {
+        return groups;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Set<Class<? extends Payload>> getPayload() {
+        return payload;
+    }
+
+    public ConstraintTarget getValidationAppliesTo() {
+        return validationAppliesTo;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<Class<? extends ConstraintValidator<T, ?>>> getConstraintValidatorClasses() {
+        if (validatorClasses == null) {
+            return Collections.emptyList();
+        }
+        return Arrays.asList(validatorClasses);
+    }
+
+    public void setValidationAppliesTo(final ConstraintTarget validationAppliesTo) {
+        this.validationAppliesTo = validationAppliesTo;
+    }
+
+    public boolean isValidated() {
+        return validated;
+    }
+
+    public void setValidated(final boolean validated) {
+        this.validated = validated;
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidationListener.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidationListener.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidationListener.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidationListener.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,255 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.bval.jsr;
+
+
+import org.apache.bval.jsr.util.PathImpl;
+import org.apache.bval.model.ValidationContext;
+import org.apache.bval.model.ValidationListener;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ElementKind;
+import javax.validation.MessageInterpolator;
+import javax.validation.Path;
+import javax.validation.metadata.ConstraintDescriptor;
+import java.lang.annotation.ElementType;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Description: JSR-303 {@link ValidationListener} implementation; provides {@link ConstraintViolation}s.<br/>
+ * 
+ * @version $Rev: 1503686 $ $Date: 2013-07-16 14:38:56 +0200 (mar., 16 juil. 2013) $
+ */
+public final class ConstraintValidationListener<T> implements ValidationListener {
+    private final Set<ConstraintViolation<T>> constraintViolations = new HashSet<ConstraintViolation<T>>();
+    private final T rootBean;
+    private final Class<T> rootBeanType;
+    // the validation process is single-threaded and it's unlikely to change in the near future (otherwise use AtomicInteger).
+    private int compositeDepth = 0;
+    private boolean hasCompositeError;
+
+    /**
+     * Create a new ConstraintValidationListener instance.
+     * @param aRootBean
+     * @param rootBeanType
+     */
+    public ConstraintValidationListener(T aRootBean, Class<T> rootBeanType) {
+        this.rootBean = aRootBean;
+        this.rootBeanType = rootBeanType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <VL extends ValidationListener> void addError(String reason, ValidationContext<VL> context) {
+        addError(reason, null, context);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <VL extends ValidationListener> void addError(Error error, ValidationContext<VL> context) {
+        if (error.getOwner() instanceof Path) {
+            addError(error.getReason(), (Path) error.getOwner(), context);
+        } else {
+            addError(error.getReason(), null, context);
+        }
+    }
+
+    private void addError(String messageTemplate, Path propPath,
+                          ValidationContext<?> context) {
+        if (compositeDepth > 0) {
+            hasCompositeError |= true;
+            return;
+        }
+        final Object value;
+
+        final ConstraintDescriptor<?> descriptor;
+        final String message;
+        if (context instanceof GroupValidationContext<?>) {
+            GroupValidationContext<?> gcontext = (GroupValidationContext<?>) context;
+            value = gcontext.getValidatedValue();
+            if (gcontext instanceof MessageInterpolator.Context) {
+                message = gcontext.getMessageResolver()
+                      .interpolate(messageTemplate,
+                            (MessageInterpolator.Context) gcontext);
+            } else {
+                message =
+                      gcontext.getMessageResolver().interpolate(messageTemplate, null);
+            }
+            descriptor = gcontext.getConstraintValidation().asSerializableDescriptor();
+            if (propPath == null) propPath = gcontext.getPropertyPath();
+        } else {
+            if (context.getMetaProperty() == null) value = context.getBean();
+            else value = context.getPropertyValue();
+            message = messageTemplate;
+            if (propPath == null)
+                propPath = PathImpl.createPathFromString(context.getPropertyName());
+            descriptor = null;
+        }
+        ElementType elementType = (context.getAccess() != null) ? context.getAccess().getElementType() : null;
+
+        final Object[] parameters;
+        Object leaf;
+        Object returnValue;
+        T rootBean;
+        if (GroupValidationContext.class.isInstance(context)) { // TODO: clean up it but it would need to rework completely our context - get rid of it would be the best
+            final GroupValidationContext<T> ctx = GroupValidationContext.class.cast(context);
+            final ElementKind elementKind = ctx.getElementKind();
+            final Iterator<Path.Node> it = propPath.iterator();
+            final ElementKind kind = propPath.iterator().next().getKind();
+
+            returnValue = ctx.getReturnValue();
+
+            if (ElementKind.CONSTRUCTOR.equals(kind)) {
+                rootBean = null;
+                leaf = context.getBean();
+                returnValue = this.rootBean; // switch back return value and rootBean
+            } else if (ElementKind.METHOD.equals(kind)) {
+                if (ElementKind.RETURN_VALUE.equals(elementKind)) { // switch back return value and rootBean
+                    rootBean = (T) returnValue;
+                    if (kindOf(propPath, ElementKind.RETURN_VALUE)) {
+                        leaf = returnValue;
+                        returnValue = this.rootBean;
+                    } else {
+                        leaf = this.rootBean;
+                        returnValue = this.rootBean;
+                    }
+                } else {
+                    rootBean = this.rootBean;
+                    if (kindOf(propPath, ElementKind.PARAMETER, ElementKind.CROSS_PARAMETER)) {
+                        leaf = rootBean;
+                    } else {
+                        leaf = context.getBean();
+                    }
+                }
+            } else {
+                rootBean = this.rootBean;
+                leaf = context.getBean();
+            }
+
+            if (ElementKind.CONSTRUCTOR.equals(kind)
+                    && (ElementKind.CROSS_PARAMETER.equals(elementKind)
+                        || ElementKind.PARAMETER.equals(elementKind))
+                    && (it.hasNext() && it.next() != null && it.hasNext() && it.next() != null && !it.hasNext())) { // means inherited validation use real value
+                leaf = null;
+            }
+
+            parameters = ctx.getParameters();
+        } else {
+            leaf = context.getBean();
+            returnValue = null;
+            parameters = null;
+            rootBean = this.rootBean;
+        }
+
+        constraintViolations.add(new ConstraintViolationImpl<T>(
+                messageTemplate, message,
+                rootBean, leaf,
+                propPath, value, descriptor,
+                rootBeanType,
+                elementType, returnValue, parameters));
+    }
+
+    private static boolean kindOf(final Path propPath, final ElementKind... kinds) {
+        final Iterator<Path.Node> node = propPath.iterator();
+        boolean isParam = false;
+        while (node.hasNext()) {
+            final ElementKind current = node.next().getKind();
+            isParam = false;
+            for (final ElementKind k : kinds) {
+                if (k.equals(current)) {
+                    isParam = true;
+                    break;
+                }
+            }
+        }
+        return isParam;
+    }
+
+    /**
+     * Get the {@link ConstraintViolation}s accumulated by this {@link ConstraintValidationListener}.
+     * @return {@link Set} of {@link ConstraintViolation}
+     */
+    public Set<ConstraintViolation<T>> getConstraintViolations() {
+        return constraintViolations;
+    }
+
+    /**
+     * Learn whether no violations were found. 
+     * @return boolean
+     */
+    public boolean isEmpty() {
+        return constraintViolations.isEmpty();
+    }
+
+    /**
+     * Get the root bean.
+     * @return T
+     */
+    public T getRootBean() {
+        return rootBean;
+    }
+
+    /**
+     * Get the root bean type of this {@link ConstraintValidationListener}.
+     * @return Class<T>
+     */
+    public Class<T> getRootBeanType() {
+        return rootBeanType;
+    }
+    
+    /**
+     * Get the count of encountered violations.
+     * @return int
+     */
+    public int violationsSize() {
+        return constraintViolations.size();
+    }
+
+    /**
+     * Learn whether there are violations available.
+     * If in report-as-single-violation mode, the result is scoped accordingly.
+     * Note that this means you must check before exiting report-as-single-violation mode
+     * @return boolean
+     */
+    public boolean hasViolations() {
+        return compositeDepth == 0 ? !constraintViolations.isEmpty() : hasCompositeError;
+    }
+
+    /**
+     * Signify the beginning of a report-as-single-violation composite validation.
+     * @return <code>true</code> as this call caused the listener to enter report-as-single-violation mode
+     */
+    public boolean beginReportAsSingle() {
+        return ++compositeDepth == 1;
+    }
+
+    /**
+     * Signify the end of a report-as-single-violation composite validation.
+     * @return <code>true</code> as this call caused the listener to exit report-as-single-violation mode
+     */
+    public boolean endReportAsSingle() {
+        boolean endOutMostReportAsSingle = (--compositeDepth == 0);
+        if( endOutMostReportAsSingle ) {
+            hasCompositeError = false;
+        }
+        return endOutMostReportAsSingle;
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr;
+
+
+import org.apache.bval.jsr.util.LeafNodeBuilderCustomizableContextImpl;
+import org.apache.bval.jsr.util.NodeBuilderDefinedContextImpl;
+import org.apache.bval.jsr.util.NodeImpl;
+import org.apache.bval.jsr.util.PathImpl;
+import org.apache.bval.model.ValidationListener;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.ElementKind;
+import javax.validation.Path;
+import javax.validation.ValidationException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Description: Short-lived {@link ConstraintValidatorContext} implementation passed by
+ * a {@link ConstraintValidation} to its adapted {@link ConstraintValidator}. <br/>
+ */
+public class ConstraintValidatorContextImpl implements ConstraintValidatorContext {
+    private final List<ValidationListener.Error> errorMessages =
+          new LinkedList<ValidationListener.Error>();
+
+    private final ConstraintValidation<?> constraintDescriptor;
+    private final GroupValidationContext<?> validationContext;
+
+    private boolean defaultDisabled;
+
+    /**
+     * Create a new ConstraintValidatorContextImpl instance.
+     * @param validationContext
+     * @param aConstraintValidation
+     */
+    public ConstraintValidatorContextImpl(GroupValidationContext<?> validationContext,
+                                          ConstraintValidation<?> aConstraintValidation) {
+        this.validationContext = validationContext;
+        this.constraintDescriptor = aConstraintValidation;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void disableDefaultConstraintViolation() {
+        defaultDisabled = true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getDefaultConstraintMessageTemplate() {
+        return constraintDescriptor.getMessageTemplate();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ConstraintViolationBuilder buildConstraintViolationWithTemplate(
+          String messageTemplate) {
+        return new ConstraintViolationBuilderImpl(this, messageTemplate, validationContext.getPropertyPath());
+    }
+
+    public <T> T unwrap(Class<T> type) {
+        if (type.isInstance(this)) {
+            return type.cast(this);
+        }
+        throw new ValidationException("Type " + type + " not supported");
+    }
+
+    private static final class ConstraintViolationBuilderImpl
+          implements ConstraintValidatorContext.ConstraintViolationBuilder {
+        private final ConstraintValidatorContextImpl parent;
+        private final String messageTemplate;
+        private final PathImpl propertyPath;
+
+        /**
+         * Create a new ConstraintViolationBuilderImpl instance.
+         * @param contextImpl
+         * @param template
+         * @param path
+         */
+        ConstraintViolationBuilderImpl(ConstraintValidatorContextImpl contextImpl,
+                                       String template, PathImpl path) {
+            parent = contextImpl;
+            messageTemplate = template;
+            propertyPath = path;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public NodeBuilderDefinedContext addNode(String name) {
+            PathImpl path;
+            if (propertyPath.isRootPath()) {
+                path = PathImpl.create();
+                path.getLeafNode().setName(name);
+            } else {
+                path = PathImpl.copy(propertyPath);
+                path.addNode(new NodeImpl(name));
+            }
+            return new NodeBuilderDefinedContextImpl(parent, messageTemplate, path);
+        }
+
+        public NodeBuilderCustomizableContext addPropertyNode(String name) {
+            final NodeImpl node;
+            if (!propertyPath.isRootPath()) {
+                if (propertyPath.getLeafNode().getKind() != null) {
+                    node = new NodeImpl.PropertyNodeImpl(name);
+                    propertyPath.addNode(node);
+                } else {
+                    node = propertyPath.getLeafNode();
+                }
+            } else {
+                node = new NodeImpl.PropertyNodeImpl(name);
+                propertyPath.addNode(node);
+            }
+            node.setName(name);
+            node.setKind(ElementKind.PROPERTY); // enforce it
+            return new NodeBuilderCustomizableContextImpl(parent, messageTemplate, propertyPath);
+        }
+
+        public LeafNodeBuilderCustomizableContext addBeanNode() {
+            final NodeImpl node = new NodeImpl.BeanNodeImpl();
+            node.setKind(ElementKind.BEAN);
+            propertyPath.addNode(node);
+            return new LeafNodeBuilderCustomizableContextImpl(parent, messageTemplate, propertyPath);
+        }
+
+        public NodeBuilderDefinedContext addParameterNode(int index) {
+            final Method method = parent.validationContext.getMethod();
+            final List<String> parameters = parent.validationContext.getParameterNameProvider().getParameterNames(method);
+            final NodeImpl node = new NodeImpl.ParameterNodeImpl(parameters.get(index), index);
+            node.setParameterIndex(index);
+            node.setKind(ElementKind.PARAMETER);
+            if (!propertyPath.isRootPath()) {
+                propertyPath.removeLeafNode();
+            }
+            propertyPath.addNode(node);
+            return new NodeBuilderDefinedContextImpl(parent, messageTemplate, propertyPath);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public ConstraintValidatorContext addConstraintViolation() {
+            parent.addError(messageTemplate, propertyPath);
+            return parent;
+        }
+    }
+
+    /**
+     * Get the queued error messages.
+     * @return List
+     */
+    public List<ValidationListener.Error> getErrorMessages() {
+        if (defaultDisabled && errorMessages.isEmpty()) {
+            throw new ValidationException(
+                  "At least one custom message must be created if the default error message gets disabled.");
+        }
+
+        List<ValidationListener.Error> returnedErrorMessages =
+              new ArrayList<ValidationListener.Error>(errorMessages);
+        if (!defaultDisabled) {
+            returnedErrorMessages.add(new ValidationListener.Error(
+                  getDefaultConstraintMessageTemplate(), validationContext.getPropertyPath(),
+                  null));
+        }
+        return returnedErrorMessages;
+    }
+
+    /**
+     * Get this {@link ConstraintValidatorContext}'s {@link GroupValidationContext}.
+     * @return {@link GroupValidationContext}
+     */
+    public GroupValidationContext<?> getValidationContext() {
+        return validationContext;
+    }
+
+    /**
+     * Add an error message to this {@link ConstraintValidatorContext}.
+     * @param messageTemplate
+     * @param propertyPath
+     */
+    public void addError(String messageTemplate, Path propertyPath) {
+        errorMessages.add(new ValidationListener.Error(messageTemplate, propertyPath, null));
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,134 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.bval.jsr;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.Path;
+
+/**
+ * Class that stores the needed properties to ensure that a validation is not
+ * checked more than once.
+ * <p>
+ * These properties are:
+ * <ul>
+ * <li>The ref of the bean to which the validation would be applied.</li>
+ * <li>The path of the property.</li>
+ * <li>The ref of the {@link ConstraintValidator}.</li>
+ * </ul>
+ * 
+ * @author Carlos Vara
+ */
+final class ConstraintValidatorIdentity {
+
+    private final Object bean;
+    private final Path path;
+    private final ConstraintValidator<?, ?> constraintValidator;
+
+    /**
+     * Create a new ConstraintValidatorIdentity instance.
+     * @param bean
+     * @param path
+     * @param constraintValidator
+     */
+    public ConstraintValidatorIdentity(Object bean, Path path, ConstraintValidator<?, ?> constraintValidator) {
+        this.bean = bean;
+        this.path = path;
+        this.constraintValidator = constraintValidator;
+    }
+
+    /**
+     * Get the referenced bean.
+     * @return Object
+     */
+    public Object getBean() {
+        return bean;
+    }
+
+    /**
+     * Get the referenced property {@link Path}.
+     * @return Path
+     */
+    public Path getPath() {
+        return path;
+    }
+
+    /**
+     * Get the associated {@link ConstraintValidator}.
+     * @return {@link ConstraintValidator}
+     */
+    public ConstraintValidator<?, ?> getConstraintValidator() {
+        return constraintValidator;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equals(Object obj) {
+
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (!(obj instanceof ConstraintValidatorIdentity)) {
+            return false;
+        }
+
+        ConstraintValidatorIdentity other = (ConstraintValidatorIdentity) obj;
+
+        // Bean ref must be the same
+        if (this.bean != other.bean) {
+            return false;
+        }
+
+        // ConstraintValidator ref must be the same
+        if (this.constraintValidator != other.constraintValidator) {
+            return false;
+        }
+
+        // Path must be equals
+        if (!this.path.equals(other.path)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+                + ((this.bean == null) ? 0 : this.bean.hashCode());
+        result = prime * result
+                + ((this.path == null) ? 0 : this.path.hashCode());
+        result = prime * result
+                + ((this.constraintValidator == null) ? 0 : this.constraintValidator.hashCode());
+        return result;
+    }
+
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.bval.jsr;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Path;
+import javax.validation.ValidationException;
+import javax.validation.metadata.ConstraintDescriptor;
+import java.io.Serializable;
+import java.lang.annotation.ElementType;
+import java.util.Arrays;
+
+/**
+ * Description: Describe a constraint validation defect.<br/>
+ * From rootBean and propertyPath, it is possible to rebuild the context of the failure
+ */
+class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable {
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    private final String messageTemplate;
+    private final String message;
+    /** root bean validation was invoked on. */
+    private final T rootBean;
+    private final Class<T> rootBeanClass;
+    /** last bean validated. */
+    private final Object leafBean;
+    private final Object value;
+    private final Path propertyPath;
+    private final ElementType elementType;
+    private final ConstraintDescriptor<?> constraintDescriptor;
+    private final Object returnValue;
+    private final Object[] parameters;
+    private final int hashCode;
+
+    /**
+     * Create a new ConstraintViolationImpl instance.
+     * @param messageTemplate - message reason (raw message)
+     * @param message - interpolated message (locale specific)
+     * @param rootBean
+     * @param leafBean
+     * @param propertyPath
+     * @param value
+     * @param constraintDescriptor
+     * @param rootBeanClass
+     * @param elementType
+     * @param returnValue
+     * @param parameters
+     */
+    public ConstraintViolationImpl(String messageTemplate, String message, T rootBean, Object leafBean,
+                                   Path propertyPath, Object value,
+                                   ConstraintDescriptor<?> constraintDescriptor, Class<T> rootBeanClass,
+                                   ElementType elementType, Object returnValue, Object[] parameters) {
+        this.messageTemplate = messageTemplate;
+        this.message = message;
+        this.rootBean = rootBean;
+        this.rootBeanClass = rootBeanClass;
+        this.propertyPath = propertyPath;
+        this.leafBean = leafBean;
+        this.value = value;
+        this.constraintDescriptor = constraintDescriptor;
+        this.elementType = elementType;
+        this.returnValue = returnValue;
+        this.parameters = parameters;
+        this.hashCode = computeHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     * former name getInterpolatedMessage()
+     * @return The interpolated error message for this constraint violation.
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getMessageTemplate() {
+        return messageTemplate;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return Root bean being validated
+     */
+    public T getRootBean() {
+        return rootBean;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Class<T> getRootBeanClass() {
+        return rootBeanClass;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object getLeafBean() {
+        return leafBean;
+    }
+
+    public Object[] getExecutableParameters() {
+        return parameters;
+    }
+
+    public Object getExecutableReturnValue() {
+        return returnValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return The value failing to pass the constraint
+     */
+    public Object getInvalidValue() {
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return the property path to the value from <code>rootBean</code>
+     *         Null if the value is the rootBean itself
+     */
+    public Path getPropertyPath() {
+        return propertyPath;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ConstraintDescriptor<?> getConstraintDescriptor() {
+        return constraintDescriptor;
+    }
+
+    public <U> U unwrap(Class<U> type) {
+        if (type.isInstance(this)) {
+            return type.cast(this);
+        }
+        throw new ValidationException("Type " + type + " is not supported");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return "ConstraintViolationImpl{" + "rootBean=" + rootBean + ", propertyPath='" +
+              propertyPath + '\'' + ", message='" + message + '\'' + ", leafBean=" +
+              leafBean + ", value=" + value + '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ConstraintViolationImpl that = (ConstraintViolationImpl) o;
+
+        if (constraintDescriptor != null ? !constraintDescriptor.equals(that.constraintDescriptor) : that.constraintDescriptor != null)
+            return false;
+        if (elementType != that.elementType) return false;
+        if (leafBean != null ? !leafBean.equals(that.leafBean) : that.leafBean != null) return false;
+        if (message != null ? !message.equals(that.message) : that.message != null) return false;
+        if (messageTemplate != null ? !messageTemplate.equals(that.messageTemplate) : that.messageTemplate != null)
+            return false;
+        // Probably incorrect - comparing Object[] arrays with Arrays.equals
+        if (!Arrays.equals(parameters, that.parameters)) return false;
+        if (propertyPath != null ? !propertyPath.equals(that.propertyPath) : that.propertyPath != null) return false;
+        if (returnValue != null ? !returnValue.equals(that.returnValue) : that.returnValue != null) return false;
+        if (rootBean != null ? !rootBean.equals(that.rootBean) : that.rootBean != null) return false;
+        if (rootBeanClass != null ? !rootBeanClass.equals(that.rootBeanClass) : that.rootBeanClass != null)
+            return false;
+        if (value != null ? !value.equals(that.value) : that.value != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return hashCode;
+    }
+
+    public int computeHashCode() {
+        int result = messageTemplate != null ? messageTemplate.hashCode() : 0;
+        result = 31 * result + (message != null ? message.hashCode() : 0);
+        result = 31 * result + (rootBean != null ? rootBean.hashCode() : 0);
+        result = 31 * result + (rootBeanClass != null ? rootBeanClass.hashCode() : 0);
+        result = 31 * result + (leafBean != null ? leafBean.hashCode() : 0);
+        result = 31 * result + (value != null ? value.hashCode() : 0);
+        result = 31 * result + (propertyPath != null ? propertyPath.hashCode() : 0);
+        result = 31 * result + (elementType != null ? elementType.hashCode() : 0);
+        result = 31 * result + (constraintDescriptor != null ? constraintDescriptor.hashCode() : 0);
+        result = 31 * result + (returnValue != null ? returnValue.hashCode() : 0);
+        result = 31 * result + (parameters != null ? Arrays.hashCode(parameters) : 0);
+        return result;
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstructorDescriptorImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstructorDescriptorImpl.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstructorDescriptorImpl.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/ConstructorDescriptorImpl.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.bval.jsr;
+
+
+import org.apache.bval.model.MetaBean;
+import org.apache.bval.model.MetaConstructor;
+import org.apache.bval.model.Validation;
+
+import javax.validation.metadata.ConstructorDescriptor;
+
+/**
+ * Description: {@link javax.validation.metadata.ConstructorDescriptor} implementation.<br/>
+ */
+public class ConstructorDescriptorImpl extends InvocableElementDescriptor
+      implements ConstructorDescriptor, ProcedureDescriptor {
+    /**
+     * Create a new ConstructorDescriptorImpl instance.
+     * @param metaBean
+     * @param validations
+     */
+    protected ConstructorDescriptorImpl(MetaBean metaBean, Validation[] validations) {
+        super(metaBean, metaBean.getBeanClass(), validations);
+    }
+
+    public ConstructorDescriptorImpl(final MetaBean metaBean, final MetaConstructor metaMethod) {
+        super(metaBean, metaBean.getBeanClass(), new Validation[0]);
+        setCascaded(false);
+    }
+
+    public String getName() {
+        return elementClass.getSimpleName();
+    }
+
+    @Override
+    public boolean hasConstraints() {
+        return false;
+    }
+
+    public boolean hasConstrainedParameters() {
+        return super.hasConstrainedParameters();
+    }
+
+    public boolean hasConstrainedReturnValue() {
+        return super.hasConstrainedReturnValue();
+    }
+}

Added: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/CrossParameterDescriptorImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/CrossParameterDescriptorImpl.java?rev=1517540&view=auto
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/CrossParameterDescriptorImpl.java (added)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/jsr/CrossParameterDescriptorImpl.java Mon Aug 26 13:59:15 2013
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.bval.jsr;
+
+import org.apache.bval.model.MetaBean;
+
+import javax.validation.metadata.CrossParameterDescriptor;
+import java.util.Collection;
+
+public class CrossParameterDescriptorImpl extends ElementDescriptorImpl implements CrossParameterDescriptor {
+    public CrossParameterDescriptorImpl(final MetaBean bean, final Collection<ConstraintValidation<?>> list) {
+        super(bean, Object[].class, list.toArray(new ConstraintValidation<?>[list.size()]));
+    }
+
+    public boolean hasConstraints() {
+        return !getConstraintDescriptors().isEmpty();
+    }
+}



Mime
View raw message