bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject svn commit: r999729 [2/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
Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,219 @@
+/*
+ *  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.util.Collections;
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.validation.metadata.BeanDescriptor;
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.PropertyDescriptor;
+
+import org.apache.bval.jsr303.BeanDescriptorImpl;
+import org.apache.bval.jsr303.ClassValidator;
+import org.apache.bval.jsr303.ElementDescriptorImpl;
+import org.apache.bval.jsr303.GroupValidationContext;
+import org.apache.bval.model.Features;
+import org.apache.bval.model.MetaBean;
+import org.apache.bval.model.MetaProperty;
+import org.apache.bval.model.Validation;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.Validate;
+
+/**
+ * {@link Validator} implementation that cooperates to handle context-specific
+ * dynamic validation constraints.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DynamicClassValidator extends ClassValidator {
+    /**
+     * Create a new {@link DynamicClassValidator} instance.
+     */
+    public DynamicClassValidator(DynamicValidatorContext validatorContext) {
+        super(validatorContext);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {
+        try {
+            return super.validate(object, groups);
+        } finally {
+            factoryContext().clearValidationState();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, boolean cascade,
+        Class<?>... groups) {
+        try {
+            return super.validateProperty(object, propertyName, cascade, groups);
+        } finally {
+            factoryContext().clearValidationState();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
+        boolean cascade, Class<?>... groups) {
+        try {
+            return super.validateValue(beanType, propertyName, value, cascade, groups);
+        } finally {
+            factoryContext().clearValidationState();
+        }
+    }
+
+    /**
+     * Convenience method to get the strongly typed
+     * {@link DynamicValidatorContext}.
+     *
+     * @return {@link DynamicValidatorContext}
+     */
+    protected DynamicValidatorContext factoryContext() {
+        return (DynamicValidatorContext) factoryContext;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected <T> GroupValidationContext<T> createContext(MetaBean metaBean, T object, Class<T> objectClass,
+        Class<?>... groups) {
+        GroupValidationContext<T> result = super.createContext(metaBean, object, objectClass, groups);
+        factoryContext().register(new GroupValidationContextValidationState(object, result));
+        return result;
+    }
+
+    /**
+     * Create a dynamic {@link BeanDescriptor}. This character overrides
+     * {@link BeanDescriptor#getConstraintsForProperty(String)} to accept path
+     * expressions and return dynamically calculated constraints.
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
+        return new DynamicBeanDescriptorImpl(metaBean);
+    }
+
+    private class DynamicBeanDescriptorImpl extends BeanDescriptorImpl {
+
+        /**
+         * Create a new DynamicBeanDescriptorImpl instance.
+         *
+         * @param factoryContext
+         * @param metaBean
+         */
+        protected DynamicBeanDescriptorImpl(MetaBean metaBean) {
+            super(factoryContext(), metaBean);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public Set<ConstraintDescriptor<?>> getConstraintDescriptors() {
+            MetaBean dynamicInfo = factoryContext().getMetaBeanFinder().findForClass(elementClass);
+            if (dynamicInfo == null) {
+                // wtf?
+                return super.getConstraintDescriptors();
+            }
+            return Collections.unmodifiableSet(getConstraintDescriptors(dynamicInfo.getValidations()));
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public PropertyDescriptor getConstraintsForProperty(String propertyName) {
+            Validate.isTrue(StringUtils.isNotEmpty(propertyName), "Invalid path '%s'", propertyName);
+
+            try {
+                GroupValidationContext<?> validationContext = createContext(metaBean, null, metaBean.getBeanClass());
+
+                try {
+                    nestedPathNavigator.navigate(validationContext, propertyName);
+                } catch (ValidationException e) {
+                    return null;
+                }
+
+                boolean cascaded;
+                Class<?> propertyType;
+                Validation[] validations;
+                MetaProperty prop = validationContext.getMetaProperty();
+                if (prop != null) {
+                    cascaded = prop.getMetaBean() != null || prop.getFeature(Features.Property.REF_CASCADE) != null;
+                    propertyType = prop.getTypeClass();
+                    validations = prop.getValidations();
+                } else { // must be in iterable:
+                    cascaded = true;
+                    propertyType = validationContext.getMetaBean().getBeanClass();
+                    validations = validationContext.getMetaBean().getValidations();
+                }
+                return new DynamicPropertyDescriptorImpl(metaBean, propertyName, propertyType, cascaded, validations);
+            } finally {
+                factoryContext().clearValidationState();
+            }
+
+        }
+    }
+
+    private static class DynamicPropertyDescriptorImpl extends ElementDescriptorImpl implements PropertyDescriptor {
+        private final String propertyName;
+        private final boolean cascaded;
+
+        /**
+         * Create a new DynamicPropertyDescriptorImpl instance.
+         *
+         * @param metaBean
+         * @param propertyName
+         * @param elementClass
+         * @param cascaded
+         * @param validations
+         */
+        protected DynamicPropertyDescriptorImpl(MetaBean metaBean, String propertyName, Class<?> elementClass,
+            boolean cascaded, Validation[] validations) {
+            super(metaBean, elementClass, validations);
+            this.propertyName = propertyName;
+            this.cascaded = cascaded;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public String getPropertyName() {
+            return propertyName;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean isCascaded() {
+            return cascaded;
+        }
+
+    }
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManager.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManager.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManager.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManager.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,78 @@
+/*
+ *  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 org.apache.bval.model.FeaturesCapable;
+import org.apache.bval.model.MetaBean;
+
+/**
+ * Defines an interface to manage a graph of {@link FeaturesCapable}+ objects
+ * rooted at a {@link MetaBean}.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface DynamicMetaGraphManager {
+
+    /**
+     * Describes the interface for handling metadata.
+     */
+    public interface Interface {
+        /**
+         * Get the MetaBean representing the specified type.
+         *
+         * @param type
+         * @return MetaBean
+         */
+        MetaBean getMetaBean(Class<?> type);
+
+        /**
+         * Get the meta-object representing <code>propertyPath</code> relative
+         * to <code>type</code>.
+         *
+         * @param <T>
+         * @param type
+         * @param propertyPath
+         * @return FeaturesCapable; typically MetaBean for root or indexed/keyed
+         *         paths; MetaProperty otherwise.
+         */
+        <T extends FeaturesCapable> T getMeta(Class<?> type, String propertyPath);
+    }
+
+    /**
+     * Return a {@link DynamicMetaGraphManager.Interface} for reading metadata.
+     * Results are merged; i.e. features on member <code>bar</code> of type
+     * <code>Bar</code> on class <code>Foo</code> will be merged with features
+     * that have been explicitly granted to class <code>Bar</code>. Features are
+     * merged in order of shortest property path to longest, thus
+     * <code>Foo.bar</code> features will override conflicting features of
+     * <code>Bar</code>. The nearer a node is to the root of the graph, the more
+     * precedence is given its dynamic features.
+     *
+     * @return readable instance whose results cannot affect future
+     *         {@link #forRead()} results.
+     */
+    Interface readOnly();
+
+    /**
+     * Return an {@link DynamicMetaGraphManager.Interface} for writing metadata.
+     * Querying is less than wholly meaningful because results are non-merged.
+     *
+     * @return an instance whose results are live and will affect future
+     *         {@link #forRead()} results.
+     */
+    Interface writable();
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,228 @@
+/*
+ *  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 static org.apache.bval.jsr303.dynamic.DynamicModel.Features.*;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.bval.jsr303.ConstraintValidation;
+import org.apache.bval.model.FeaturesCapable;
+import org.apache.bval.model.MetaBean;
+import org.apache.bval.model.MetaProperty;
+import org.apache.bval.model.Validation;
+import org.apache.bval.util.IndexedAccess;
+import org.apache.bval.util.KeyedAccess;
+import org.apache.bval.util.PropertyAccess;
+
+/**
+ * Utilities for working with the core + dynamic meta-model classes.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class DynamicModel {
+    /**
+     * Feature keys.
+     */
+    public interface Features {
+        /**
+         * Dynamic constraint collection feature key
+         */
+        public static final String DYNAMIC_CONSTRAINT_COLLECTION = "dynamicConstraintCollection";
+
+        /** meta-container key */
+        public static final String META_CONTAINER = "metaContainer";
+    }
+
+    private DynamicModel() {
+
+    }
+
+    /**
+     * Copy source to target MetaBeans.
+     * 
+     * @param target
+     * @param source
+     */
+    public static void copy(MetaBean target, MetaBean source) {
+        if (source == null) {
+            return;
+        }
+        target.setBeanClass(source.getBeanClass());
+        for (MetaProperty property : source.getProperties()) {
+            copy(getRequiredProperty(target, property.getName()), property);
+        }
+        copyConstraints(target, source);
+    }
+
+    /**
+     * Get or create the named property from <code>metaBean</code>.
+     * 
+     * @param metaBean
+     * @param name
+     * @return MetaProperty
+     */
+    public static MetaProperty getRequiredProperty(MetaBean metaBean, String name) {
+        MetaProperty result = metaBean.getProperty(name);
+        if (result == null) {
+            result = new MetaProperty();
+            result.setName(name);
+            result.setParentMetaBean(metaBean);
+            result.setType(new PropertyAccess(metaBean.getBeanClass(), name).getJavaType());
+            MetaBean propertyBean = new MetaBean();
+            propertyBean.setBeanClass(result.getTypeClass());
+            result.setMetaBean(propertyBean);
+            metaBean.putProperty(name, result);
+        }
+        return result;
+    }
+
+    /**
+     * Get or create a MetaContainer for the specified property.
+     * 
+     * @param property
+     * @return MetaContainer
+     * @throws IllegalArgumentException
+     *             if the property doesn't seem to refer to a container
+     */
+    public static MetaContainer<?> getRequiredContainer(MetaProperty property) {
+        MetaContainer<?> result = property.getFeature(META_CONTAINER);
+        if (result == null) {
+            if (KeyedAccess.getJavaElementType(property.getType()) != null) {
+                result = new MetaMap(property);
+            } else if (IndexedAccess.getJavaElementType(property.getType()) != null) {
+                result = new MetaCollection(property);
+            } else {
+                throw new IllegalArgumentException("don't know how to make a container of " + property + " of "
+                    + property.getParentMetaBean());
+            }
+            property.putFeature(META_CONTAINER, result);
+        }
+        return result;
+    }
+
+    /**
+     * Copy source to target {@link MetaProperty}.
+     * 
+     * @param target
+     * @param source
+     */
+    public static void copy(MetaProperty target, MetaProperty source) {
+        copyConstraints(target, source);
+
+        if (KeyedAccess.getJavaElementType(source.getType()) != null
+            || IndexedAccess.getJavaElementType(source.getType()) != null) {
+
+            MetaContainer<?> sourceContainer = source.getFeature(META_CONTAINER);
+            if (sourceContainer == null) {
+                return;
+            }
+            MetaContainer<?> targetContainer = getRequiredContainer(target);
+
+            if (!sourceContainer.getIdType().isAssignableFrom(targetContainer.getIdType())) {
+                throw new IllegalStateException(String.format("Mismatched container id types: %s[%s] vs. %s[%s]",
+                    source.getName(), sourceContainer.getIdType(), target.getName(), targetContainer.getIdType()));
+            }
+            if (Integer.class.equals(targetContainer.getIdType())) {
+                @SuppressWarnings("unchecked")
+                final MetaContainer<Integer> targetCollection = (MetaContainer<Integer>) targetContainer;
+                @SuppressWarnings("unchecked")
+                final MetaContainer<Integer> sourceCollection = (MetaContainer<Integer>) sourceContainer;
+                copy(targetCollection, sourceCollection);
+            } else if (String.class.equals(targetContainer.getIdType())) {
+                @SuppressWarnings("unchecked")
+                final MetaContainer<String> targetMap = (MetaContainer<String>) targetContainer;
+                @SuppressWarnings("unchecked")
+                final MetaContainer<String> sourceMap = (MetaContainer<String>) sourceContainer;
+                copy(targetMap, sourceMap);
+            }
+        } else {
+            copy(target.getMetaBean(), source.getMetaBean());
+        }
+    }
+
+    /**
+     * Typesafe helper method.
+     * 
+     * @param <K>
+     * @param targetContainer
+     * @param sourceContainer
+     */
+    private static <K> void copy(MetaContainer<K> targetContainer, MetaContainer<K> sourceContainer) {
+        copy(targetContainer.getPrototype(), sourceContainer.getPrototype());
+        for (Map.Entry<K, MetaBean> e : sourceContainer.getElements().entrySet()) {
+            copy(targetContainer.getElement(e.getKey()), e.getValue());
+        }
+    }
+
+    /**
+     * Copy constraints from source to target meta.
+     * 
+     * @param target
+     * @param source
+     */
+    public static boolean copyConstraints(FeaturesCapable target, FeaturesCapable source) {
+        Collection<Annotation> targetConstraints = target.getFeature(DYNAMIC_CONSTRAINT_COLLECTION);
+        Collection<Annotation> sourceConstraints = source.getFeature(DYNAMIC_CONSTRAINT_COLLECTION);
+        if (sourceConstraints == null || sourceConstraints.isEmpty()) {
+            return false;
+        }
+        targetConstraints = getRequiredDynamicConstraints(target);
+
+        // treat the target's preexisting ConstraintValidations like early arrivals to the dynamic constraints: 
+        ArrayList<Validation> ignoredValidations = new ArrayList<Validation>();
+        for (Validation v : target.getValidations()) {
+            if (v instanceof ConstraintValidation<?>) {
+                Annotation constraint = ((ConstraintValidation<?>) v).getAnnotation();
+                ConstraintAppender.FACTORY.constraintAppender(constraint).append(constraint, targetConstraints);
+            } else {
+                ignoredValidations.add(v);
+            }
+        }
+        if (ignoredValidations.size() < target.getValidations().length) {
+            target.setValidations(ignoredValidations.toArray(new Validation[ignoredValidations.size()]));
+        }
+
+        boolean result = false;
+        for (Annotation constraint : sourceConstraints) {
+            result |= ConstraintAppender.FACTORY.constraintAppender(constraint).append(constraint, targetConstraints);
+        }
+        return result;
+    }
+
+    /**
+     * Get or create the dynamic constraints collection from <code>meta</code>.
+     * 
+     * @param meta
+     * @return Collection<Annotation>
+     */
+    public static Collection<Annotation> getRequiredDynamicConstraints(FeaturesCapable meta) {
+        Collection<Annotation> result = meta.getFeature(DYNAMIC_CONSTRAINT_COLLECTION);
+        if (result == null) {
+            result = Collections.synchronizedList(new ArrayList<Annotation>());
+            meta.optimizeRead(false);
+            meta.putFeature(DYNAMIC_CONSTRAINT_COLLECTION, result);
+            meta.optimizeRead(true);
+        }
+        return result;
+    }
+
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationState.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationState.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationState.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationState.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,45 @@
+/*
+ *  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 org.apache.bval.jsr303.util.PathImpl;
+import org.apache.bval.model.MetaBean;
+
+/**
+ * Encapsulates the state of a validation.
+ *
+ * @version $Rev$ $Date$
+ */
+interface DynamicValidationState {
+    /**
+     * Get the root bean being validated.
+     * @return Object
+     */
+    Object getRootBean();
+
+    /**
+     * Get the {@link MetaBean} representing the root of this validation.
+     * @return MetaBean
+     */
+    MetaBean getRootMetaBean();
+
+    /**
+     * Get the property path representing the current context of this validation.
+     * @return {@link PathImpl}
+     */
+    PathImpl getPropertyPath();
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationStateBean.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationStateBean.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationStateBean.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidationStateBean.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,67 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.bval.jsr303.dynamic;
+
+import org.apache.bval.jsr303.util.PathImpl;
+import org.apache.bval.model.MetaBean;
+
+/**
+ * Freestanding {@link DynamicValidationState} implementation.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class DynamicValidationStateBean implements DynamicValidationState {
+    private final Object rootBean;
+    private final MetaBean rootMetaBean;
+    private final PathImpl propertyPath;
+
+    /**
+     * Create a new DynamicValidationStateBean instance.
+     * 
+     * @param rootBean
+     * @param rootMetaBean
+     * @param propertyPath
+     */
+    public DynamicValidationStateBean(Object rootBean, MetaBean rootMetaBean, PathImpl propertyPath) {
+        super();
+        this.rootBean = rootBean;
+        this.rootMetaBean = rootMetaBean;
+        this.propertyPath = propertyPath;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object getRootBean() {
+        return rootBean;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MetaBean getRootMetaBean() {
+        return rootMetaBean;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PathImpl getPropertyPath() {
+        return propertyPath;
+    }
+
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorContext.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorContext.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorContext.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorContext.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,536 @@
+/*
+ *  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 static org.apache.bval.jsr303.dynamic.DynamicModel.copyConstraints;
+import static org.apache.bval.jsr303.dynamic.DynamicModel.getRequiredContainer;
+import static org.apache.bval.jsr303.dynamic.DynamicModel.getRequiredDynamicConstraints;
+import static org.apache.bval.jsr303.dynamic.DynamicModel.getRequiredProperty;
+import static org.apache.bval.jsr303.dynamic.DynamicModel.Features.DYNAMIC_CONSTRAINT_COLLECTION;
+import static org.apache.bval.jsr303.dynamic.DynamicModel.Features.META_CONTAINER;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.validation.Path;
+import javax.validation.Validator;
+import javax.validation.ValidatorContext;
+
+import org.apache.bval.MetaBeanBuilder;
+import org.apache.bval.MetaBeanFinder;
+import org.apache.bval.MetaBeanManager;
+import org.apache.bval.jsr303.AnnotationProcessor;
+import org.apache.bval.jsr303.ApacheFactoryContext;
+import org.apache.bval.jsr303.AppendValidationToMeta;
+import org.apache.bval.jsr303.util.ClassHelper;
+import org.apache.bval.jsr303.util.PathImpl;
+import org.apache.bval.jsr303.util.PathNavigation;
+import org.apache.bval.model.FeaturesCapable;
+import org.apache.bval.model.MetaBean;
+import org.apache.bval.model.MetaProperty;
+import org.apache.bval.util.AccessStrategy;
+import org.apache.bval.util.IndexedAccess;
+import org.apache.bval.util.KeyedAccess;
+import org.apache.bval.util.PropertyAccess;
+import org.apache.commons.lang3.Pair;
+import org.apache.commons.lang3.reflect.TypeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@link ValidatorContext} implementation supporting context-bound dynamic
+ * constraints.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class DynamicValidatorContext extends ApacheFactoryContext implements DynamicMetaGraphManager {
+    /**
+     * Default means of signifying "any" as a match for a bracketed index/key in
+     * a path.
+     */
+    public static final String DEFAULT_WILDCARD = "*";
+
+    private static final Collection<Annotation> EMPTY_DYNAMIC_ANNOTATIONS = Collections.<Annotation> emptySet();
+
+    /**
+     * PathNavigation callback for initial location of a property path.
+     */
+    private class NavigateOrBuildGraph implements PathNavigation.Callback<FeaturesCapable> {
+        private MetaBean metaBean;
+        private MetaProperty property;
+
+        /**
+         * Create a new SetupConstraintCallback instance.
+         * 
+         * @param root
+         */
+        NavigateOrBuildGraph(MetaBean root) {
+            super();
+            this.metaBean = root;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void handleIndexOrKey(String value) {
+            if (property == null) {
+                throw new IllegalStateException(
+                    "Bean validation doesn't handle property paths that lead with indexes... does it?");
+            }
+            MetaContainer<?> container = getRequiredContainer(property);
+            if (wildcard.equals(value)) {
+                metaBean = container.getPrototype();
+            } else if (Integer.class.equals(container.getIdType())) {
+                @SuppressWarnings("unchecked")
+                MetaContainer<Integer> collection = (MetaContainer<Integer>) container;
+                metaBean = collection.getElement(Integer.valueOf(value));
+            } else if (Object.class.equals(container.getIdType())) {
+                @SuppressWarnings("unchecked")
+                MetaContainer<Object> map = (MetaContainer<Object>) container;
+                metaBean = map.getElement(value);
+            } else {
+                throw new IllegalStateException(String.format("Don't know how to handle container id type %s",
+                    container.getIdType()));
+            }
+            property = null;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void handleProperty(String name) {
+            if (property != null) {
+                metaBean = property.getMetaBean();
+            }
+            property = getRequiredProperty(metaBean, name);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public FeaturesCapable result() {
+            return property == null ? metaBean : property;
+        }
+
+    }
+
+    private class DynamicMetaBeanFinder extends MetaBeanManager {
+
+        /**
+         * Create a new DynamicValidatorContext.DynamicMetaBeanFinder instance.
+         */
+        DynamicMetaBeanFinder(MetaBeanBuilder builder) {
+            super(builder);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public MetaBean findForClass(final Class<?> clazz) {
+            final MetaBean initial = super.findForClass(clazz);
+            MetaBean result = initial;
+
+            final PathImpl path;
+            final Object rootBean;
+            final MetaBean rootMetaBean;
+
+            DynamicValidationState validationState = currentValidationState.get();
+            if (validationState == null) {
+                path = PathImpl.create(null);
+                rootBean = null;
+                rootMetaBean = initial;
+            } else {
+                rootMetaBean = validationState.getRootMetaBean();
+                path = validationState.getPropertyPath();
+                rootBean = validationState.getRootBean();
+            }
+            try {
+                /*
+                 * For each step of the path, we need to know whether the bean
+                 * we are looking for matches a mapped property, so we build a
+                 * stack of path/bean pairs. We use a stack so that when we
+                 * process, the longest path goes last and therefore wins over
+                 * short paths: the rationale here is that the longer path is
+                 * more specific thus more likely to be rooted at more important
+                 * part of your domain model.
+                 */
+                Deque<Pair<? extends PathImpl, Class<?>>> pathStack =
+                    buildPathStack(path, rootBean, rootMetaBean.getBeanClass());
+
+                while (!pathStack.isEmpty()) {
+                    Pair<? extends PathImpl, Class<?>> pair = pathStack.pop();
+                    List<MetaBean> dynamicInfo = getAssignableDynamicInfo(pair.right);
+
+                    PathImpl relativePath = pair.left;
+                    for (MetaBean root : dynamicInfo) {
+                        MetaBean leaf = findLeaf(root, relativePath);
+                        if (leaf == null) {
+                            continue;
+                        }
+                        if (result == initial) {
+                            result = initial.copy();
+                        }
+
+                        // copy bean + property constraints:
+                        copyConstraints(result, leaf);
+
+                        for (MetaProperty sourceProperty : leaf.getProperties()) {
+                            MetaProperty targetProperty = getRequiredProperty(result, sourceProperty.getName());
+                            copyConstraints(targetProperty, sourceProperty);
+                        }
+
+                    }
+                }
+
+                if (result == initial) {
+                    return result;
+                }
+                // now the dynamic constraints should FINALLY be fully
+                // populated:
+
+                {
+                    Collection<Annotation> constraints =
+                        result.getFeature(DYNAMIC_CONSTRAINT_COLLECTION, EMPTY_DYNAMIC_ANNOTATIONS);
+                    for (Annotation constraint : constraints) {
+                        annotationProcessor.processAnnotation(constraint, result.getBeanClass(),
+                            new AppendValidationToMeta(result));
+                    }
+                }
+                for (MetaProperty property : result.getProperties()) {
+                    String propertyName = property.getName();
+                    Collection<Annotation> constraints =
+                        property.getFeature(DYNAMIC_CONSTRAINT_COLLECTION, EMPTY_DYNAMIC_ANNOTATIONS);
+                    for (Annotation constraint : constraints) {
+                        annotationProcessor.processAnnotation(constraint, property, result.getBeanClass(),
+                            new PropertyAccess(result.getBeanClass(), propertyName), new AppendValidationToMeta(
+                                property));
+                    }
+                }
+
+            } catch (Exception e) {
+                StringBuilder msg =
+                    new StringBuilder("Encountered error applying dynamic constraints for type ").append(clazz
+                        .getName());
+                if (!path.isRootPath()) {
+                    msg.append(": path ").append(path);
+                }
+                log.error(msg.toString(), e);
+            }
+            return result;
+        }
+    }
+
+    private List<MetaBean> getAssignableDynamicInfo(Class<?> type) {
+        List<Class<?>> classSequence = new ArrayList<Class<?>>();
+        ClassHelper.fillFullClassHierarchyAsList(classSequence, type);
+        List<MetaBean> result = new ArrayList<MetaBean>(classSequence.size());
+        for (Class<?> assignable : classSequence) {
+            MetaBean dynamicInfo = dynamicBeanInfo.get(assignable);
+            if (dynamicInfo != null) {
+                result.add(dynamicInfo);
+            }
+        }
+        return result;
+    }
+
+    /*
+     * build a stack of pairs of path + metabean representing each object in the
+     * currently known path, i.e. what we're trying to complete the bean for
+     */
+    private Deque<Pair<? extends PathImpl, Class<?>>> buildPathStack(final PathImpl fullPath, Object rootBean,
+        Class<?> rootType) {
+        // get a list of Nodes we can play with:
+        LinkedList<Path.Node> nodes = new LinkedList<Path.Node>();
+        Iterator<Path.Node> fullNodes = fullPath.iterator();
+        while (fullNodes.hasNext()) {
+            nodes.add(fullNodes.next());
+        }
+
+        Deque<Pair<? extends PathImpl, Class<?>>> stack = new ArrayDeque<Pair<? extends PathImpl, Class<?>>>();
+
+        PathImpl path = fullPath;
+        Class<?> rawType = rootType;
+        Type type = rawType;
+        Object bean = rootBean;
+
+        while (true) {
+            stack.push(Pair.<PathImpl, Class<?>> of(path, rawType));
+            if (path.isRootPath()) {
+                break;
+            }
+            // handle the property:
+            Path.Node node = nodes.remove(0);
+            {
+                PropertyAccess access = new PropertyAccess(rawType, node.getName());
+                if (bean != null) {
+                    bean = access.get(bean);
+                }
+                rawType = TypeUtils.getRawType(access.getJavaType(), type);
+                type = access.getJavaType();
+            }
+            if (node.isInIterable()) {
+                AccessStrategy access;
+                if (node.getIndex() != null) {
+                    access = new IndexedAccess(type, node.getIndex());
+                } else {
+                    access = new KeyedAccess(type, node.getKey());
+                }
+                if (bean != null) {
+                    bean = access.get(bean);
+                }
+                rawType = TypeUtils.getRawType(access.getJavaType(), type);
+                type = access.getJavaType();
+            }
+
+            // rebuild relative path from remaining nodes:
+            path = buildPath(nodes);
+        }
+        return stack;
+    }
+
+    private MetaBean findLeaf(MetaBean root, PathImpl path) {
+        if (path.isRootPath()) {
+            return root;
+        }
+        MetaBean result = root;
+        // iterate over the path; bail at the first null meta object:
+        for (Path.Node node : path) {
+            MetaProperty sourceProperty = result.getProperty(node.getName());
+            if (sourceProperty == null) {
+                return null;
+            }
+            if (node.isInIterable()) {
+                if (sourceProperty.getFeature(META_CONTAINER) == null) {
+                    return null;
+                }
+                if (node.getIndex() != null) {
+                    MetaContainer<Integer> collection = sourceProperty.getFeature(META_CONTAINER);
+                    result = collection.getMergedElement(node.getIndex());
+                } else {
+                    // assume there must be a key
+                    MetaContainer<Object> map = sourceProperty.getFeature(META_CONTAINER);
+                    result = map.getMergedElement(node.getKey());
+                }
+            } else {
+                result = sourceProperty.getMetaBean();
+            }
+            // make sure the source (dynamic) properties know how to
+            // cascade so that when/if they copy over the target will
+            // cascade them as well:
+            annotationProcessor.addAccessStrategy(sourceProperty, new PropertyAccess(sourceProperty.getParentMetaBean()
+                .getBeanClass(), sourceProperty.getName()));
+        }
+        return result;
+    }
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private final ThreadLocal<DynamicValidationState> currentValidationState =
+        new ThreadLocal<DynamicValidationState>();
+
+    private final AnnotationProcessor annotationProcessor = new AnnotationProcessor(this);
+    private final ConcurrentMap<Class<?>, MetaBean> dynamicBeanInfo = new ConcurrentHashMap<Class<?>, MetaBean>();
+    private String wildcard = DEFAULT_WILDCARD;
+
+    /**
+     * Create a new {@link DynamicValidatorContext} instance.
+     * 
+     * @param validatorFactory
+     */
+    public DynamicValidatorContext(DynamicValidatorFactory validatorFactory) {
+        super(validatorFactory);
+    }
+
+    /**
+     * Set the wildcard string in use for dynamically constrained properties.
+     * 
+     * @param wildcard
+     * @return <code>this</code> following the chained invocation pattern
+     */
+    public DynamicValidatorContext wildcard(String wildcard) {
+        this.wildcard = wildcard;
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Validator getValidator() {
+        return new DynamicClassValidator(this);
+    }
+
+    /**
+     * Constrain a bean type at the class level.
+     * 
+     * @param beanType
+     * @param constraintCollectionManipulator
+     * @return <code>this</code> following the chained invocation pattern
+     * @return <code>this</code> following the chained invocation pattern
+     */
+    public final DynamicValidatorContext constrain(Class<?> beanType, Annotation constraint) {
+        return constrain(beanType, null, constraint);
+    }
+
+    /**
+     * Constrain a property path relative to a root bean type.
+     * 
+     * @param beanType
+     * @param propertyPath
+     * @param constraintCollectionManipulator
+     * @return <code>this</code> following the chained invocation pattern
+     */
+    public DynamicValidatorContext constrain(Class<?> beanType, String propertyPath, Annotation constraint) {
+        MetaBean metaBean = writable().getMetaBean(beanType);
+        FeaturesCapable meta = PathNavigation.navigateAndReturn(propertyPath, new NavigateOrBuildGraph(metaBean));
+        Collection<Annotation> constraints = getRequiredDynamicConstraints(meta);
+        ConstraintAppender.FACTORY.constraintAppender(constraint).append(constraint, constraints);
+        return this;
+    }
+
+    /**
+     * Clear dynamic constraints for this context.
+     */
+    public void clearDynamicConstraints() {
+        dynamicBeanInfo.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public DynamicMetaGraphManager.Interface writable() {
+        return new DynamicMetaGraphManager.Interface() {
+
+            /**
+             * {@inheritDoc}
+             */
+            public MetaBean getMetaBean(Class<?> type) {
+                MetaBean result;
+                if (dynamicBeanInfo.containsKey(type)) {
+                    result = dynamicBeanInfo.get(type);
+                } else {
+                    result = new MetaBean();
+                    result.setBeanClass(type);
+                    MetaBean faster = dynamicBeanInfo.putIfAbsent(type, result);
+                    if (faster != null) {
+                        return faster;
+                    }
+                }
+                return result;
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            public <T extends FeaturesCapable> T getMeta(Class<?> type, String propertyPath) {
+                MetaBean root = getMetaBean(type);
+                @SuppressWarnings("unchecked")
+                T result = (T) PathNavigation.navigateAndReturn(propertyPath, new NavigateOrBuildGraph(root));
+                return result;
+            }
+        };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public DynamicMetaGraphManager.Interface readOnly() {
+        return new DynamicMetaGraphManager.Interface() {
+
+            /**
+             * {@inheritDoc}
+             */
+            public MetaBean getMetaBean(Class<?> type) {
+                return getMetaBeanFinder().findForClass(type);
+            }
+
+            /**
+             * {@inheritDoc}
+             */
+            @SuppressWarnings("unchecked")
+            public <T extends FeaturesCapable> T getMeta(Class<?> type, String propertyPath) {
+                MetaBean rootMetaBean = DynamicValidatorContext.this.writable().getMetaBean(type);
+                PathImpl path = PathImpl.createPathFromString(propertyPath);
+                // trim off simple leaf property if applicable:
+                String simplePropertyName;
+                if (path.isRootPath() || path.getLeafNode().isInIterable()) {
+                    simplePropertyName = null;
+                } else {
+                    simplePropertyName = path.getLeafNode().getName();
+                    path = path.getPathWithoutLeafNode();
+                }
+                FeaturesCapable meta =
+                    PathNavigation.navigateAndReturn(path.toString(), new NavigateOrBuildGraph(rootMetaBean));
+
+                try {
+                    register(new DynamicValidationStateBean(null, rootMetaBean, path));
+                    meta = getMetaBeanFinder().findForClass(((MetaBean) meta).getBeanClass());
+                } finally {
+                    clearValidationState();
+                }
+                if (simplePropertyName != null) {
+                    meta = ((MetaBean) meta).getProperty(simplePropertyName);
+                }
+                return (T) meta;
+            }
+        };
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected MetaBeanFinder buildMetaBeanFinder() {
+        return new DynamicMetaBeanFinder(((MetaBeanManager) super.buildMetaBeanFinder()).getBuilder());
+    }
+
+    /**
+     * Register a {@link DynamicValidationState} instance to the current thread.
+     * Etiquette requires the caller to clear the instance when no longer
+     * needed.
+     * 
+     * @param validationState
+     * @see #clearValidationState()
+     */
+    void register(DynamicValidationState validationState) {
+        currentValidationState.set(validationState);
+    }
+
+    /**
+     * Clear the registered {@link DynamicValidationState}.
+     */
+    void clearValidationState() {
+        currentValidationState.remove();
+    }
+
+    private static PathImpl buildPath(Iterable<? extends Path.Node> nodes) {
+        PathImpl result = PathImpl.create(null);
+        for (Path.Node node : nodes) {
+            result.addNode(node);
+        }
+        return result;
+    }
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorFactory.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorFactory.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorFactory.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicValidatorFactory.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,48 @@
+/*
+ *  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 javax.validation.spi.ConfigurationState;
+
+import org.apache.bval.jsr303.ApacheValidatorFactory;
+
+/**
+ * {@link ApacheValidatorFactory} extension that creates a
+ * {@link DynamicValidatorContext}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DynamicValidatorFactory extends ApacheValidatorFactory {
+    /**
+     * Create a new {@link DynamicValidatorFactory} instance.
+     *
+     * @param configurationState
+     */
+    public DynamicValidatorFactory(ConfigurationState configurationState) {
+        super(configurationState);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.bval.jsr303.ApacheValidatorFactory#usingContext()
+     */
+    @Override
+    public DynamicValidatorContext usingContext() {
+        return new DynamicValidatorContext(this);
+    }
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/GroupValidationContextValidationState.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/GroupValidationContextValidationState.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/GroupValidationContextValidationState.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/GroupValidationContextValidationState.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,66 @@
+/*
+ *  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 org.apache.bval.jsr303.GroupValidationContext;
+import org.apache.bval.jsr303.util.PathImpl;
+import org.apache.bval.model.MetaBean;
+
+/**
+ * {@link DynamicValidationState} implementation that wraps a
+ * {@link GroupValidationContext}.
+ *
+ * @version $Rev$ $Date$
+ */
+class GroupValidationContextValidationState implements DynamicValidationState {
+    private Object rootBean;
+    private GroupValidationContext<?> validationContext;
+
+    /**
+     * Create a new GroupValidationContextValidationState instance.
+     *
+     * @param rootBean
+     * @param validationContext
+     */
+    public GroupValidationContextValidationState(Object rootBean, GroupValidationContext<?> validationContext) {
+        super();
+        this.rootBean = rootBean;
+        this.validationContext = validationContext;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PathImpl getPropertyPath() {
+        return validationContext.getPropertyPath();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Object getRootBean() {
+        return rootBean;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MetaBean getRootMetaBean() {
+        return validationContext.getRootMetaBean();
+    }
+
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaCollection.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaCollection.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaCollection.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaCollection.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,47 @@
+/*
+ *  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.reflect.Type;
+
+import org.apache.bval.model.MetaProperty;
+import org.apache.bval.util.IndexedAccess;
+
+/**
+ * Meta-collection.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MetaCollection extends MetaContainer<Integer> {
+
+    /**
+     * Create a new MetaCollection instance.
+     *
+     * @param parent
+     */
+    public MetaCollection(MetaProperty parent) {
+        super(Integer.class, parent);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Type getElementType(MetaProperty parent) {
+        return IndexedAccess.getJavaElementType(parent.getType());
+    }
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaContainer.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaContainer.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaContainer.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaContainer.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,121 @@
+/*
+ *  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 static org.apache.bval.jsr303.dynamic.DynamicModel.*;
+
+import java.lang.reflect.Type;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.bval.model.MetaBean;
+import org.apache.bval.model.MetaProperty;
+import org.apache.commons.lang3.reflect.TypeUtils;
+
+/**
+ * Represents a "container."
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class MetaContainer<K> {
+
+    private final Class<K> idType;
+    private final Type elementType;
+    private final MetaBean prototype;
+    private final ConcurrentMap<K, MetaBean> elements = new ConcurrentHashMap<K, MetaBean>();
+
+    /**
+     * Create a new MetaContainer instance.
+     * @param parent
+     */
+    protected MetaContainer(Class<K> idType, MetaProperty parent) {
+        this.idType = idType;
+        this.elementType = getElementType(parent);
+        prototype = new MetaBean();
+        prototype.setBeanClass(TypeUtils.getRawType(elementType, parent.getType()));
+    }
+
+    /**
+     * Get the raw element type of this {@link MetaContainer} given its parent.
+     * @param parent
+     * @return
+     */
+    protected abstract Type getElementType(MetaProperty parent);
+
+    /**
+     * @return the idType
+     */
+    public Class<K> getIdType() {
+        return idType;
+    }
+
+    /**
+     * @return the elementType
+     */
+    public Type getElementType() {
+
+        return elementType;
+    }
+
+    /**
+     * @return the prototype
+     */
+    public MetaBean getPrototype() {
+        return prototype;
+    }
+
+    /**
+     * @return the elements
+     */
+    public ConcurrentMap<K, MetaBean> getElements() {
+        return elements;
+    }
+
+    /**
+     * Get the raw element bean keyed by <code>id</code>.
+     *
+     * @param id
+     * @return MetaBean
+     */
+    public MetaBean getElement(K id) {
+        MetaBean result = elements.get(id);
+        if (result == null) {
+            result = new MetaBean();
+            result.setBeanClass(prototype.getBeanClass());
+            MetaBean faster = elements.putIfAbsent(id, result);
+            if (faster != null) {
+                result = faster;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Get a MetaBean representing the bean keyed by id, merged with the
+     * prototype.
+     *
+     * @param id
+     * @return MetaBean
+     */
+    public MetaBean getMergedElement(K id) {
+        MetaBean result = new MetaBean();
+        copy(result, prototype);
+        copy(result, elements.get(id));
+        return result;
+    }
+
+}

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

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaMap.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaMap.java?rev=999729&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaMap.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/MetaMap.java Wed Sep 22 02:37:54 2010
@@ -0,0 +1,47 @@
+/*
+ *  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.reflect.Type;
+
+import org.apache.bval.model.MetaProperty;
+import org.apache.bval.util.KeyedAccess;
+
+/**
+ * Meta-Map
+ *
+ * @version $Rev$ $Date$
+ */
+public class MetaMap extends MetaContainer<Object> {
+
+    /**
+     * Create a new MetaMap instance.
+     *
+     * @param parent
+     */
+    public MetaMap(MetaProperty parent) {
+        super(Object.class, parent);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Type getElementType(MetaProperty parent) {
+        return KeyedAccess.getJavaElementType(parent.getType());
+    }
+}

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

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



Mime
View raw message