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 2011/05/17 00:38:34 UTC

svn commit: r1103934 - in /incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic: ./ extval/ extval/src/ extval/src/main/ extval/src/main/java/ extval/src/main/java/org/ extval/src/main/java/org/apache/ extval/src/main/java/org/apache/bval/ extval/src/...

Author: mbenson
Date: Mon May 16 22:38:33 2011
New Revision: 1103934

URL: http://svn.apache.org/viewvc?rev=1103934&view=rev
Log:
dynamic validation + myfaces-extval WIP

Added:
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/pom.xml   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationELHelper.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationModuleValidationInterceptor.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationStartupListener.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicValidatorFactoryProxy.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathBasedPropertyDetails.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathRecordingELResolver.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/ValidatorContextProvider.java   (with props)
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/META-INF/
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/META-INF/faces-config.xml   (with props)
Modified:
    incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/pom.xml

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon May 16 22:38:33 2011
@@ -0,0 +1,3 @@
+*.log
+.*
+target

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/pom.xml
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/pom.xml?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/pom.xml (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/pom.xml Mon May 16 22:38:33 2011
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<!--
+	Maven release plugin requires the project tag to be on a single line.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>bval-jsr303-dynamic</artifactId>
+    <groupId>org.apache.bval</groupId>
+    <version>0.4-incubating-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.bval</groupId>
+  <artifactId>bval-jsr303-dynamic-extval</artifactId>
+  <version>0.4-incubating-SNAPSHOT</version>
+  <name>bval-jsr303-dynamic-extval</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>
+    	<artifactId>myfaces-extval-bean-validation</artifactId>
+    	<version>${extval.version}</version>
+    	<type>jar</type>
+    	<scope>compile</scope>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.bval</groupId>
+    	<artifactId>bval-jsr303-dynamic-provider</artifactId>
+    	<version>${project.version}</version>
+    	<type>jar</type>
+    	<scope>compile</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.myfaces.core</groupId>
+        <artifactId>myfaces-api</artifactId>
+        <version>${jsf.version}</version>
+        <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>de.odysseus.juel</groupId>
+        <artifactId>juel-api</artifactId>
+        <version>2.2.3</version>
+        <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <extval.version>2.0.5-SNAPSHOT</extval.version>
+    <jsf.version>2.1.0-SNAPSHOT</jsf.version>
+  </properties>
+</project>

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationELHelper.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationELHelper.java?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationELHelper.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationELHelper.java Mon May 16 22:38:33 2011
@@ -0,0 +1,136 @@
+/*
+ *  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.extval;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ValueExpression;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.el.CompositeComponentExpressionHolder;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+
+import org.apache.myfaces.extensions.validator.core.el.AbstractELHelperFactory;
+import org.apache.myfaces.extensions.validator.core.el.DefaultELHelper;
+import org.apache.myfaces.extensions.validator.core.el.ELHelper;
+import org.apache.myfaces.extensions.validator.core.el.ExtValELResolver;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+
+/**
+ * Special {@link ELHelper} implementation for dynamic bean validation.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class DynamicBeanValidationELHelper extends DefaultELHelper {
+
+    private static final String PROPERTY_DETAILS_CACHE_KEY =
+        "org.apache.bval.jsr303.dynamic.extval.DynamicBeanValidationELHelper.Factory.propertyDetailsCache";
+
+    /**
+     * {@code DynamicBeanValidationELHelper} Factory.
+     */
+    public static class Factory extends AbstractELHelperFactory implements PhaseListener {
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        protected ELHelper createELHelper() {
+            return new DynamicBeanValidationELHelper();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void afterPhase(PhaseEvent event) {
+            if (event.getPhaseId() == PhaseId.UPDATE_MODEL_VALUES || event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
+                Map<String, PathBasedPropertyDetails> propertyDetailsCache =
+                    getPropertyDetailsCache(event.getFacesContext(), false);
+                if (propertyDetailsCache != null) {
+                    propertyDetailsCache.clear();
+                }
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void beforePhase(PhaseEvent event) {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public PhaseId getPhaseId() {
+            return PhaseId.ANY_PHASE;
+        }
+    }
+
+    private static Map<String, PathBasedPropertyDetails> getPropertyDetailsCache(FacesContext facesContext,
+        boolean create) {
+        @SuppressWarnings("unchecked")
+        Map<String, PathBasedPropertyDetails> result =
+            (Map<String, PathBasedPropertyDetails>) facesContext.getAttributes().get(PROPERTY_DETAILS_CACHE_KEY);
+        if (result == null && create) {
+            result = new HashMap<String, PathBasedPropertyDetails>();
+            facesContext.getAttributes().put(PROPERTY_DETAILS_CACHE_KEY, result);
+        }
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public PropertyDetails getPropertyDetailsOfValueBinding(UIComponent uiComponent) {
+        ValueExpression valueExpression = uiComponent.getValueExpression("value");
+        if (valueExpression != null) {
+            final FacesContext facesContext = FacesContext.getCurrentInstance();
+            String expr = valueExpression.getExpressionString();
+            Map<String, PathBasedPropertyDetails> cache = getPropertyDetailsCache(facesContext, true);
+            if (cache.containsKey(expr)) {
+                return cache.get(expr);
+            }
+            PathBasedPropertyDetails result = resolve(valueExpression, facesContext.getELContext());
+            cache.put(expr, result);
+            return result;
+        }
+        return null;
+    }
+
+    private static PathBasedPropertyDetails resolve(ValueExpression valueExpression, ELContext elContext) {
+        PathRecordingELResolver elResolver = new PathRecordingELResolver(elContext.getELResolver());
+        ELContext contextWrapper = ExtValELResolver.createContextWrapper(elContext, elResolver);
+        ValueExpression expr = valueExpression;
+        while (true) {
+            expr.setValue(contextWrapper, null);
+            Object baseObject = elResolver.getBaseObject();
+            if (baseObject instanceof CompositeComponentExpressionHolder) {
+                expr = ((CompositeComponentExpressionHolder) baseObject).getExpression(elResolver.getLeafProperty());
+                continue;
+            }
+            break;
+        }
+        return new PathBasedPropertyDetails(elResolver.getPath().toString(), elResolver.getBaseObject(),
+            elResolver.getLeafProperty(), elResolver.getPath());
+    }
+}

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationModuleValidationInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationModuleValidationInterceptor.java?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationModuleValidationInterceptor.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationModuleValidationInterceptor.java Mon May 16 22:38:33 2011
@@ -0,0 +1,79 @@
+/*
+ *  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.extval;
+
+import java.util.Iterator;
+
+import javax.el.ValueExpression;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.validation.Path;
+
+import org.apache.bval.jsr303.util.NodeImpl;
+import org.apache.bval.jsr303.util.PathImpl;
+import org.apache.myfaces.extensions.validator.beanval.BeanValidationModuleValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+
+/**
+ * Dynamic {@code BeanValidationModuleValidationInterceptor}.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class DynamicBeanValidationModuleValidationInterceptor extends BeanValidationModuleValidationInterceptor {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void initComponentWithPropertyDetails(FacesContext facesContext, UIComponent uiComponent,
+        PropertyDetails propertyDetails) {
+        Path path = null;
+        try {
+            if (propertyDetails instanceof PathBasedPropertyDetails) {
+                path = ((PathBasedPropertyDetails) propertyDetails).getPath();
+                processPath(facesContext, path);
+            }
+            super.initComponentWithPropertyDetails(facesContext, uiComponent, propertyDetails);
+        } finally {
+            if (path != null) {
+                DynamicValidatorFactoryProxy.INSTANCE.popPath();
+            }
+        }
+    }
+
+    private static void processPath(FacesContext facesContext, Path path) {
+        PathImpl subPath = PathImpl.create(null);
+        Iterator<Path.Node> nodes = path.iterator();
+        String bean = nodes.next().getName();
+        ValueExpression valueExpression =
+            facesContext.getApplication().getExpressionFactory()
+                .createValueExpression(facesContext.getELContext(), bean, Object.class);
+        Object rootBean = valueExpression.getValue(facesContext.getELContext());
+        while (nodes.hasNext()) {
+            subPath.addNode(nodes.next());
+        }
+        Path.Node leaf = subPath.removeLeafNode();
+        if (leaf.isInIterable()) {
+            if (leaf.getIndex() != null) {
+                subPath.addNode(NodeImpl.atIndex(leaf.getIndex()));
+            } else {
+                subPath.addNode(NodeImpl.atKey(leaf.getKey()));
+            }
+        }
+        DynamicValidatorFactoryProxy.INSTANCE.pushPath(rootBean.getClass(), subPath.toString());
+    }
+}

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationStartupListener.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationStartupListener.java?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationStartupListener.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicBeanValidationStartupListener.java Mon May 16 22:38:33 2011
@@ -0,0 +1,51 @@
+/*
+ *  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.extval;
+
+import javax.validation.ValidatorFactory;
+
+import org.apache.myfaces.extensions.validator.beanval.BeanValidationModuleValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.el.AbstractELHelperFactory;
+import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;
+import org.apache.myfaces.extensions.validator.core.startup.AbstractStartupListener;
+
+/**
+ * Startup listener for dynamic bean validation support.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class DynamicBeanValidationStartupListener extends AbstractStartupListener {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void init() {
+        final ExtValContext extValContext = ExtValContext.getContext();
+
+        extValContext.addGlobalProperty(ValidatorFactory.class.getName(), DynamicValidatorFactoryProxy.INSTANCE, true);
+        extValContext.getFactoryFinder().getFactory(FactoryNames.EL_HELPER_FACTORY, AbstractELHelperFactory.class)
+            .setCustomELHelperFactory(new DynamicBeanValidationELHelper.Factory());
+
+        extValContext.denyRendererInterceptor(BeanValidationModuleValidationInterceptor.class);
+        extValContext.registerRendererInterceptor(new DynamicBeanValidationModuleValidationInterceptor());
+    }
+
+}

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicValidatorFactoryProxy.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicValidatorFactoryProxy.java?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicValidatorFactoryProxy.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/DynamicValidatorFactoryProxy.java Mon May 16 22:38:33 2011
@@ -0,0 +1,95 @@
+/*
+ *  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.extval;
+
+import javax.validation.Validator;
+import javax.validation.ValidatorContext;
+import javax.validation.ValidatorFactory;
+
+import org.apache.bval.jsr303.ApacheFactoryContext;
+import org.apache.bval.jsr303.dynamic.DynamicValidatorContext;
+import org.apache.bval.jsr303.dynamic.NestedValidator;
+import org.apache.myfaces.extensions.validator.beanval.ValidatorFactoryProxy;
+
+/**
+ * Forwards {@link ValidatorFactory} calls per {@link ValidatorContext}.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class DynamicValidatorFactoryProxy extends ValidatorFactoryProxy {
+    /**
+     * Statically available instance.
+     */
+    public static final DynamicValidatorFactoryProxy INSTANCE = new DynamicValidatorFactoryProxy();
+
+    /**
+     * Thread-registered validator delegate.
+     */
+    private static ThreadLocal<Validator> VALIDATOR = new ThreadLocal<Validator>();
+
+    /**
+     * Create a new DynamicValidatorFactoryProxy instance.
+     */
+    private DynamicValidatorFactoryProxy() {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected ValidatorFactory getValidatorFactory() {
+        ValidatorContext context = usingContext();
+        if (context instanceof ApacheFactoryContext) {
+            return ((ApacheFactoryContext) context).getFactory();
+        }
+        return super.getValidatorFactory();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ValidatorContext usingContext() {
+        return ValidatorContextProvider.MANAGER.getRequired().get();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Validator getValidator() {
+        Validator result = VALIDATOR.get();
+        return result == null ? usingContext().getValidator() : result;
+    }
+
+    /**
+     * Register a {@code ThreadLocal} {@code NestedValidator}.
+     * 
+     * @param rootBean
+     * @param path
+     */
+    void pushPath(Class<?> rootType, String path) {
+        VALIDATOR.set(new NestedValidator(((DynamicValidatorContext) usingContext()), rootType, path));
+    }
+
+    /**
+     * Deregister any {@code ThreadLocal} {@code NestedValidator}.
+     */
+    void popPath() {
+        VALIDATOR.remove();
+    }
+}

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathBasedPropertyDetails.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathBasedPropertyDetails.java?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathBasedPropertyDetails.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathBasedPropertyDetails.java Mon May 16 22:38:33 2011
@@ -0,0 +1,52 @@
+/*
+ * 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.extval;
+
+import javax.validation.Path;
+
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+
+/**
+ * {@link PropertyDetails} based on a {@code Path}.
+ */
+public class PathBasedPropertyDetails extends PropertyDetails {
+    private final Path path;
+
+    /**
+     * Create a new PathBasedPropertyDetails instance.
+     * 
+     * @param key
+     * @param baseObject
+     * @param property
+     * @param path
+     */
+    public PathBasedPropertyDetails(String key, Object baseObject, String property, Path path) {
+        super(key, baseObject, property);
+        this.path = path;
+    }
+
+    /**
+     * Get the path.
+     * 
+     * @return Path
+     */
+    public Path getPath() {
+        return path;
+    }
+}

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathRecordingELResolver.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathRecordingELResolver.java?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathRecordingELResolver.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/PathRecordingELResolver.java Mon May 16 22:38:33 2011
@@ -0,0 +1,181 @@
+/*
+ *  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.extval;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.validation.Path;
+
+import org.apache.bval.jsr303.util.NodeImpl;
+import org.apache.bval.jsr303.util.PathImpl;
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.mutable.MutableInt;
+
+/**
+ * Adapted from {@link org.apache.myfaces.extensions.validator.core.el.ExtValELResolver} to get the direct property path
+ * of an expression after resolving embedded dynamic references. Uses the JSR303 {@link Path} interface for its
+ * representation. For example use, see {@link ELUtils#resolvePath(javax.el.ValueExpression, ELContext)}.
+ * 
+ * @version $Rev$ $Date$
+ */
+public class PathRecordingELResolver extends ELResolver {
+    private final ELResolver wrapped;
+    private final MutableInt depth = new MutableInt(0);
+    private PathImpl path;
+    private Object tip;
+    private Object baseObject;
+    private String leafProperty;
+
+    /**
+     * Create a new PathRecordingELResolver instance.
+     * @param wrapped
+     */
+    public PathRecordingELResolver(ELResolver wrapped) {
+        super();
+        Validate.notNull(wrapped);
+        this.wrapped = wrapped;
+        reset();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<?> getCommonPropertyType(ELContext context, Object base) {
+        return wrapped.getCommonPropertyType(context, base);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
+        return wrapped.getFeatureDescriptors(context, base);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Class<?> getType(ELContext context, Object base, Object property) {
+        return wrapped.getType(context, base, property);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+        return wrapped.isReadOnly(context, base, property);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Object getValue(ELContext context, Object base, Object property) {
+        Object value = wrapped.getValue(context, base, property);
+        handle(base, property, value);
+        return value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setValue(ELContext context, Object base, Object property, Object value) {
+        Validate.isTrue(base == tip);
+        handle(base, property, value);
+        context.setPropertyResolved(true);
+        baseObject = base;
+        leafProperty = property.toString();
+    }
+
+    private void handle(Object base, Object property, Object value) {
+        // look for nested reads against tip:
+        if (value == tip) {
+            if (base == value) {
+                // somewhat odd, but value seems to be its own property, so simply skip this node:
+            } else {
+                // record that we expect to see a property resolved against tip before we pick up recording again:
+                depth.increment();
+            }
+            return;
+        }
+        if (base == tip) {
+            // if applicable, pop out of the most recent nested read against tip:
+            if (depth.intValue() > 0) {
+                depth.decrement();
+                return;
+            }
+            tip = value;
+            if (base != null) {
+                if (base instanceof Iterable || base.getClass().isArray()) {
+                    path.addNode(NodeImpl.atIndex(Integer.valueOf(((Number) property).intValue())));
+                    return;
+                }
+                if (base instanceof Map) {
+                    path.addNode(NodeImpl.atKey(property));
+                    return;
+                }
+            }
+            path.addProperty(property.toString());
+        }
+    }
+
+    /**
+     * Get the baseObject.
+     * 
+     * @return Object
+     */
+    public Object getBaseObject() {
+        return baseObject;
+    }
+
+    /**
+     * Get the leafProperty.
+     * 
+     * @return String
+     */
+    public String getLeafProperty() {
+        return leafProperty;
+    }
+
+    /**
+     * Get the recorded path.
+     * 
+     * @return Path
+     */
+    public Path getPath() {
+        return PathImpl.copy(path);
+    }
+
+    /**
+     * Reset this {@code PathRecordingELResolver}.
+     */
+    public void reset() {
+        path = PathImpl.create(null);
+        tip = null;
+        baseObject = null;
+        leafProperty = null;
+        depth.setValue(0);
+    }
+}
\ No newline at end of file

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/ValidatorContextProvider.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/ValidatorContextProvider.java?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/ValidatorContextProvider.java (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/java/org/apache/bval/jsr303/dynamic/extval/ValidatorContextProvider.java Mon May 16 22:38:33 2011
@@ -0,0 +1,84 @@
+/*
+ * 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.extval;
+
+import javax.validation.ValidatorContext;
+
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+
+/**
+ * Specifies the interface to retrieve the correct {@link ValidatorContext}.
+ */
+public interface ValidatorContextProvider {
+    /**
+     * Get the provided {@link ValidatorContext}.
+     * 
+     * @return ValidatorContext
+     */
+    ValidatorContext get();
+
+    /**
+     * Manages the {@code ValidatorContextProvider} associated with the {@code ExtValContext}.
+     */
+    public static class Manager {
+        private Manager() {
+        }
+
+        /**
+         * Set the provider.
+         * 
+         * @param provider
+         *            to install
+         */
+        public void set(ValidatorContextProvider provider) {
+            ExtValContext.getContext().addGlobalProperty(ValidatorContextProvider.class.getName(), provider);
+        }
+
+        /**
+         * Get the installed provider.
+         * 
+         * @return {@code ValidatorContextProvider}
+         */
+        public ValidatorContextProvider get() {
+            return (ValidatorContextProvider) ExtValContext.getContext().getGlobalProperty(
+                ValidatorContextProvider.class.getName());
+        }
+
+        /**
+         * Get the installed provider...
+         * 
+         * @return {@code ValidatorContextProvider}
+         * @throws IllegalStateException
+         *             if no instance has been configured
+         */
+        public ValidatorContextProvider getRequired() {
+            ValidatorContextProvider result = get();
+            if (result == null) {
+                throw new IllegalStateException(String.format("No %s configured",
+                    ValidatorContextProvider.class.getName()));
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Permits e.g. {@code ValidatorContextProvider.MANAGER.set(...)} fluent syntax.
+     */
+    public static final Manager MANAGER = new Manager();
+}

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

Added: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/META-INF/faces-config.xml?rev=1103934&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/META-INF/faces-config.xml (added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/META-INF/faces-config.xml Mon May 16 22:38:33 2011
@@ -0,0 +1,26 @@
+<!--
+ * 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.
+-->
+<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
+              version="1.2">
+    <lifecycle>
+        <phase-listener>org.apache.myfaces.extensions.validator.beanval.startup.BeanValidationStartupListener</phase-listener>
+    </lifecycle>
+</faces-config>
\ No newline at end of file

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/extval/src/main/resources/META-INF/faces-config.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/pom.xml
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/pom.xml?rev=1103934&r1=1103933&r2=1103934&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/pom.xml (original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/pom.xml Mon May 16 22:38:33 2011
@@ -33,5 +33,6 @@
   <description>Bean Validation - Dynamic JSR303 Validation</description>
   <modules>
     <module>provider</module>
+    <module>extval</module>
   </modules>
 </project>