bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject svn commit: r999729 [1/3] - in /incubator/bval/sandbox/lang3-work: bval-jsr303/src/test/java/org/apache/bval/constraints/ bval-jsr303d/ bval-jsr303d/src/ bval-jsr303d/src/main/ bval-jsr303d/src/main/java/ bval-jsr303d/src/main/java/org/ bval-jsr303d/sr...
Date Wed, 22 Sep 2010 02:37:56 GMT
Author: mbenson
Date: Wed Sep 22 02:37:54 2010
New Revision: 999729

URL: http://svn.apache.org/viewvc?rev=999729&view=rev
Log:
initial add of the dynamic jsr303 module

Added:
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/constraints/AuthorAddressKnown.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/pom.xml   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractConstraintAppender.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericConstraintAppender.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericMultivaluedConstraintAppender.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesConstraintAppender.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesValidator.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/EnumValuesValidator.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/StringValuesValidator.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/Values.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/ValuesConstraintAppender.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/ConstraintAppender.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DefaultConstraintAppender.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManager.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationState.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationStateBean.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorContext.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorFactory.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/GroupValidationContextValidationState.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaCollection.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaContainer.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaMap.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/apache/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/apache/bval/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/apache/bval/constraints/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/apache/bval/constraints/dynamic/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/apache/bval/constraints/dynamic/ValuesConstraintValidationTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicBeanDescriptorTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicCircularReferencesTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicCollectionValidationTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicComposedConstraintsTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicConstraintCompositionTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicConstraintDefinitionsTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicExceptionsContractTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicJsr303Test.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicPayloadTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicTckReproducerTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicValidationTest.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/test/java/org/bval/jsr303/dynamic/DynamicValidatorResolutionTest.java   (with props)

Added: incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/constraints/AuthorAddressKnown.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/constraints/AuthorAddressKnown.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/constraints/AuthorAddressKnown.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/constraints/AuthorAddressKnown.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,75 @@
+/*
+ *  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.constraints;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.Payload;
+
+import org.apache.bval.jsr303.example.Address;
+import org.apache.bval.jsr303.example.Author;
+
+/**
+ * 
+ * 
+ * @version $Rev$ $Date$
+ */
+@Target( { ANNOTATION_TYPE, METHOD, FIELD })
+@Constraint(validatedBy = AuthorAddressKnown.Validator.class)
+@Retention(RUNTIME)
+public @interface AuthorAddressKnown {
+
+    String message() default "{org.apache.bval.constraints.AuthorAddressKnown.message}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default { };
+
+    public static class Validator implements ConstraintValidator<AuthorAddressKnown, Author> {
+
+        /**
+         * {@inheritDoc}
+         */
+        public void initialize(AuthorAddressKnown constraintAnnotation) {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean isValid(Author value, ConstraintValidatorContext context) {
+            if (value.getAddresses() == null) {
+                return false;
+            }
+            for (Address address : value.getAddresses()) {
+                if (address != null) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+    }
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/constraints/AuthorAddressKnown.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/constraints/AuthorAddressKnown.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Sep 22 02:37:54 2010
@@ -0,0 +1,4 @@
+*.log
+.*
+target
+maven-eclipse.xml

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/pom.xml
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/pom.xml?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/pom.xml (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/pom.xml Wed Sep 22 02:37:54 2010
@@ -0,0 +1,121 @@
+<?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.
+-->
+<!--
+	Maven release plugin requires the project tag to be on a single line.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.bval</groupId>
+        <artifactId>bval-parent</artifactId>
+        <version>0.3-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>bval-jsr303d</artifactId>
+    <name>Apache Bean Validation :: bval-jsr303d</name>
+    <packaging>bundle</packaging>
+
+    <description>Bean Validation - Dynamic extensions for JSR303</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.bval</groupId>
+            <artifactId>org.apache.bval.bundle</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.bval</groupId>
+            <artifactId>bval-jsr303</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-proxy2-stub</artifactId>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <!--
+            default profile using geronimo-validation_1.0_spec.jar
+            active when property "ri" is not present.
+        -->
+        <profile>
+            <id>geronimo</id>
+            <activation>
+                <property>
+                    <name>!ri</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.geronimo.specs</groupId>
+                    <artifactId>geronimo-validation_1.0_spec</artifactId>
+                    <!-- allow users to choose an API provider -->
+                    <scope>provided</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+        <!--
+            optional profile using javax.validation/validation-api.jar
+            from RI manually active when property "-Pri" is provided.
+        -->
+        <profile>
+            <id>ri</id>
+            <activation>
+                <property>
+                    <name>ri</name>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>javax.validation</groupId>
+                    <artifactId>validation-api</artifactId>
+                    <!-- allow users to choose an API provider -->
+                    <scope>provided</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+    <build>
+        <defaultGoal>install</defaultGoal>
+
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+        </resources>
+    </build>
+
+</project>

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractConstraintAppender.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractConstraintAppender.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractConstraintAppender.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractConstraintAppender.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,69 @@
+/*
+ *  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.constraints.dynamic;
+
+import java.lang.annotation.Annotation;
+
+import javax.validation.Payload;
+
+import org.apache.bval.jsr303.ConstraintAnnotationAttributes;
+import org.apache.bval.jsr303.dynamic.ConstraintAppender;
+import org.apache.bval.jsr303.groups.GroupsComputer;
+
+/**
+ * Provide basic functionality for {@link ConstraintAppender}s.
+ * 
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractConstraintAppender implements ConstraintAppender {
+    /**
+     * GroupsComputer for whatever purposes it may serve.
+     */
+    protected static final GroupsComputer GROUPS_COMPUTER = new GroupsComputer();
+
+    /**
+     * Get the validation message of the specified constraint.
+     * 
+     * @param constraint
+     * @return String
+     */
+    protected String getMessage(Annotation constraint) {
+        return (String) ConstraintAnnotationAttributes.MESSAGE.getValue(constraint);
+    }
+
+    /**
+     * Get the validation groups associated with the specified constraint.
+     * 
+     * @param constraint
+     * @return Class[]
+     */
+    protected Class<?>[] getGroups(Annotation constraint) {
+        return (Class<?>[]) ConstraintAnnotationAttributes.GROUPS.getValue(constraint);
+    }
+
+    /**
+     * Get the payload associated with the specified constraint.
+     * 
+     * @param constraint
+     * @return Class<? extends Payload>[]
+     */
+    @SuppressWarnings("unchecked")
+    protected Class<? extends Payload>[] getPayload(Annotation constraint) {
+        return (Class<? extends Payload>[]) ConstraintAnnotationAttributes.PAYLOAD.getValue(constraint);
+    }
+
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractConstraintAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractConstraintAppender.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericConstraintAppender.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericConstraintAppender.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericConstraintAppender.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericConstraintAppender.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,107 @@
+/*
+ *  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.constraints.dynamic;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.bval.jsr303.ConstraintAnnotationAttributes;
+import org.apache.bval.jsr303.dynamic.ConstraintAppender;
+import org.apache.bval.jsr303.groups.Groups;
+
+/**
+ * Convenience superclass for a {@link ConstraintAppender} that deals
+ * exclusively with a single constraint annotation type.
+ * 
+ * @param <A>
+ *            constraint type
+ * 
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractGenericConstraintAppender<A extends Annotation> extends AbstractConstraintAppender {
+
+    /**
+     * Constraint type.
+     */
+    protected final Class<A> constraintType;
+
+    /**
+     * Create a new AbstractGenericConstraintAppender instance.
+     * 
+     * @param constraintType
+     */
+    protected AbstractGenericConstraintAppender(Class<A> constraintType) {
+        super();
+        this.constraintType = constraintType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final boolean append(Annotation constraint, Collection<Annotation> collection) {
+        return appendSimple(constraint, collection) || doAppend(constraint, collection);
+    }
+
+    /**
+     * Implement a non-simple append process.
+     * 
+     * @param constraint
+     * @param collection
+     * @return whether the constraint was applied successfully.
+     */
+    @SuppressWarnings("unchecked")
+    protected boolean doAppend(Annotation constraint, Collection<Annotation> collection) {
+        return constraintType.isInstance(constraint) && appendTyped((A) constraint, collection);
+    }
+
+    /**
+     * Append the typed constraint to the collection.
+     * 
+     * @param constraint
+     * @param collection
+     * @return whether the constraint was applied successfully.
+     */
+    protected abstract boolean appendTyped(A constraint, Collection<Annotation> collection);
+
+    /**
+     * If permitted, simply append the constraint to the collection. Default
+     * implementation assumes that this operation would be precluded by an
+     * existing constraint of this type with overlapping groups.
+     * 
+     * @param constraint
+     * @param collection
+     * @return whether the constraint was applied successfully.
+     */
+    protected boolean appendSimple(Annotation constraint, Collection<Annotation> collection) {
+        if (!ConstraintAnnotationAttributes.GROUPS.isDeclaredOn(constraint.annotationType())) {
+            //non-constraint; don't know how to handle:
+            return false;
+        }
+        Groups groups = GROUPS_COMPUTER.computeGroups(getGroups(constraint));
+        for (Annotation a : collection) {
+            if (constraintType.isInstance(a)) {
+                if (Collections.disjoint(groups.getGroups(), GROUPS_COMPUTER.computeGroups(getGroups(a)).getGroups())) {
+                    continue;
+                }
+                return false;
+            }
+        }
+        return collection.add(constraint);
+    }
+
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericConstraintAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericConstraintAppender.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericMultivaluedConstraintAppender.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericMultivaluedConstraintAppender.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericMultivaluedConstraintAppender.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericMultivaluedConstraintAppender.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,109 @@
+/*
+ *  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.constraints.dynamic;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+
+import javax.validation.ConstraintDefinitionException;
+
+import org.apache.bval.jsr303.ConstraintAnnotationAttributes;
+import org.apache.commons.lang3.reflect.TypeUtils;
+
+/**
+ * {@link AbstractGenericConstraintAppender} with knowledge of the corresponding
+ * multivalued constraint annotation.
+ *
+ * @param <A>
+ *            constraint type
+ * @param <M>
+ *            multiple constraint type
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractGenericMultivaluedConstraintAppender<A extends Annotation, M extends Annotation> extends
+    AbstractGenericConstraintAppender<A> {
+
+    /**
+     * Annotation type that contains multiple A instances.
+     */
+    protected final Class<M> multipleConstraintType;
+
+    /**
+     * Create a new AbstractGenericMultivaluedConstraintAppender instance.
+     *
+     * @param constraintType
+     * @param multipleConstraintType
+     */
+    public AbstractGenericMultivaluedConstraintAppender(Class<A> constraintType, Class<M> multipleConstraintType) {
+        super(constraintType);
+        ConstraintAnnotationAttributes.VALUE.validateOn(multipleConstraintType);
+        this.multipleConstraintType = multipleConstraintType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean doAppend(Annotation constraint, Collection<Annotation> collection) {
+        if (multipleConstraintType.isInstance(constraint)) {
+            boolean result = false;
+            @SuppressWarnings("unchecked")
+            A[] singleAnnotations = getValue((M) constraint);
+            for (A single : singleAnnotations) {
+                result |= appendTyped(single, collection);
+            }
+            return result;
+        }
+        return super.doAppend(constraint, collection);
+    }
+
+    /**
+     * Get the array of A constraints from the multiple. Default implementation
+     * returns the value() member of the multiple.
+     *
+     * @param multiple
+     * @return A[]
+     */
+    @SuppressWarnings("unchecked")
+    protected A[] getValue(M multiple) {
+        Object result = ConstraintAnnotationAttributes.VALUE.getValue(multiple);
+        if (!TypeUtils.isAssignable(TypeUtils.getArrayComponentType(result.getClass()), constraintType)) {
+            throw new ConstraintDefinitionException(String.format(
+                "%s is not a valid multiple annotation container for %s", multipleConstraintType, constraintType));
+        }
+        return (A[]) result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean appendSimple(Annotation constraint, Collection<Annotation> collection) {
+        boolean foundSingles = false;
+        for (Annotation a : collection) {
+            if (multipleConstraintType.isInstance(a)) {
+                return false;
+            }
+            foundSingles |= constraintType.isInstance(a);
+        }
+        if (multipleConstraintType.isInstance(constraint)) {
+            return !foundSingles && collection.add(constraint);
+        }
+        return super.appendSimple(constraint, collection);
+    }
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericMultivaluedConstraintAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractGenericMultivaluedConstraintAppender.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesConstraintAppender.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesConstraintAppender.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesConstraintAppender.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesConstraintAppender.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,471 @@
+/*
+ *  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.constraints.dynamic;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+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;
+
+import javax.validation.ConstraintDefinitionException;
+import javax.validation.Payload;
+
+import org.apache.bval.constraints.dynamic.Values.Strategy;
+import org.apache.bval.constraints.dynamic.Values.Rule;
+import org.apache.bval.jsr303.groups.Group;
+import org.apache.bval.jsr303.groups.Groups;
+import org.apache.bval.jsr303.groups.GroupsComputer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.proxy2.stub.AnnotationFactory;
+import org.apache.commons.proxy2.stub.StubConfigurer;
+
+/**
+ * Templated implementation for managing values-based constraints.
+ * 
+ * @param <A>
+ *            constraint type
+ * @param <M>
+ *            multiple constraint type
+ * @param <V>
+ *            <code>A.value()</code> component type
+ * 
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractValuesConstraintAppender<A extends Annotation, M extends Annotation, V> extends
+    AbstractGenericMultivaluedConstraintAppender<A, M> {
+
+    private static final GroupsComputer GROUPS_COMPUTER = new GroupsComputer();
+
+    /**
+     * {@link AnnotationFactory} instance for annotation generation.
+     */
+    protected final AnnotationFactory annotationFactory = new AnnotationFactory();
+
+    /**
+     * Prototype for <code>Values.value()</code>.
+     */
+    protected final V[] emptyValueArray;
+
+    /**
+     * Prototype <code>Values.List.value()</code>.
+     */
+    protected final A[] emptyConstraintArray;
+
+    /**
+     * Create a new AbstractValuesConstraintAppender instance.
+     * 
+     * @param constraintType
+     * @param multipleConstraintType
+     * @param valueComponentType
+     */
+    @SuppressWarnings("unchecked")
+    public AbstractValuesConstraintAppender(Class<A> constraintType, Class<M> multipleConstraintType,
+        Class<V> valueComponentType) {
+        super(constraintType, multipleConstraintType);
+        emptyValueArray = (V[]) Array.newInstance(valueComponentType, 0);
+        emptyConstraintArray = (A[]) Array.newInstance(constraintType, 0);
+    }
+
+    private class CumulativeValues {
+        final Set<V> values = new HashSet<V>();
+        final Set<Class<? extends Payload>> payload = new HashSet<Class<? extends Payload>>();
+        final Set<String> message = new HashSet<String>();
+        final Strategy strategy;
+
+        /**
+         * Create a new AbstractCumulativeValues instance.
+         * 
+         * @param strategy
+         */
+        CumulativeValues(Strategy strategy) {
+            this.strategy = strategy;
+        }
+    }
+
+    /**
+     * Values holder.
+     */
+    private class ValuesMerger {
+        Map<Group, CumulativeValues> includedValuesByGroup = new HashMap<Group, CumulativeValues>();
+        Map<Group, CumulativeValues> excludedValuesByGroup = new HashMap<Group, CumulativeValues>();
+
+        /**
+         * Merge the specified constraint.
+         * 
+         * @param constraint
+         */
+        public void apply(A constraint) {
+            apply(constraint, false);
+        }
+
+        /**
+         * Merge the specified constraint.
+         * 
+         * @param constraint
+         * @param applyingModification
+         *            whether the constraint being applied is (one of) the
+         *            constraint(s) that began this append process
+         */
+        public void apply(A constraint, boolean applyingModification) {
+            // when we are applying the modification, the meaning of the rule
+            // changes
+            // depending on the existing inclusions/exclusions:
+
+            Rule rule = getRule(constraint);
+            Groups chain = GROUPS_COMPUTER.computeGroups(getGroups(constraint));
+
+            Strategy strategy = getStrategy(constraint);
+            if (strategy == Strategy.REPLACE) {
+                for (Group group : chain.getGroups()) {
+                    includedValuesByGroup.remove(group);
+                    excludedValuesByGroup.remove(group);
+                }
+            }
+
+            List<V> constraintValue = Arrays.asList(getConstraintValue(constraint));
+            for (Group group : chain.getGroups()) {
+                CumulativeValues includes = includedValuesByGroup.get(group);
+                CumulativeValues excludes = excludedValuesByGroup.get(group);
+
+                // inclusions may be inclusions OR negative exclusions, but not
+                // both
+                if (rule == Rule.INCLUDE) {
+                    boolean useNegativeExclusion = false;
+                    if (excludes != null) {
+
+                        if (applyingModification && excludes.values.containsAll(constraintValue)) {
+                            useNegativeExclusion = includes == null || includes.values.isEmpty();
+                        }
+                        excludes.values.removeAll(constraintValue);
+                    }
+
+                    if (!useNegativeExclusion) {
+                        if (includes == null) {
+                            includes = new CumulativeValues(strategy);
+                            includedValuesByGroup.put(group, includes);
+                        }
+                        includes.values.addAll(constraintValue);
+                        includes.payload.addAll(Arrays.asList(getPayload(constraint)));
+                        includes.message.add(getMessage(constraint));
+                    }
+                } else { // EXCLUDE
+                    // exclusions must always be exclusions as well as negative
+                    // inclusions
+                    boolean useNegativeInclusion = false;
+                    if (includes != null) {
+                        if (includes.values.containsAll(constraintValue)) {
+                            useNegativeInclusion = excludes == null || excludes.values.isEmpty();
+                        }
+                        includes.values.removeAll(constraintValue);
+                    }
+                    if (!useNegativeInclusion) {
+                        if (excludes == null) {
+                            excludes = new CumulativeValues(strategy);
+                            excludedValuesByGroup.put(group, excludes);
+                        }
+                        excludes.values.addAll(constraintValue);
+                        excludes.payload.addAll(Arrays.asList(getPayload(constraint)));
+                        excludes.message.add(getMessage(constraint));
+                    }
+                }
+            }
+        }
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean doAppend(Annotation constraint, Collection<Annotation> collection) {
+        List<A> singles;
+        if (multipleConstraintType.isInstance(constraint)) {
+            singles = Arrays.asList(getValue((M) constraint));
+        } else if (constraintType.isInstance(constraint)) {
+            singles = Collections.singletonList((A) constraint);
+        } else {
+            return false;
+        }
+        ValuesMerger valuesMerger = new ValuesMerger();
+
+        extractMultipleConstraints(collection, valuesMerger);
+        extractConstraints(collection, valuesMerger);
+
+        for (A single : singles) {
+            valuesMerger.apply(single, true);
+        }
+
+        // validateIncludes(valuesMerger.includedValuesByGroup);
+
+        ArrayList<A> results = new ArrayList<A>();
+        do {
+        } while (process(valuesMerger, results));
+
+        return results.isEmpty() || collection.add(createMultipleConstraint(results.toArray(emptyConstraintArray)));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected boolean appendTyped(A constraint, Collection<Annotation> collection) {
+        throw new UnsupportedOperationException("we have intercepted doAppend() so this should never be called");
+    }
+
+    private void extractMultipleConstraints(Collection<Annotation> collection, ValuesMerger into) {
+        for (Iterator<Annotation> iterator = collection.iterator(); iterator.hasNext();) {
+            Annotation existing = iterator.next();
+            if (multipleConstraintType.isInstance(existing)) {
+                iterator.remove();
+                @SuppressWarnings("unchecked")
+                M multiple = (M) existing;
+                for (A single : getValue(multiple)) {
+                    into.apply(single);
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void extractConstraints(Collection<Annotation> collection, ValuesMerger into) {
+        for (Iterator<Annotation> iterator = collection.iterator(); iterator.hasNext();) {
+            Annotation existing = iterator.next();
+            if (constraintType.isInstance(existing)) {
+                iterator.remove();
+                into.apply((A) existing);
+            }
+        }
+    }
+
+    /**
+     * If a constraint can be extracted, add it to the specified list.
+     * 
+     * @param valuesMerger
+     * @param includedExcludedConstraints
+     * @return <code>true</code> while more processing to be done.
+     */
+    private boolean process(ValuesMerger valuesMerger, Collection<A> constraints) {
+        Map<Group, CumulativeValues> valuesMap = valuesMerger.includedValuesByGroup;
+        Rule rule = Rule.INCLUDE;
+        if (valuesMap.isEmpty()) {
+            valuesMap = valuesMerger.excludedValuesByGroup;
+            if (valuesMap.isEmpty()) {
+                return false;
+            }
+            rule = Rule.EXCLUDE;
+        }
+        Group group = findFirstRootGroup(valuesMap.keySet());
+        if (group == null) {
+            throw new ConstraintDefinitionException(String.format("Can't find root group among %s", valuesMap.keySet()));
+        }
+        CumulativeValues values = valuesMap.remove(group);
+        HashSet<Class<?>> groups = new HashSet<Class<?>>();
+        groups.add(group.getGroup());
+        HashSet<Class<? extends Payload>> payloads = new HashSet<Class<? extends Payload>>(values.payload);
+        HashSet<String> messages = new HashSet<String>(values.message);
+        if (!values.values.isEmpty()) {
+            // merge groups with same values and strategy:
+            for (Iterator<Map.Entry<Group, CumulativeValues>> iter = valuesMap.entrySet().iterator(); iter.hasNext();) {
+                Map.Entry<Group, CumulativeValues> e = iter.next();
+                if (e.getValue().values.equals(values.values) && e.getValue().strategy == values.strategy) {
+                    iter.remove();
+                    // swallow groups that extend our base group:
+                    if (!group.getGroup().isAssignableFrom(e.getKey().getGroup())) {
+                        groups.add(e.getKey().getGroup());
+                    }
+                    payloads.addAll(e.getValue().payload);
+                    messages.addAll(e.getValue().message);
+                }
+
+            }
+
+            String message = StringUtils.join(messages, "; ");
+
+            @SuppressWarnings("unchecked")
+            Class<? extends Payload>[] payload = payloads.toArray(new Class[payloads.size()]);
+            A constraint =
+                annotationFactory.create(new AnnotationStubConfigurer(values.values.toArray(emptyValueArray), rule,
+                    message, groups.toArray(new Class[groups.size()]), payload, values.strategy));
+            constraints.add(constraint);
+        }
+        return valuesMerger.includedValuesByGroup.size() + valuesMerger.excludedValuesByGroup.size() > 0;
+    }
+
+    /**
+     * In a given set of groups, find the first one that does not extend any
+     * other group in the set.
+     * 
+     * @param groups
+     * @return Group
+     */
+    private Group findFirstRootGroup(Set<Group> groups) {
+        for (Group group : groups) {
+            boolean ok = true;
+            for (Group other : groups) {
+                if (other == group) {
+                    continue;
+                }
+                if (other.getGroup().isAssignableFrom(group.getGroup())) {
+                    ok = false;
+                    break;
+                }
+            }
+            if (ok) {
+                return group;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The annotation stub configurer we use.
+     */
+    private final class AnnotationStubConfigurer extends StubConfigurer<A> {
+        final V[] values;
+        final Rule rule;
+        final String message;
+        final Class<?>[] groups;
+        final Class<? extends Payload>[] payloads;
+        final Strategy strategy;
+
+        /**
+         * Create a new AnnotationStubConfigurer instance.
+         * 
+         * @param values
+         * @param rule
+         * @param message
+         * @param groups
+         * @param payloads
+         * @param strategy
+         */
+        public AnnotationStubConfigurer(V[] values, Rule rule, String message, Class<?>[] groups,
+            Class<? extends Payload>[] payloads, Strategy strategy) {
+            super(constraintType);
+            this.values = values;
+            this.rule = rule;
+            this.message = message;
+            this.groups = groups;
+            this.payloads = payloads;
+            this.strategy = strategy;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected void configure(A stub) {
+            when(getConstraintValue(stub)).thenReturn(values).when(getRule(stub)).thenReturn(rule)
+                .when(getMessage(stub)).thenReturn(message).when(getGroups(stub)).thenReturn(groups)
+                .when(getPayload(stub)).thenReturn(payloads).when(getStrategy(stub)).thenReturn(strategy);
+        }
+
+    }
+
+    /**
+     * Create a multiple constraint.
+     * 
+     * @param value
+     * @return M
+     */
+    protected abstract M createMultipleConstraint(A[] value);
+
+    /**
+     * Get the values of the specified constraint.
+     * 
+     * @param constraint
+     * @return V[]
+     */
+    protected abstract V[] getConstraintValue(A constraint);
+
+    /**
+     * Get the {@link Rule} of the specified constraint.
+     * 
+     * @param constraint
+     * @return {@link Rule}
+     */
+    protected abstract Values.Rule getRule(A constraint);
+
+    /**
+     * Get the {@link Strategy} of the specified constraint.
+     * 
+     * @param constraint
+     * @return {@link Strategy}
+     */
+    protected abstract Values.Strategy getStrategy(A constraint);
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    protected final String getMessage(Annotation constraint) {
+        return constraintType.isInstance(constraint) ? getTypedConstraintMessage((A) constraint) : super
+            .getMessage(constraint);
+    }
+
+    /**
+     * Get the <code>message()</code> from a typed <code>A</code> constraint.
+     * 
+     * @param constraint
+     * @return String
+     */
+    protected abstract String getTypedConstraintMessage(A constraint);
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    protected Class<?>[] getGroups(Annotation constraint) {
+        return constraintType.isInstance(constraint) ? getTypedConstraintGroups((A) constraint) : super
+            .getGroups(constraint);
+    }
+
+    /**
+     * Get the <code>groups()</code> from a typed <code>A</code> constraint.
+     * 
+     * @param constraint
+     * @return Class<?>[]
+     */
+    protected abstract Class<?>[] getTypedConstraintGroups(A constraint);
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    protected final Class<? extends Payload>[] getPayload(Annotation constraint) {
+        return constraintType.isInstance(constraint) ? getTypedConstraintPayload((A) constraint) : super
+            .getPayload(constraint);
+    }
+
+    /**
+     * Get the <code>payload()</code> from a typed <code>A</code> constraint.
+     * 
+     * @param constraint
+     * @return Class<? extends Payload>[]
+     */
+    protected abstract Class<? extends Payload>[] getTypedConstraintPayload(A constraint);
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesConstraintAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesConstraintAppender.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesValidator.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesValidator.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesValidator.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,138 @@
+/*
+ *  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.constraints.dynamic;
+
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+import org.apache.bval.constraints.dynamic.Values.Rule;
+
+/**
+ * Abstract {@link ConstraintValidator} for a {@link Values} or
+ * {@link Values.Labeled} constraint.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractValuesValidator<A extends Annotation, T> implements ConstraintValidator<A, T> {
+
+    private Set<String> choices;
+    private Values.Rule inclusivity;
+
+    /**
+     * {@inheritDoc}
+     */
+    public void initialize(A constraintAnnotation) {
+        this.choices = new HashSet<String>();
+        addChoicesFrom(constraintAnnotation, this.choices);
+        this.inclusivity = getInclusivity(constraintAnnotation);
+    }
+
+    /**
+     * Add the value choices extracted from <code>constraint</code> to
+     * <code>toSet</code>.
+     *
+     * @param toSet
+     */
+    protected abstract void addChoicesFrom(A constraint, Set<String> toSet);
+
+    /**
+     * Extract an {@link Rule} from the specified constraint.
+     *
+     * @param constraint
+     * @return {@link Rule}
+     */
+    protected abstract Values.Rule getInclusivity(A constraint);
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isValid(T value, ConstraintValidatorContext context) {
+        if (value == null) {
+            return true;
+        }
+        boolean matched = false;
+        for (String choice : choices) {
+            if (matches(value, choice)) {
+                matched = true;
+                break;
+            }
+        }
+        return matched ^ inclusivity == Rule.EXCLUDE;
+    }
+
+    /**
+     * Learn whether a choice matches the actual value.
+     *
+     * @param value
+     * @param choice
+     * @return whether a match was made
+     */
+    protected abstract boolean matches(T value, String choice);
+
+    /**
+     * Partial implementation of {@link Values} validation.
+     *
+     * @param <T>
+     */
+    public static abstract class Plain<T> extends AbstractValuesValidator<Values, T> {
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected void addChoicesFrom(Values constraint, Set<String> toSet) {
+            toSet.addAll(Arrays.asList(constraint.value()));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Rule getInclusivity(Values constraint) {
+            return constraint.rule();
+        }
+    }
+
+    /**
+     * Partial implementation of {@link Values.Labeled} validation.
+     *
+     * @param <T>
+     */
+    public static abstract class Labeled<T> extends AbstractValuesValidator<Values.Labeled, T> {
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected void addChoicesFrom(org.apache.bval.constraints.dynamic.Values.Labeled constraint, Set<String> toSet) {
+            for (Values.Labeled.Item item : constraint.value()) {
+                toSet.add(item.value());
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Rule getInclusivity(org.apache.bval.constraints.dynamic.Values.Labeled constraint) {
+            return constraint.rule();
+        }
+    }
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/AbstractValuesValidator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/EnumValuesValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/EnumValuesValidator.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/EnumValuesValidator.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/EnumValuesValidator.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,43 @@
+/*
+ *  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.constraints.dynamic;
+
+/**
+ * Validates {@link Values} annotations against enum constants.
+ *
+ * @version $Rev$ $Date$
+ */
+public class EnumValuesValidator extends AbstractValuesValidator.Plain<Enum<?>> {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean matches(Enum<?> value, String choice) {
+        return value.name().equals(choice);
+    }
+
+    public static class Labeled extends AbstractValuesValidator.Labeled<Enum<?>> {
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected boolean matches(Enum<?> value, String choice) {
+            return value.name().equals(choice);
+        }
+    }
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/EnumValuesValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/EnumValuesValidator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/StringValuesValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/StringValuesValidator.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/StringValuesValidator.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/StringValuesValidator.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,54 @@
+/*
+ *  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.constraints.dynamic;
+
+import javax.validation.ConstraintValidator;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * {@link ConstraintValidator} for {@link Values} constraints on
+ * {@link CharSequence} types.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class StringValuesValidator extends AbstractValuesValidator.Plain<CharSequence> {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean matches(CharSequence value, String choice) {
+        return StringUtils.equals(value, choice);
+    }
+
+    /**
+     * {@link ConstraintValidator} for {@link Values.Labeled} constraints on
+     * {@link String} types.
+     */
+    public static class Labeled extends AbstractValuesValidator.Labeled<CharSequence> {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected boolean matches(CharSequence value, String choice) {
+            return StringUtils.equals(value, choice);
+        }
+
+    }
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/StringValuesValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/StringValuesValidator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/Values.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/Values.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/Values.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/Values.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,193 @@
+/*
+ *  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.constraints.dynamic;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+import org.apache.bval.jsr303.dynamic.ConstraintAppender;
+
+/**
+ * <p>
+ * Allows the specification of discrete values either allowed or disallowed for
+ * a property. This class functions as an exercise of the
+ * {@link ConstraintAppender} portion of the dynamic bean validation
+ * implementation.
+ * </p>
+ * <p>
+ * Because of the type limitations on Java annotations, it is not feasible to
+ * write an open-ended constraint annotation to allow the specification of
+ * strongly-typed values. It <em>is</em> feasible, however, to write validators
+ * for various types assuming that a reliable strategy for string conversion of
+ * a given type is available.
+ * </p>
+ * 
+ * @version $Rev$ $Date$
+ */
+@Documented
+@Target({ METHOD, FIELD, ANNOTATION_TYPE, PARAMETER })
+@Retention(RUNTIME)
+@Constraint(validatedBy = { StringValuesValidator.class, EnumValuesValidator.class })
+@ConstraintAppender.Use(ValuesConstraintAppender.class)
+public @interface Values {
+    /**
+     * String values handled.
+     * 
+     * @return String[]
+     */
+    String[] value();
+
+    /**
+     * Values handling.
+     * 
+     * @return {@link Rule}
+     */
+    Rule rule() default Rule.INCLUDE;
+
+    /**
+     * Append strategy for the constraint instance.
+     * 
+     * @return {@link Strategy}
+     */
+    Strategy strategy() default Strategy.REPLACE;
+
+    String message() default "{org.apache.bval.constraints.dynamic.Values}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+
+    /**
+     * List of {@link Values} annotation; typically not used directly, but
+     * utilized by {@link Appender}.
+     */
+    @Documented
+    @Target({ METHOD, FIELD, ANNOTATION_TYPE, PARAMETER })
+    @Retention(RUNTIME)
+    @ConstraintAppender.Use(ValuesConstraintAppender.class)
+    public @interface List {
+        /**
+         * Held {@link Values} constraints.
+         * 
+         * @return Values[]
+         */
+        Values[] value() default {};
+    }
+
+    /**
+     * Labeled values constraint for those occasions where it is necessary for a
+     * human-consumable label to accompany a data value. Arguably more properly
+     * the concern of the view technology of an application, this constraint is
+     * a concession to the concept that there may be times when it is
+     * appropriate to pair a value and its label so low as an application's
+     * business/validation layer.
+     */
+    @Documented
+    @Target({ METHOD, FIELD, ANNOTATION_TYPE, PARAMETER })
+    @Retention(RUNTIME)
+    @Constraint(validatedBy = { StringValuesValidator.Labeled.class, EnumValuesValidator.Labeled.class })
+    @ConstraintAppender.Use(ValuesConstraintAppender.Labeled.class)
+    public @interface Labeled {
+
+        /**
+         * Labeled values item.
+         */
+        public @interface Item {
+            /**
+             * Label for this item.
+             * 
+             * @return String
+             */
+            String label();
+
+            /**
+             * Value for this item.
+             * 
+             * @return String
+             */
+            String value();
+        }
+
+        /**
+         * Labeled value items.
+         * 
+         * @return Item[]
+         */
+        Item[] value();
+
+        /**
+         * Values handling.
+         * 
+         * @return {@link Rule}
+         */
+        Rule rule() default Rule.INCLUDE;
+
+        /**
+         * Append strategy for the constraint instance.
+         * 
+         * @return {@link Strategy}
+         */
+        Strategy strategy() default Strategy.REPLACE;
+
+        String message() default "{org.apache.bval.constraints.dynamic.Values.Labeled}";
+
+        Class<?>[] groups() default {};
+
+        Class<? extends Payload>[] payload() default {};
+
+        /**
+         * Labeled values list.
+         */
+        @Documented
+        @Target({ METHOD, FIELD, ANNOTATION_TYPE, PARAMETER })
+        @Retention(RUNTIME)
+        @ConstraintAppender.Use(ValuesConstraintAppender.Labeled.class)
+        public @interface List {
+            /**
+             * Held {@link Values.Labeled} constraints.
+             * 
+             * @return Values.Labeled[]
+             */
+            Values.Labeled[] value() default {};
+        }
+    }
+
+    /**
+     * Describes the intended handling of values specified by
+     * {@link Values#value()}.
+     */
+    public enum Rule {
+        INCLUDE, EXCLUDE;
+    }
+
+    /**
+     * Append strategy.
+     */
+    public enum Strategy {
+        MERGE, REPLACE;
+    }
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/Values.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/Values.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/ValuesConstraintAppender.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/ValuesConstraintAppender.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/ValuesConstraintAppender.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/ValuesConstraintAppender.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,178 @@
+/*
+ *  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.constraints.dynamic;
+
+import javax.validation.Payload;
+
+import org.apache.bval.constraints.dynamic.Values.Strategy;
+import org.apache.bval.constraints.dynamic.Values.Rule;
+import org.apache.bval.jsr303.dynamic.ConstraintAppender;
+import org.apache.commons.proxy2.stub.StubConfigurer;
+
+/**
+ * {@link ConstraintAppender} for {@link Values} constraints.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class ValuesConstraintAppender extends AbstractValuesConstraintAppender<Values, Values.List, String> {
+
+    /**
+     * Create a new ValuesConstraintAppender instance.
+     */
+    public ValuesConstraintAppender() {
+        super(Values.class, Values.List.class, String.class);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Rule getRule(Values constraint) {
+        return constraint.rule();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Values.List createMultipleConstraint(final Values[] value) {
+        return annotationFactory.create(new StubConfigurer<Values.List>() {
+
+            @Override
+            protected void configure(Values.List stub) {
+                when(stub.value()).thenReturn(value);
+            }
+        });
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String[] getConstraintValue(Values constraint) {
+        return constraint.value();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Strategy getStrategy(Values constraint) {
+        return constraint.strategy();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String getTypedConstraintMessage(Values constraint) {
+        return constraint.message();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Class<?>[] getTypedConstraintGroups(Values constraint) {
+        return constraint.groups();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Class<? extends Payload>[] getTypedConstraintPayload(Values constraint) {
+        return constraint.payload();
+    }
+
+    /**
+     * {@link Values.Labeled} constraint appender.
+     */
+    public static class Labeled extends
+        AbstractValuesConstraintAppender<Values.Labeled, Values.Labeled.List, Values.Labeled.Item> {
+
+        /**
+         * Create a new ValuesConstraintAppender instance.
+         */
+        public Labeled() {
+            super(Values.Labeled.class, Values.Labeled.List.class, Values.Labeled.Item.class);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Values.Labeled.List createMultipleConstraint(final Values.Labeled[] value) {
+            return annotationFactory.create(new StubConfigurer<Values.Labeled.List>() {
+
+                @Override
+                protected void configure(Values.Labeled.List stub) {
+                    when(stub.value()).thenReturn(value);
+                }
+            });
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Values.Labeled.Item[] getConstraintValue(Values.Labeled constraint) {
+            return constraint.value();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Rule getRule(Values.Labeled constraint) {
+            return constraint.rule();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Strategy getStrategy(Values.Labeled constraint) {
+            return constraint.strategy();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected String getTypedConstraintMessage(Values.Labeled constraint) {
+            return constraint.message();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Class<?>[] getTypedConstraintGroups(Values.Labeled constraint) {
+            return constraint.groups();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected Class<? extends Payload>[] getTypedConstraintPayload(Values.Labeled constraint) {
+            return constraint.payload();
+        }
+    }
+
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/ValuesConstraintAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/constraints/dynamic/ValuesConstraintAppender.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/ConstraintAppender.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/ConstraintAppender.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/ConstraintAppender.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/ConstraintAppender.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,100 @@
+/*
+ *  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.jsr303.dynamic;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Collection;
+
+import org.apache.bval.jsr303.util.SecureActions;
+
+/**
+ * Interface specifying a means of applying a constraint annotation to a
+ * collection of same, thus allowing for the situation where the addition of a
+ * constraint must result in the eviction or modification of existing
+ * constraints, the added constraint, or, indeed, any imaginable combination
+ * thereof. Caveat: Because dynamic constraints must be applied multiple times
+ * (i.e. setup vs. "playback"), it's important that a {@link ConstraintAppender}
+ * always contribute something to the collection, even when the true intent is
+ * to do nothing.
+ * 
+ * @version $Rev$ $Date$
+ */
+public interface ConstraintAppender {
+
+    /**
+     * Meta-annotation to specify a {@link ConstraintAppender} implementation
+     * that knows how to manage a given jsr303 annotation.
+     */
+    @Documented
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ ElementType.ANNOTATION_TYPE })
+    public @interface Use {
+        Class<? extends ConstraintAppender> value();
+    }
+
+    /**
+     * Factory class
+     */
+    public static final class Factory {
+        /**
+         * Create a new ConstraintAppender.Factory instance.
+         */
+        private Factory() {
+        }
+
+        /**
+         * Get a constraint appender for the specified constraint. If the
+         * constraint does not declare an annotation method of
+         * {@link ConstraintAppender#TYPE_ATTRIBUTE} returning
+         * <code>Class<? extends {@link ConstraintAppender}></code>,
+         * {@link DefaultConstraintAppender#INSTANCE} will be used.
+         * 
+         * @param constraint
+         * @return {@link ConstraintAppender}
+         */
+        public ConstraintAppender constraintAppender(Annotation constraint) {
+            try {
+                Use use = constraint.annotationType().getAnnotation(Use.class);
+                Class<? extends ConstraintAppender> appenderType = use.value();
+                if (appenderType != null) {
+                    return SecureActions.newInstance(appenderType);
+                }
+            } catch (RuntimeException e) {
+            }
+            return DefaultConstraintAppender.INSTANCE;
+        }
+    }
+
+    /**
+     * Factory instance.
+     */
+    public static final Factory FACTORY = new Factory();
+
+    /**
+     * Append <code>constraint</code> to <code>collection</code>.
+     * 
+     * @param constraint
+     * @param collection
+     * @return whether the constraint was applied successfully.
+     */
+    boolean append(Annotation constraint, Collection<Annotation> collection);
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/ConstraintAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/ConstraintAppender.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DefaultConstraintAppender.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DefaultConstraintAppender.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DefaultConstraintAppender.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DefaultConstraintAppender.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,56 @@
+/*
+ *  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.jsr303.dynamic;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+
+import org.apache.commons.lang3.AnnotationUtils;
+
+/**
+ * Default {@link ConstraintAppender} implementation. Adds unique constraints to
+ * the collection.
+ *
+ * @see Annotation#equals(Object)
+ *
+ * @version $Rev$ $Date$
+ */
+public final class DefaultConstraintAppender implements ConstraintAppender {
+    /**
+     * Static instance.
+     */
+    public static final DefaultConstraintAppender INSTANCE = new DefaultConstraintAppender();
+
+    /**
+     * Create a new DefaultAppendConstraint instance.
+     */
+    private DefaultConstraintAppender() {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean append(Annotation constraint, Collection<Annotation> collection) {
+        for (Annotation element : collection) {
+            if (AnnotationUtils.equals(constraint, element)) {
+                return false;
+            }
+        }
+        return collection.add(constraint);
+    }
+
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DefaultConstraintAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DefaultConstraintAppender.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



Mime
View raw message