You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2010/09/22 04:37:56 UTC
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...
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