You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2009/05/24 22:56:33 UTC

svn commit: r778232 - in /myfaces/extensions/validator/branches/beanval_integration/trunk: core/src/main/java/org/apache/myfaces/extensions/validator/core/ core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ core/src/main/java/...

Author: gpetracek
Date: Sun May 24 20:56:33 2009
New Revision: 778232

URL: http://svn.apache.org/viewvc?rev=778232&view=rev
Log:
EXTVAL-42 first draft

Added:
    myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/
    myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ValidationGroupProvider.java
Modified:
    myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationRendererInterceptor.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java
    myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java Sun May 24 20:56:33 2009
@@ -42,6 +42,7 @@
     STARTUP_LISTENER,
     COMPONENT_INITIALIZER,
     VALIDATION_EXCEPTION_INTERCEPTOR,
+    VALIDATION_INTERCEPTOR,
     META_DATA_EXTRACTION_INTERCEPTOR,
 
     MESSAGE_RESOLVER_FACTORY,

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java Sun May 24 20:56:33 2009
@@ -23,6 +23,7 @@
 import org.apache.myfaces.extensions.validator.core.interceptor.RendererInterceptor;
 import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;
 import org.apache.myfaces.extensions.validator.core.interceptor.MetaDataExtractionInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationInterceptor;
 import org.apache.myfaces.extensions.validator.core.recorder.ProcessedInformationRecorder;
 import org.apache.myfaces.extensions.validator.core.factory.FactoryFinder;
 import org.apache.myfaces.extensions.validator.core.factory.DefaultFactoryFinder;
@@ -59,6 +60,7 @@
 
     private List<ComponentInitializer> componentInitializers;
     private List<ValidationExceptionInterceptor> validationExceptionInterceptors;
+    private List<ValidationInterceptor> validationInterceptors;
     private List<MetaDataExtractionInterceptor> metaDataExtractionInterceptors;
 
     private Map<String, Object> globalProperties = new HashMap<String, Object>();
@@ -134,6 +136,41 @@
         }
     }
 
+    private void lazyInitValidationInterceptors()
+    {
+        if(this.validationInterceptors != null)
+        {
+            return;
+        }
+
+        this.validationInterceptors = new ArrayList<ValidationInterceptor>();
+        List<String> validationInterceptorClassNames = new ArrayList<String>();
+
+        validationInterceptorClassNames
+            .add(WebXmlParameter.CUSTOM_VALIDATION_INTERCEPTOR);
+        validationInterceptorClassNames
+            .add(ExtValContext.getContext().getInformationProviderBean().get(
+                    CustomInformation.VALIDATION_INTERCEPTOR));
+
+        ValidationInterceptor validationInterceptor;
+        for (String validationInterceptorName : validationInterceptorClassNames)
+        {
+            validationInterceptor =
+                (ValidationInterceptor)
+                        ClassUtils.tryToInstantiateClassForName(validationInterceptorName);
+
+            if (validationInterceptor != null)
+            {
+                validationInterceptors.add(validationInterceptor);
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace(validationInterceptor.getClass().getName() + " added");
+                }
+            }
+        }
+    }
+
     private void lazyInitMetaDataExtractionInterceptors()
     {
         if(this.metaDataExtractionInterceptors != null)
@@ -252,7 +289,19 @@
     public List<ValidationExceptionInterceptor> getValidationExceptionInterceptors()
     {
         lazyInitValidationExceptionInterceptors();
-        return validationExceptionInterceptors;
+        return this.validationExceptionInterceptors;
+    }
+
+    public void addValidationInterceptor(ValidationInterceptor validationInterceptor)
+    {
+        lazyInitValidationInterceptors();
+        this.validationInterceptors.add(validationInterceptor);
+    }
+
+    public List<ValidationInterceptor> getValidationValidationInterceptors()
+    {
+        lazyInitValidationInterceptors();
+        return this.validationInterceptors;
     }
 
     public void addMetaDataExtractionInterceptor(MetaDataExtractionInterceptor metaDataExtractionInterceptor)

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java Sun May 24 20:56:33 2009
@@ -90,6 +90,8 @@
                 "ComponentInitializer");
         customizableInfos.put(CustomInformation.VALIDATION_EXCEPTION_INTERCEPTOR,
                 "ValidationExceptionInterceptor");
+        customizableInfos.put(CustomInformation.VALIDATION_INTERCEPTOR,
+                "ValidationInterceptor");
         customizableInfos.put(CustomInformation.META_DATA_EXTRACTION_INTERCEPTOR,
                 "MetaDataExtractionInterceptor");
 

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java Sun May 24 20:56:33 2009
@@ -55,6 +55,9 @@
     static final String CUSTOM_VALIDATION_EXCEPTION_INTERCEPTOR = WebXmlUtils
         .getInitParameter("CUSTOM_VALIDATION_EXCEPTION_INTERCEPTOR");
 
+    static final String CUSTOM_VALIDATION_INTERCEPTOR = WebXmlUtils
+        .getInitParameter("CUSTOM_VALIDATION_INTERCEPTOR");
+
     static final String CUSTOM_META_DATA_EXTRACTION_INTERCEPTOR = WebXmlUtils
         .getInitParameter("CUSTOM_META_DATA_EXTRACTION_INTERCEPTOR");
 

Added: myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java?rev=778232&view=auto
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java (added)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java Sun May 24 20:56:33 2009
@@ -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.myfaces.extensions.validator.core.interceptor;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.API)
+public interface ValidationInterceptor
+{
+    /**
+     * @return false if the validation process should be bypassed
+     */
+    boolean beforeValidation(FacesContext facesContext,
+                             UIComponent uiComponent,
+                             Object convertedObject,
+                             Map<String, Object> properties);
+
+    /**
+     * processed if validation was executed
+     * in contrast to ValidationExceptionInterceptor it gets executed in any case
+     */
+    void afterValidation(FacesContext facesContext,
+                         UIComponent uiComponent,
+                         Object convertedObject,
+                         Map<String, Object> properties);
+}

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationRendererInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationRendererInterceptor.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationRendererInterceptor.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationRendererInterceptor.java Sun May 24 20:56:33 2009
@@ -26,6 +26,7 @@
 import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
 import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
 import org.apache.myfaces.extensions.validator.core.ExtValContext;
 import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipBeforeInterceptorsException;
 import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipRendererDelegationException;
@@ -159,16 +160,44 @@
             return;
         }
 
-        if(logger.isTraceEnabled())
+        MetaDataExtractor metaDataExtractor = ExtValUtils.getComponentMetaDataExtractor();
+
+        PropertyInformation propertyInformation = metaDataExtractor.extract(facesContext, uiComponent);
+
+        if(!ExtValUtils.executeBeforeValidationInterceptors(facesContext, uiComponent, convertedObject,
+                PropertyInformation.class.getName() ,propertyInformation))
         {
-            logger.trace("start validation");
+            return;
         }
 
-        ValidationStrategy validationStrategy;
+        try
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("start validation");
+            }
 
-        MetaDataExtractor metaDataExtractor = ExtValUtils.getComponentMetaDataExtractor();
+            processFieldValidation(facesContext, uiComponent, convertedObject, propertyInformation);
 
-        for (MetaDataEntry entry : metaDataExtractor.extract(facesContext, uiComponent).getMetaDataEntries())
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("validation finished");
+            }
+        }
+        finally
+        {
+            ExtValUtils.executeAfterValidationInterceptors(facesContext, uiComponent, convertedObject,
+                    PropertyInformation.class.getName(), propertyInformation);
+        }
+    }
+
+    protected void processFieldValidation(FacesContext facesContext,
+                                          UIComponent uiComponent,
+                                          Object convertedObject,
+                                          PropertyInformation propertyInformation)
+    {
+        ValidationStrategy validationStrategy;
+        for (MetaDataEntry entry : propertyInformation.getMetaDataEntries())
         {
             validationStrategy = ExtValUtils.getValidationStrategyForMetaData(entry.getKey());
 
@@ -184,8 +213,7 @@
 
                 if(logger.isTraceEnabled())
                 {
-                    logger.trace("validate " + entry.getValue() + " with " +
-                            validationStrategy.getClass().getName());
+                    logger.trace("validate " + entry.getValue() + " with " + validationStrategy.getClass().getName());
                 }
 
                 validationStrategy.validate(facesContext, uiComponent, entry, convertedObject);
@@ -194,16 +222,10 @@
             {
                 if(logger.isTraceEnabled())
                 {
-                    logger.trace("no validation strategy found for "
-                            + entry.getValue());
+                    logger.trace("no validation strategy found for " + entry.getValue());
                 }
             }
         }
-
-        if(logger.isTraceEnabled())
-        {
-            logger.trace("validation finished");
-        }
     }
 
     protected boolean skipValidation(FacesContext facesContext,

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java Sun May 24 20:56:33 2009
@@ -27,6 +27,7 @@
 import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;
 import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;
 import org.apache.myfaces.extensions.validator.core.interceptor.MetaDataExtractionInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationInterceptor;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
 import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
@@ -52,6 +53,7 @@
 import javax.faces.validator.ValidatorException;
 import javax.faces.application.FacesMessage;
 import java.util.Map;
+import java.util.HashMap;
 import java.util.MissingResourceException;
 import java.util.List;
 import java.util.ArrayList;
@@ -419,4 +421,53 @@
 
         return false;
     }
+
+    public static boolean executeBeforeValidationInterceptors(FacesContext facesContext,
+                                                              UIComponent uiComponent,
+                                                              Object convertedObject,
+                                                              String propertyKey,
+                                                              Object properties)
+    {
+        Map<String, Object> propertyMap = new HashMap<String, Object>();
+
+        if(properties != null)
+        {
+            propertyMap.put(propertyKey, properties);
+        }
+        
+        List<ValidationInterceptor> validationInterceptors =
+                ExtValContext.getContext().getValidationValidationInterceptors();
+
+        for(ValidationInterceptor validationInterceptor : validationInterceptors)
+        {
+            if(!validationInterceptor.beforeValidation(facesContext, uiComponent, convertedObject, propertyMap))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public static void executeAfterValidationInterceptors(FacesContext facesContext,
+                                                          UIComponent uiComponent,
+                                                          Object convertedObject,
+                                                          String propertyKey,
+                                                          Object properties)
+    {
+        Map<String, Object> propertyMap = new HashMap<String, Object>();
+
+        if(properties != null)
+        {
+            propertyMap.put(propertyKey, properties);
+        }
+
+        List<ValidationInterceptor> validationInterceptors =
+                ExtValContext.getContext().getValidationValidationInterceptors();
+
+        for(ValidationInterceptor validationInterceptor : validationInterceptors)
+        {
+            validationInterceptor.afterValidation(facesContext, uiComponent, convertedObject, propertyMap);
+        }
+    }
 }

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationInterceptor.java Sun May 24 20:56:33 2009
@@ -23,8 +23,6 @@
 import org.apache.myfaces.extensions.validator.core.recorder.ProcessedInformationRecorder;
 import org.apache.myfaces.extensions.validator.core.ExtValContext;
 import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
-import org.apache.myfaces.extensions.validator.core.el.ELHelper;
-import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
 import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
@@ -34,16 +32,12 @@
 import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;
 import org.apache.myfaces.extensions.validator.core.interceptor.AbstractRendererInterceptor;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
-import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
 import org.apache.myfaces.extensions.validator.beanval.property.BeanValidationPropertyInformationKeys;
-import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;
-import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;
-import org.apache.myfaces.extensions.validator.beanval.annotation.extractor.DefaultGroupControllerScanningExtractor;
 import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationStrategyAdapter;
-import org.apache.myfaces.extensions.validator.beanval.validation.ModelValidationEntry;
-import org.apache.myfaces.extensions.validator.beanval.annotation.NoRestrictionGroup;
 import org.apache.myfaces.extensions.validator.internal.ToDo;
 import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 
 import javax.faces.context.FacesContext;
 import javax.faces.component.UIComponent;
@@ -58,19 +52,16 @@
 import javax.validation.ConstraintDescriptor;
 import javax.validation.ValidatorFactory;
 import javax.validation.ConstraintViolation;
-import javax.validation.groups.Default;
 import java.util.Set;
 import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.io.IOException;
-import java.lang.reflect.Method;
 
 /**
  * @author Gerhard Petracek
- * @since 1.x.3
+ * @since x.x.3
  */
+@ToDo(value = Priority.HIGH, description = "sync jsf 2.0 specific changes with bv-branch")
+@UsageInformation(UsageCategory.INTERNAL)
 public class BeanValidationInterceptor extends AbstractRendererInterceptor
 {
     private ValidatorFactory validationFactory = Validation.buildDefaultValidatorFactory();
@@ -79,17 +70,15 @@
     public void beforeEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
             throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException
     {
-        initComponent(facesContext, uiComponent);
+        if(processComponent(uiComponent))
+        {
+            initComponent(facesContext, uiComponent);
+        }
     }
 
     @ToDo(value = Priority.HIGH, description = "check groups")
     protected void initComponent(FacesContext facesContext, UIComponent uiComponent)
     {
-        if (!(uiComponent instanceof EditableValueHolder))
-        {
-            return;
-        }
-
         if (logger.isTraceEnabled())
         {
             logger.trace("start to init component " + uiComponent.getClass().getName());
@@ -110,8 +99,18 @@
             return;
         }
 
+        /*TODO
+            //TODO extract groups - see ValidationGroupProvider
+            Class[] foundGroups = ExtValBeanValidationContext.getCurrentInstance().getGroups(
+                    facesContext.getViewRoot().getViewId(),
+                    uiComponent.getClientId(facesContext));
+
+            foundGroups = mergeFoundGroupsWithValidatorGroups(
+                foundGroups, ((EditableValueHolder)uiComponent).getValidators());
+         */
+
         BeanDescriptor beanDescriptor = this.validationFactory.getValidator().getConstraintsForClass(
-                propertyDetails.getBaseObject().getClass());
+                propertyDetails.getBaseObject().getClass()/*, foundGroups*/);
 
         ElementDescriptor elementDescriptor = beanDescriptor.getConstraintsForProperty(propertyDetails.getProperty());
 
@@ -151,6 +150,7 @@
                 entry = new MetaDataEntry();
                 entry.setKey(constraintDescriptor.getAnnotation().annotationType().getName());
                 entry.setValue(constraintDescriptor);
+                //TODO (?) add type of property for meta-data transformation (e.g. size: string vs. number)
 
                 metaData = metaDataTransformer.convertMetaData(entry);
             }
@@ -208,7 +208,7 @@
         }
     }
 
-    private boolean processComponent(UIComponent uiComponent)
+    protected boolean processComponent(UIComponent uiComponent)
     {
         return uiComponent instanceof EditableValueHolder;
     }
@@ -216,11 +216,6 @@
     @ToDo(value = Priority.HIGH, description = "use ExtValUtils#createFacesMessage")
     protected void processValidation(FacesContext facesContext, UIComponent uiComponent, Object convertedObject)
     {
-        if (logger.isTraceEnabled())
-        {
-            logger.trace("jsr303 start validation");
-        }
-
         if (!"true".equalsIgnoreCase(WebXmlParameter.DEACTIVATE_EMPTY_STRING_INTERPRETATION)
                 && "".equals(convertedObject))
         {
@@ -231,138 +226,32 @@
 
         PropertyInformation propertyInformation = metaDataExtractor.extract(facesContext, uiComponent);
 
-        //extract group validation annotations
-        addMetaDataToContext(propertyInformation, uiComponent);
-
-        processFieldValidation(facesContext, uiComponent, convertedObject, propertyInformation);
-
-        if (logger.isTraceEnabled())
+        //e.g.: extract groups for validation
+        if(!ExtValUtils.executeBeforeValidationInterceptors(facesContext, uiComponent, convertedObject,
+                PropertyInformation.class.getName() ,propertyInformation))
         {
-            logger.trace("jsr303 validation finished");
-        }
-    }
-
-    protected void addMetaDataToContext(PropertyInformation propertyInformation, UIComponent component)
-    {
-        PropertyDetails propertyDetails = propertyInformation
-                .getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);
-
-        String[] key = propertyDetails.getKey().split("\\.");
-
-        Object firstBean = ExtValUtils.getELHelper().getBean(key[0]);
-
-        List<Class> foundGroupsForPropertyValidation = new ArrayList<Class>();
-        List<Class> restrictedGroupsForPropertyValidation = new ArrayList<Class>();
-        List<ModelValidationEntry> modelValidationEntryList = new ArrayList<ModelValidationEntry>();
-        List<Class> restrictedGroupsForModelValidation = new ArrayList<Class>();
-
-        //extract bv-controller-annotation of
-
-        //first bean
-        processClass(firstBean,
-                foundGroupsForPropertyValidation,
-                restrictedGroupsForPropertyValidation,
-                modelValidationEntryList,
-                restrictedGroupsForModelValidation);
-
-        //first property
-        processFieldsAndProperties(key[0] + "." + key[1],
-                firstBean,
-                key[1],
-                foundGroupsForPropertyValidation,
-                restrictedGroupsForPropertyValidation,
-                modelValidationEntryList,
-                restrictedGroupsForModelValidation);
-
-        //base object (of target property)
-        processClass(propertyDetails.getBaseObject(),
-                foundGroupsForPropertyValidation,
-                restrictedGroupsForPropertyValidation,
-                modelValidationEntryList,
-                restrictedGroupsForModelValidation);
-
-        //last property
-        processFieldsAndProperties(
-                propertyDetails.getKey(),
-                propertyDetails.getBaseObject(),
-                propertyDetails.getProperty(),
-                foundGroupsForPropertyValidation,
-                restrictedGroupsForPropertyValidation,
-                modelValidationEntryList,
-                restrictedGroupsForModelValidation);
-
-        ExtValBeanValidationContext extValBeanValidationContext = ExtValBeanValidationContext.getCurrentInstance();
-        String currentViewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
-
-        String clientId = component.getClientId(FacesContext.getCurrentInstance());
-
-        processFoundGroups(extValBeanValidationContext, currentViewId, clientId,
-                foundGroupsForPropertyValidation);
-
-        processRestrictedGroups(extValBeanValidationContext, currentViewId, clientId,
-                restrictedGroupsForPropertyValidation);
-
-        initModelValidation(extValBeanValidationContext, currentViewId, component, propertyDetails,
-                modelValidationEntryList, restrictedGroupsForModelValidation);
-    }
-
-    protected void processFoundGroups(ExtValBeanValidationContext extValBeanValidationContext,
-                                      String currentViewId,
-                                      String clientId,
-                                      List<Class> foundGroupsForPropertyValidation)
-    {
-        /*
-         * add found groups to context
-         */
-        for (Class currentGroupClass : foundGroupsForPropertyValidation)
-        {
-            extValBeanValidationContext.addGroup(currentGroupClass, currentViewId, clientId);
-        }
-    }
-
-    protected void processRestrictedGroups(ExtValBeanValidationContext extValBeanValidationContext,
-                                         String currentViewId,
-                                         String clientId,
-                                         List<Class> restrictedGroupsForPropertyValidation)
-    {
-        /*
-         * add restricted groups
-         */
-        for (Class currentGroupClass : restrictedGroupsForPropertyValidation)
-        {
-            extValBeanValidationContext.restrictGroup(currentGroupClass, currentViewId, clientId);
+            return;
         }
-    }
 
-    protected void initModelValidation(ExtValBeanValidationContext extValBeanValidationContext,
-                                     String currentViewId,
-                                     UIComponent component,
-                                     PropertyDetails propertyDetails,
-                                     List<ModelValidationEntry> modelValidationEntryList,
-                                     List<Class> restrictedGroupsForModelValidation)
-    {
-        /*
-         * add model validation entry list
-         */
-        for(ModelValidationEntry modelValidationEntry : modelValidationEntryList)
+        try
         {
-            if(!"true".equalsIgnoreCase(org.apache.myfaces.extensions.validator.beanval.WebXmlParameter
-                    .DEACTIVATE_IMPLICIT_DEFAULT_GROUP_VALIDATION))
+            if (logger.isTraceEnabled())
             {
-                modelValidationEntry.addGroup(Default.class);
+                logger.trace("jsr303 start validation");
             }
 
-            for(Class restrictedGroup : restrictedGroupsForModelValidation)
-            {
-                modelValidationEntry.removeGroup(restrictedGroup);
-            }
+            processFieldValidation(facesContext, uiComponent, convertedObject, propertyInformation);
 
-            if(modelValidationEntry.getGroups().length > 0)
+            if (logger.isTraceEnabled())
             {
-                addTargetsForModelValidation(modelValidationEntry, propertyDetails.getBaseObject());
-                extValBeanValidationContext.addModelValidationEntry(modelValidationEntry, currentViewId, component);
+                logger.trace("jsr303 validation finished");
             }
         }
+        finally
+        {
+            ExtValUtils.executeAfterValidationInterceptors(facesContext, uiComponent, convertedObject,
+                    PropertyInformation.class.getName(), propertyInformation);
+        }
     }
 
     protected void processFieldValidation(FacesContext facesContext,
@@ -426,292 +315,4 @@
         }
     }
     
-    private void processClass(Object objectToInspect,
-                              List<Class> foundGroupsForPropertyValidation,
-                              List<Class> restrictedGroupsForPropertyValidation,
-                              List<ModelValidationEntry> modelValidationEntryList,
-                              List<Class> restrictedGroupsForModelValidation)
-    {
-        Class classToInspect = objectToInspect.getClass();
-        while (!Object.class.getName().equals(classToInspect.getName()))
-        {
-            transferGroupValidationInformationToFoundGroups(objectToInspect,
-                    foundGroupsForPropertyValidation,
-                    restrictedGroupsForPropertyValidation,
-                    modelValidationEntryList,
-                    restrictedGroupsForModelValidation);
-
-            processInterfaces(objectToInspect.getClass(), objectToInspect,
-                    foundGroupsForPropertyValidation,
-                    restrictedGroupsForPropertyValidation,
-                    modelValidationEntryList,
-                    restrictedGroupsForModelValidation);
-
-            classToInspect = classToInspect.getSuperclass();
-        }
-    }
-
-    private void processInterfaces(Class currentClass,
-                                   Object metaDataSourceObject,
-                                   List<Class> foundGroupsForPropertyValidation,
-                                   List<Class> restrictedGroupsForPropertyValidation,
-                                   List<ModelValidationEntry> modelValidationEntryList,
-                                   List<Class> restrictedGroupsForModelValidation)
-    {
-        for (Class currentInterface : currentClass.getInterfaces())
-        {
-            transferGroupValidationInformationToFoundGroups(metaDataSourceObject,
-                    foundGroupsForPropertyValidation,
-                    restrictedGroupsForPropertyValidation,
-                    modelValidationEntryList,
-                    restrictedGroupsForModelValidation);
-
-            processInterfaces(currentInterface, metaDataSourceObject,
-                    foundGroupsForPropertyValidation,
-                    restrictedGroupsForPropertyValidation,
-                    modelValidationEntryList,
-                    restrictedGroupsForModelValidation);
-        }
-    }
-
-    private void transferGroupValidationInformationToFoundGroups(Object objectToInspect,
-                                                                 List<Class> foundGroupsForPropertyValidation,
-                                                                 List<Class> restrictedGroupsForPropertyValidation,
-                                                                 List<ModelValidationEntry> modelValidationEntryList,
-                                                                 List<Class> restrictedGroupsForModelValidation)
-    {
-        if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.class))
-        {
-            processMetaData(objectToInspect.getClass().getAnnotation(BeanValidation.class),
-                    objectToInspect,
-                    foundGroupsForPropertyValidation,
-                    restrictedGroupsForPropertyValidation,
-                    modelValidationEntryList,
-                    restrictedGroupsForModelValidation);
-        }
-        else if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.List.class))
-        {
-            for(BeanValidation currentBeanValidation :
-                    (objectToInspect.getClass().getAnnotation(BeanValidation.List.class)).value())
-            {
-                processMetaData(currentBeanValidation,
-                        objectToInspect,
-                        foundGroupsForPropertyValidation,
-                        restrictedGroupsForPropertyValidation,
-                        modelValidationEntryList,
-                        restrictedGroupsForModelValidation);
-            }
-        }
-    }
-
-    private void processFieldsAndProperties(String key,
-                                            Object base,
-                                            String property, List<Class> foundGroupsForPropertyValidation,
-                                            List<Class> restrictedGroupsForPropertyValidation,
-                                            List<ModelValidationEntry> modelValidationEntryList,
-                                            List<Class> restrictedGroupsForModelValidation)
-    {
-        PropertyInformation propertyInformation = new DefaultGroupControllerScanningExtractor()
-                .extract(FacesContext.getCurrentInstance(), new PropertyDetails(key, base, property));
-
-        for (MetaDataEntry metaDataEntry : propertyInformation.getMetaDataEntries())
-        {
-            if (metaDataEntry.getValue() instanceof BeanValidation)
-            {
-                processMetaData((BeanValidation) metaDataEntry.getValue(),
-                        base,
-                        foundGroupsForPropertyValidation,
-                        restrictedGroupsForPropertyValidation,
-                        modelValidationEntryList,
-                        restrictedGroupsForModelValidation);
-            }
-            else if(metaDataEntry.getValue() instanceof BeanValidation.List)
-            {
-                for(BeanValidation currentBeanValidation : ((BeanValidation.List)metaDataEntry.getValue()).value())
-                {
-                    processMetaData(currentBeanValidation,
-                            base,
-                            foundGroupsForPropertyValidation,
-                            restrictedGroupsForPropertyValidation,
-                            modelValidationEntryList,
-                            restrictedGroupsForModelValidation);
-                }
-            }
-        }
-    }
-
-    protected void processMetaData(BeanValidation beanValidation,
-                                 Object metaDataSourceObject,
-                                 List<Class> foundGroupsForPropertyValidation,
-                                 List<Class> restrictedGroupsForPropertyValidation,
-                                 List<ModelValidationEntry> modelValidationEntryList,
-                                 List<Class> restrictedGroupsForModelValidation)
-    {
-        for (String currentViewId : beanValidation.viewIds())
-        {
-            if ((currentViewId.equals(FacesContext.getCurrentInstance().getViewRoot().getViewId()) ||
-                    currentViewId.equals("*")) && isValidationPermitted(beanValidation))
-            {
-                if(isModelValidation(beanValidation))
-                {
-                    addModelValidationEntry(
-                            beanValidation, metaDataSourceObject,
-                            modelValidationEntryList, restrictedGroupsForModelValidation);
-                }
-                else
-                {
-                    processGroups(
-                            beanValidation, foundGroupsForPropertyValidation, restrictedGroupsForPropertyValidation);
-                }
-
-                return;
-            }
-        }
-    }
-
-    private void processGroups(BeanValidation beanValidation,
-                           List<Class> foundGroupsForPropertyValidation,
-                           List<Class> restrictedGroupsForPropertyValidation)
-    {
-        foundGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.useGroups()));
-
-        if(!(beanValidation.restrictGroups().length == 1 &&
-                beanValidation.restrictGroups()[0].equals(NoRestrictionGroup.class)))
-        {
-            restrictedGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
-        }
-    }
-
-    private boolean isModelValidation(BeanValidation beanValidation)
-    {
-        return beanValidation.modelValidation().isActive();
-    }
-
-    private void addModelValidationEntry(BeanValidation beanValidation,
-                                         Object metaDataSourceObject,
-                                         List<ModelValidationEntry> modelValidationEntryList,
-                                         List<Class> restrictedGroupsForModelValidation)
-    {
-        ModelValidationEntry modelValidationEntry = new ModelValidationEntry();
-
-        modelValidationEntry.setGroups(Arrays.asList(beanValidation.useGroups()));
-        modelValidationEntry.setMetaData(beanValidation.modelValidation());
-        modelValidationEntry.setMetaDataSourceObject(metaDataSourceObject);
-
-        if(!(beanValidation.restrictGroups().length == 1 &&
-                beanValidation.restrictGroups()[0].equals(NoRestrictionGroup.class)))
-        {
-            restrictedGroupsForModelValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
-        }
-
-        modelValidationEntryList.add(modelValidationEntry);
-    }
-
-    private void addTargetsForModelValidation(ModelValidationEntry modelValidationEntry, Object defaultTarget)
-    {
-        if(modelValidationEntry.getMetaData().validationTargets().length == 1 &&
-                modelValidationEntry.getMetaData().validationTargets()[0].equals(ModelValidation.DEFAULT_TARGET))
-        {
-            modelValidationEntry.addValidationTarget(defaultTarget);
-        }
-        else
-        {
-            Object target;
-            for(String modelValidationTarget : modelValidationEntry.getMetaData().validationTargets())
-            {
-                target = resolveTarget(modelValidationEntry.getMetaDataSourceObject(), modelValidationTarget);
-
-                if(target == null && this.logger.isErrorEnabled())
-                {
-                    this.logger.error("target unreachable - source class: " +
-                            modelValidationEntry.getMetaDataSourceObject().getClass().getName() +
-                            " target to resolve: " + modelValidationTarget);
-                }
-
-                modelValidationEntry.addValidationTarget(target);
-            }
-        }
-    }
-
-    private Object resolveTarget(Object metaDataSourceObject, String modelValidationTarget)
-    {
-        ELHelper elHelper = ExtValUtils.getELHelper();
-
-        if(elHelper.isELTermWellFormed(modelValidationTarget))
-        {
-            if(elHelper.isELTermValid(FacesContext.getCurrentInstance(), modelValidationTarget))
-            {
-                return elHelper.getValueOfExpression(
-                        FacesContext.getCurrentInstance(), new ValueBindingExpression(modelValidationTarget));
-            }
-            else
-            {
-                if(this.logger.isErrorEnabled())
-                {
-                    this.logger.error("an invalid binding is used: " + modelValidationTarget);
-                }
-            }
-        }
-
-        String[] properties = modelValidationTarget.split("\\.");
-
-        Object result = metaDataSourceObject;
-        for(String property : properties)
-        {
-            result = getValueOfProperty(result, property);
-
-            if(result == null)
-            {
-                return null;
-            }
-        }
-
-        return result;
-    }
-
-    @ToDo(value = Priority.HIGH, description = "move to util class - the original method is in LocalCompareStrategy")
-    protected Object getValueOfProperty(Object base, String property)
-    {
-        property = property.substring(0,1).toUpperCase() + property.substring(1, property.length());
-        Method targetMethod = ReflectionUtils.tryToGetMethod(base.getClass(), "get" + property);
-
-        if(targetMethod == null)
-        {
-            targetMethod = ReflectionUtils.tryToGetMethod(base.getClass(), "is" + property);
-        }
-
-        if(targetMethod == null)
-        {
-            throw new IllegalStateException(
-                "class " + base.getClass() + " has no public get/is " + property.toLowerCase());
-        }
-        return ReflectionUtils.tryToInvokeMethod(base, targetMethod);
-    }
-
-    private boolean isValidationPermitted(BeanValidation beanValidation)
-    {
-        ELHelper elHelper = ExtValUtils.getELHelper();
-
-        for(String condition : beanValidation.conditions())
-        {
-            if(elHelper.isELTermWellFormed(condition) &&
-                    elHelper.isELTermValid(FacesContext.getCurrentInstance(), condition))
-            {
-                if(Boolean.TRUE.equals(
-                        elHelper.getValueOfExpression(
-                                FacesContext.getCurrentInstance(), new ValueBindingExpression(condition))))
-                {
-                    return true;
-                }
-            }
-            else
-            {
-                if(this.logger.isErrorEnabled())
-                {
-                    this.logger.error("an invalid condition is used: " + condition);
-                }
-            }
-        }
-        return false;
-    }
 }

Added: myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ValidationGroupProvider.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ValidationGroupProvider.java?rev=778232&view=auto
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ValidationGroupProvider.java (added)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ValidationGroupProvider.java Sun May 24 20:56:33 2009
@@ -0,0 +1,490 @@
+/*
+ * 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.myfaces.extensions.validator.beanval.interceptor;
+
+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.el.ELHelper;
+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
+import org.apache.myfaces.extensions.validator.beanval.validation.ModelValidationEntry;
+import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;
+import org.apache.myfaces.extensions.validator.beanval.annotation.extractor.DefaultGroupControllerScanningExtractor;
+import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;
+import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;
+import org.apache.myfaces.extensions.validator.beanval.annotation.NoRestrictionGroup;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import javax.validation.groups.Default;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+import java.lang.reflect.Method;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.3
+ */
+public class ValidationGroupProvider implements ValidationInterceptor
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    public boolean beforeValidation(FacesContext facesContext,
+                                    UIComponent uiComponent,
+                                    Object convertedObject,
+                                    Map<String, Object> properties)
+    {
+        if(properties.containsKey(PropertyInformation.class.getName()))
+        {
+            addMetaDataToContext(
+                    (PropertyInformation)properties.get(PropertyInformation.class.getName()), uiComponent);
+        }
+        return true;
+    }
+
+    public void afterValidation(FacesContext facesContext,
+                                UIComponent uiComponent,
+                                Object convertedObject,
+                                Map<String, Object> properties)
+    {
+        //not used
+    }
+
+    protected void addMetaDataToContext(PropertyInformation propertyInformation, UIComponent component)
+    {
+        PropertyDetails propertyDetails = propertyInformation
+                .getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);
+
+        String[] key = propertyDetails.getKey().split("\\.");
+
+        Object firstBean = ExtValUtils.getELHelper().getBean(key[0]);
+
+        List<Class> foundGroupsForPropertyValidation = new ArrayList<Class>();
+        List<Class> restrictedGroupsForPropertyValidation = new ArrayList<Class>();
+        List<ModelValidationEntry> modelValidationEntryList = new ArrayList<ModelValidationEntry>();
+        List<Class> restrictedGroupsForModelValidation = new ArrayList<Class>();
+
+        //extract bv-controller-annotation of
+
+        //first bean
+        processClass(firstBean,
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+
+        //first property
+        processFieldsAndProperties(key[0] + "." + key[1],
+                firstBean,
+                key[1],
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+
+        //base object (of target property)
+        processClass(propertyDetails.getBaseObject(),
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+
+        //last property
+        processFieldsAndProperties(
+                propertyDetails.getKey(),
+                propertyDetails.getBaseObject(),
+                propertyDetails.getProperty(),
+                foundGroupsForPropertyValidation,
+                restrictedGroupsForPropertyValidation,
+                modelValidationEntryList,
+                restrictedGroupsForModelValidation);
+
+        ExtValBeanValidationContext extValBeanValidationContext = ExtValBeanValidationContext.getCurrentInstance();
+        String currentViewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
+
+        String clientId = component.getClientId(FacesContext.getCurrentInstance());
+
+        processFoundGroups(extValBeanValidationContext, currentViewId, clientId,
+                foundGroupsForPropertyValidation);
+
+        processRestrictedGroups(extValBeanValidationContext, currentViewId, clientId,
+                restrictedGroupsForPropertyValidation);
+
+        initModelValidation(extValBeanValidationContext, currentViewId, component, propertyDetails,
+                modelValidationEntryList, restrictedGroupsForModelValidation);
+    }
+
+    private void processClass(Object objectToInspect,
+                              List<Class> foundGroupsForPropertyValidation,
+                              List<Class> restrictedGroupsForPropertyValidation,
+                              List<ModelValidationEntry> modelValidationEntryList,
+                              List<Class> restrictedGroupsForModelValidation)
+    {
+        Class classToInspect = objectToInspect.getClass();
+        while (!Object.class.getName().equals(classToInspect.getName()))
+        {
+            transferGroupValidationInformationToFoundGroups(objectToInspect,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation);
+
+            processInterfaces(objectToInspect.getClass(), objectToInspect,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation);
+
+            classToInspect = classToInspect.getSuperclass();
+        }
+    }
+
+    private void processFieldsAndProperties(String key,
+                                            Object base,
+                                            String property, List<Class> foundGroupsForPropertyValidation,
+                                            List<Class> restrictedGroupsForPropertyValidation,
+                                            List<ModelValidationEntry> modelValidationEntryList,
+                                            List<Class> restrictedGroupsForModelValidation)
+    {
+        PropertyInformation propertyInformation = new DefaultGroupControllerScanningExtractor()
+                .extract(FacesContext.getCurrentInstance(), new PropertyDetails(key, base, property));
+
+        for (MetaDataEntry metaDataEntry : propertyInformation.getMetaDataEntries())
+        {
+            if (metaDataEntry.getValue() instanceof BeanValidation)
+            {
+                processMetaData((BeanValidation) metaDataEntry.getValue(),
+                        base,
+                        foundGroupsForPropertyValidation,
+                        restrictedGroupsForPropertyValidation,
+                        modelValidationEntryList,
+                        restrictedGroupsForModelValidation);
+            }
+            else if(metaDataEntry.getValue() instanceof BeanValidation.List)
+            {
+                for(BeanValidation currentBeanValidation : ((BeanValidation.List)metaDataEntry.getValue()).value())
+                {
+                    processMetaData(currentBeanValidation,
+                            base,
+                            foundGroupsForPropertyValidation,
+                            restrictedGroupsForPropertyValidation,
+                            modelValidationEntryList,
+                            restrictedGroupsForModelValidation);
+                }
+            }
+        }
+    }
+
+    protected void processFoundGroups(ExtValBeanValidationContext extValBeanValidationContext,
+                                      String currentViewId,
+                                      String clientId,
+                                      List<Class> foundGroupsForPropertyValidation)
+    {
+        /*
+         * add found groups to context
+         */
+        for (Class currentGroupClass : foundGroupsForPropertyValidation)
+        {
+            extValBeanValidationContext.addGroup(currentGroupClass, currentViewId, clientId);
+        }
+    }
+
+    protected void processRestrictedGroups(ExtValBeanValidationContext extValBeanValidationContext,
+                                         String currentViewId,
+                                         String clientId,
+                                         List<Class> restrictedGroupsForPropertyValidation)
+    {
+        /*
+         * add restricted groups
+         */
+        for (Class currentGroupClass : restrictedGroupsForPropertyValidation)
+        {
+            extValBeanValidationContext.restrictGroup(currentGroupClass, currentViewId, clientId);
+        }
+    }
+
+    protected void initModelValidation(ExtValBeanValidationContext extValBeanValidationContext,
+                                     String currentViewId,
+                                     UIComponent component,
+                                     PropertyDetails propertyDetails,
+                                     List<ModelValidationEntry> modelValidationEntryList,
+                                     List<Class> restrictedGroupsForModelValidation)
+    {
+        /*
+         * add model validation entry list
+         */
+        for(ModelValidationEntry modelValidationEntry : modelValidationEntryList)
+        {
+            if(!"true".equalsIgnoreCase(org.apache.myfaces.extensions.validator.beanval.WebXmlParameter
+                    .DEACTIVATE_IMPLICIT_DEFAULT_GROUP_VALIDATION))
+            {
+                modelValidationEntry.addGroup(Default.class);
+            }
+
+            for(Class restrictedGroup : restrictedGroupsForModelValidation)
+            {
+                modelValidationEntry.removeGroup(restrictedGroup);
+            }
+
+            if(modelValidationEntry.getGroups().length > 0)
+            {
+                addTargetsForModelValidation(modelValidationEntry, propertyDetails.getBaseObject());
+                extValBeanValidationContext.addModelValidationEntry(modelValidationEntry, currentViewId, component);
+            }
+        }
+    }
+
+    private void transferGroupValidationInformationToFoundGroups(Object objectToInspect,
+                                                                 List<Class> foundGroupsForPropertyValidation,
+                                                                 List<Class> restrictedGroupsForPropertyValidation,
+                                                                 List<ModelValidationEntry> modelValidationEntryList,
+                                                                 List<Class> restrictedGroupsForModelValidation)
+    {
+        if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.class))
+        {
+            processMetaData(objectToInspect.getClass().getAnnotation(BeanValidation.class),
+                    objectToInspect,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation);
+        }
+        else if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.List.class))
+        {
+            for(BeanValidation currentBeanValidation :
+                    (objectToInspect.getClass().getAnnotation(BeanValidation.List.class)).value())
+            {
+                processMetaData(currentBeanValidation,
+                        objectToInspect,
+                        foundGroupsForPropertyValidation,
+                        restrictedGroupsForPropertyValidation,
+                        modelValidationEntryList,
+                        restrictedGroupsForModelValidation);
+            }
+        }
+    }
+
+    private void processInterfaces(Class currentClass,
+                                   Object metaDataSourceObject,
+                                   List<Class> foundGroupsForPropertyValidation,
+                                   List<Class> restrictedGroupsForPropertyValidation,
+                                   List<ModelValidationEntry> modelValidationEntryList,
+                                   List<Class> restrictedGroupsForModelValidation)
+    {
+        for (Class currentInterface : currentClass.getInterfaces())
+        {
+            transferGroupValidationInformationToFoundGroups(metaDataSourceObject,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation);
+
+            processInterfaces(currentInterface, metaDataSourceObject,
+                    foundGroupsForPropertyValidation,
+                    restrictedGroupsForPropertyValidation,
+                    modelValidationEntryList,
+                    restrictedGroupsForModelValidation);
+        }
+    }
+
+    protected void processMetaData(BeanValidation beanValidation,
+                                 Object metaDataSourceObject,
+                                 List<Class> foundGroupsForPropertyValidation,
+                                 List<Class> restrictedGroupsForPropertyValidation,
+                                 List<ModelValidationEntry> modelValidationEntryList,
+                                 List<Class> restrictedGroupsForModelValidation)
+    {
+        for (String currentViewId : beanValidation.viewIds())
+        {
+            if ((currentViewId.equals(FacesContext.getCurrentInstance().getViewRoot().getViewId()) ||
+                    currentViewId.equals("*")) && isValidationPermitted(beanValidation))
+            {
+                if(isModelValidation(beanValidation))
+                {
+                    addModelValidationEntry(
+                            beanValidation, metaDataSourceObject,
+                            modelValidationEntryList, restrictedGroupsForModelValidation);
+                }
+                else
+                {
+                    processGroups(
+                            beanValidation, foundGroupsForPropertyValidation, restrictedGroupsForPropertyValidation);
+                }
+
+                return;
+            }
+        }
+    }
+
+    private void addTargetsForModelValidation(ModelValidationEntry modelValidationEntry, Object defaultTarget)
+    {
+        if(modelValidationEntry.getMetaData().validationTargets().length == 1 &&
+                modelValidationEntry.getMetaData().validationTargets()[0].equals(ModelValidation.DEFAULT_TARGET))
+        {
+            modelValidationEntry.addValidationTarget(defaultTarget);
+        }
+        else
+        {
+            Object target;
+            for(String modelValidationTarget : modelValidationEntry.getMetaData().validationTargets())
+            {
+                target = resolveTarget(modelValidationEntry.getMetaDataSourceObject(), modelValidationTarget);
+
+                if(target == null && this.logger.isErrorEnabled())
+                {
+                    this.logger.error("target unreachable - source class: " +
+                            modelValidationEntry.getMetaDataSourceObject().getClass().getName() +
+                            " target to resolve: " + modelValidationTarget);
+                }
+
+                modelValidationEntry.addValidationTarget(target);
+            }
+        }
+    }
+
+    private boolean isValidationPermitted(BeanValidation beanValidation)
+    {
+        ELHelper elHelper = ExtValUtils.getELHelper();
+
+        for(String condition : beanValidation.conditions())
+        {
+            if(elHelper.isELTermWellFormed(condition) &&
+                    elHelper.isELTermValid(FacesContext.getCurrentInstance(), condition))
+            {
+                if(Boolean.TRUE.equals(
+                        elHelper.getValueOfExpression(
+                                FacesContext.getCurrentInstance(), new ValueBindingExpression(condition))))
+                {
+                    return true;
+                }
+            }
+            else
+            {
+                if(this.logger.isErrorEnabled())
+                {
+                    this.logger.error("an invalid condition is used: " + condition);
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isModelValidation(BeanValidation beanValidation)
+    {
+        return beanValidation.modelValidation().isActive();
+    }
+
+    private void addModelValidationEntry(BeanValidation beanValidation,
+                                         Object metaDataSourceObject,
+                                         List<ModelValidationEntry> modelValidationEntryList,
+                                         List<Class> restrictedGroupsForModelValidation)
+    {
+        ModelValidationEntry modelValidationEntry = new ModelValidationEntry();
+
+        modelValidationEntry.setGroups(Arrays.asList(beanValidation.useGroups()));
+        modelValidationEntry.setMetaData(beanValidation.modelValidation());
+        modelValidationEntry.setMetaDataSourceObject(metaDataSourceObject);
+
+        if(!(beanValidation.restrictGroups().length == 1 &&
+                beanValidation.restrictGroups()[0].equals(NoRestrictionGroup.class)))
+        {
+            restrictedGroupsForModelValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
+        }
+
+        modelValidationEntryList.add(modelValidationEntry);
+    }
+
+    private void processGroups(BeanValidation beanValidation,
+                           List<Class> foundGroupsForPropertyValidation,
+                           List<Class> restrictedGroupsForPropertyValidation)
+    {
+        foundGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.useGroups()));
+
+        if(!(beanValidation.restrictGroups().length == 1 &&
+                beanValidation.restrictGroups()[0].equals(NoRestrictionGroup.class)))
+        {
+            restrictedGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));
+        }
+    }
+
+    private Object resolveTarget(Object metaDataSourceObject, String modelValidationTarget)
+    {
+        ELHelper elHelper = ExtValUtils.getELHelper();
+
+        if(elHelper.isELTermWellFormed(modelValidationTarget))
+        {
+            if(elHelper.isELTermValid(FacesContext.getCurrentInstance(), modelValidationTarget))
+            {
+                return elHelper.getValueOfExpression(
+                        FacesContext.getCurrentInstance(), new ValueBindingExpression(modelValidationTarget));
+            }
+            else
+            {
+                if(this.logger.isErrorEnabled())
+                {
+                    this.logger.error("an invalid binding is used: " + modelValidationTarget);
+                }
+            }
+        }
+
+        String[] properties = modelValidationTarget.split("\\.");
+
+        Object result = metaDataSourceObject;
+        for(String property : properties)
+        {
+            result = getValueOfProperty(result, property);
+
+            if(result == null)
+            {
+                return null;
+            }
+        }
+
+        return result;
+    }
+
+    @ToDo(value = Priority.HIGH, description = "move to util class - the original method is in LocalCompareStrategy")
+    protected Object getValueOfProperty(Object base, String property)
+    {
+        property = property.substring(0,1).toUpperCase() + property.substring(1, property.length());
+        Method targetMethod = ReflectionUtils.tryToGetMethod(base.getClass(), "get" + property);
+
+        if(targetMethod == null)
+        {
+            targetMethod = ReflectionUtils.tryToGetMethod(base.getClass(), "is" + property);
+        }
+
+        if(targetMethod == null)
+        {
+            throw new IllegalStateException(
+                "class " + base.getClass() + " has no public get/is " + property.toLowerCase());
+        }
+        return ReflectionUtils.tryToInvokeMethod(base, targetMethod);
+    }
+}

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java Sun May 24 20:56:33 2009
@@ -21,18 +21,22 @@
 import org.apache.myfaces.extensions.validator.core.startup.AbstractStartupListener;
 import org.apache.myfaces.extensions.validator.core.ExtValContext;
 import org.apache.myfaces.extensions.validator.beanval.BeanValidationInterceptor;
+import org.apache.myfaces.extensions.validator.beanval.interceptor.ValidationGroupProvider;
 import org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper
         .DefaultBeanValidationStrategyToMetaDataTransformerNameMapper;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 import org.apache.myfaces.extensions.validator.internal.ToDo;
 import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 
 /**
  * @author Gerhard Petracek
- * @since 1.x.3
+ * @since x.x.3
  */
 @ToDo(value = Priority.HIGH, description = "add optional web.xml param to deactivate" +
         "DefaultBeanValidationStrategyToMetaDataTransformerNameMapper")
+@UsageInformation(UsageCategory.INTERNAL)
 public class BeanValidationStartupListener extends AbstractStartupListener
 {
     private static final long serialVersionUID = -5025748399876833394L;
@@ -41,6 +45,8 @@
     {
         ExtValContext.getContext().registerRendererInterceptor(new BeanValidationInterceptor());
 
+        ExtValContext.getContext().addValidationInterceptor(new ValidationGroupProvider());
+
         ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(
                 new DefaultBeanValidationStrategyToMetaDataTransformerNameMapper());
     }

Modified: myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java?rev=778232&r1=778231&r2=778232&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java (original)
+++ myfaces/extensions/validator/branches/beanval_integration/trunk/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java Sun May 24 20:56:33 2009
@@ -21,6 +21,7 @@
 import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;
 import org.apache.myfaces.extensions.validator.util.JsfUtils;
 import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 import org.apache.myfaces.extensions.validator.internal.UsageInformation;
 import org.apache.myfaces.extensions.validator.internal.UsageCategory;
 import org.apache.myfaces.extensions.validator.crossval.strategy.AbstractCrossValidationStrategy;
@@ -31,6 +32,7 @@
 import javax.faces.event.PhaseListener;
 import javax.faces.validator.ValidatorException;
 import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
 
 /**
  * This phase listener processes cross validation as soon as it finds a special request scoped storage.<br/>
@@ -67,6 +69,16 @@
                                 entry);
                     }
 
+                    if(!ExtValUtils.executeBeforeValidationInterceptors(
+                            FacesContext.getCurrentInstance(),
+                            entry.getComponent(),
+                            entry.getConvertedObject(),
+                            CrossValidationStorageEntry.class.getName(),
+                            entry))
+                    {
+                        continue;
+                    }
+
                     entry.getValidationStrategy().processCrossValidation(entry, crossValidationStorage);
                 }
                 catch (ValidatorException validatorException)
@@ -106,6 +118,15 @@
                         event.getFacesContext().renderResponse();
                     }
                 }
+                finally
+                {
+                    ExtValUtils.executeAfterValidationInterceptors(
+                            FacesContext.getCurrentInstance(),
+                            entry.getComponent(),
+                            entry.getConvertedObject(),
+                            CrossValidationStorageEntry.class.getName(),
+                            entry);
+                }
             }
         }
         finally