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 2014/04/07 16:18:41 UTC

svn commit: r1585490 - in /myfaces/extensions/validator/branches/branch_for_jsf_2_0: core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ validation-module...

Author: gpetracek
Date: Mon Apr  7 14:18:41 2014
New Revision: 1585490

URL: http://svn.apache.org/r1585490
Log:
EXTVAL-156 @SkipConstraintValidation support for ajax listeners

Added:
    myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValAjaxBehavior.java
Modified:
    myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValApplicationWrapper.java
    myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ExtValViewRootInterceptor.java
    myfaces/extensions/validator/branches/branch_for_jsf_2_0/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationViewRootInterceptor.java

Added: myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValAjaxBehavior.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValAjaxBehavior.java?rev=1585490&view=auto
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValAjaxBehavior.java (added)
+++ myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValAjaxBehavior.java Mon Apr  7 14:18:41 2014
@@ -0,0 +1,116 @@
+/*
+ * 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.factory;
+
+import javax.el.MethodExpression;
+import javax.faces.component.behavior.AjaxBehavior;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AjaxBehaviorListener;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class ExtValAjaxBehavior extends AjaxBehavior
+{
+    private Set<MethodExpression> listenerExpressions;
+
+    @Override
+    public void addAjaxBehaviorListener(AjaxBehaviorListener listener)
+    {
+        super.addAjaxBehaviorListener(listener);
+        if (this.listenerExpressions == null)
+        {
+            this.listenerExpressions = new HashSet<MethodExpression>();
+        }
+        this.listenerExpressions.addAll(extractListenerExpressions(listener));
+    }
+
+    @Override
+    public void removeAjaxBehaviorListener(AjaxBehaviorListener listener)
+    {
+        super.removeAjaxBehaviorListener(listener);
+        if (this.listenerExpressions != null)
+        {
+            for (MethodExpression expressionToRemove : extractListenerExpressions(listener))
+            {
+                this.listenerExpressions.remove(expressionToRemove);
+            }
+        }
+    }
+
+    public List<MethodExpression> getListenerExpressions()
+    {
+        if (this.listenerExpressions == null)
+        {
+            return Collections.emptyList();
+        }
+
+        return new ArrayList<MethodExpression>(this.listenerExpressions);
+    }
+
+    @Override
+    public void restoreState(FacesContext facesContext, Object o)
+    {
+        Object[] state = (Object[]) o;
+
+        if (state[0] != null)
+        {
+            this.listenerExpressions = (Set<MethodExpression>) state[0];
+        }
+
+        super.restoreState(facesContext, state[1]);
+    }
+
+    @Override
+    public Object saveState(FacesContext facesContext)
+    {
+        Object[] result = new Object[2];
+
+        result[0] = this.listenerExpressions;
+        result[1] = super.saveState(facesContext);
+        return result;
+    }
+
+    //workaround needed due to a missing api
+    private static List<MethodExpression> extractListenerExpressions(AjaxBehaviorListener listener)
+    {
+        List<MethodExpression> result = new ArrayList<MethodExpression>();
+        for (Field field : listener.getClass().getDeclaredFields())
+        {
+            field.setAccessible(true);
+            try
+            {
+                Object fieldValue = field.get(listener);
+
+                if (fieldValue instanceof MethodExpression)
+                {
+                    result.add((MethodExpression) fieldValue);
+                }
+            }
+            catch (IllegalAccessException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+        return result;
+    }
+}

Modified: myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValApplicationWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValApplicationWrapper.java?rev=1585490&r1=1585489&r2=1585490&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValApplicationWrapper.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ExtValApplicationWrapper.java Mon Apr  7 14:18:41 2014
@@ -27,6 +27,8 @@ import javax.faces.application.Applicati
 import javax.faces.application.Resource;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
+import javax.faces.component.behavior.AjaxBehavior;
+import javax.faces.component.behavior.Behavior;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
 
@@ -120,4 +122,17 @@ class ExtValApplicationWrapper extends A
         }
         return result;
     }
+
+    @Override
+    public Behavior createBehavior(String behaviorId) throws FacesException
+    {
+        Behavior result = wrapped.createBehavior(behaviorId);
+
+        if (result != null && result.getClass().equals(AjaxBehavior.class)) //don't use instanceof
+        {
+            return new ExtValAjaxBehavior();
+
+        }
+        return result;
+    }
 }

Modified: myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ExtValViewRootInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ExtValViewRootInterceptor.java?rev=1585490&r1=1585489&r2=1585490&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ExtValViewRootInterceptor.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_2_0/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ExtValViewRootInterceptor.java Mon Apr  7 14:18:41 2014
@@ -20,6 +20,7 @@ package org.apache.myfaces.extensions.va
 
 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.factory.ExtValAjaxBehavior;
 import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
 import org.apache.myfaces.extensions.validator.core.validation.SkipConstraintValidation;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
@@ -28,11 +29,15 @@ import org.apache.myfaces.extensions.val
 
 import javax.el.MethodExpression;
 import javax.faces.component.ActionSource2;
+import javax.faces.component.EditableValueHolder;
 import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.AjaxBehavior;
 import javax.faces.context.FacesContext;
 import javax.faces.event.ActionEvent;
+import javax.faces.event.AjaxBehaviorEvent;
 import javax.faces.event.FacesEvent;
 import java.lang.reflect.Method;
+import java.util.List;
 
 public class ExtValViewRootInterceptor implements ViewRootInterceptor
 {
@@ -43,10 +48,14 @@ public class ExtValViewRootInterceptor i
         {
             tryToProcessActionMethod((ActionSource2)event.getComponent());
         }
-
+        if (event instanceof AjaxBehaviorEvent && uiComponent instanceof EditableValueHolder &&
+                ((AjaxBehaviorEvent)event).getBehavior() instanceof AjaxBehavior)
+        {
+            tryToProcessAjaxListener(((AjaxBehavior)((AjaxBehaviorEvent)event).getBehavior()));
+        }
     }
 
-    private void tryToProcessActionMethod(ActionSource2 commandComponent)
+    protected void tryToProcessActionMethod(ActionSource2 commandComponent)
     {
         MethodExpression actionExpression = commandComponent.getActionExpression();
 
@@ -71,12 +80,45 @@ public class ExtValViewRootInterceptor i
             return;
         }
 
-        processBypassValidation(facesContext, valueBindingExpression, elHelper);
+        processBypassValidation(facesContext, valueBindingExpression, elHelper, ActionEvent.class);
+    }
+
+    protected void tryToProcessAjaxListener(AjaxBehavior ajaxBehavior)
+    {
+        if (!(ajaxBehavior instanceof ExtValAjaxBehavior))
+        {
+            return;
+        }
+
+        List<MethodExpression> listenerExpressions = ((ExtValAjaxBehavior)ajaxBehavior).getListenerExpressions();
+
+        ELHelper elHelper = ExtValUtils.getELHelper();
+
+        for (MethodExpression listenerExpression : listenerExpressions)
+        {
+            String actionString = listenerExpression.getExpressionString();
+            if(!elHelper.isELTermWellFormed(actionString))
+            {
+                continue;
+            }
+
+            ValueBindingExpression valueBindingExpression = new ValueBindingExpression(actionString);
+
+            FacesContext facesContext = FacesContext.getCurrentInstance();
+            if (!ExtValUtils.getELHelper().isELTermValid(
+                    facesContext, valueBindingExpression.getBaseExpression().getExpressionString()))
+            {
+                continue;
+            }
+
+            processBypassValidation(facesContext, valueBindingExpression, elHelper, AjaxBehaviorEvent.class);
+        }
     }
 
-    private void processBypassValidation(FacesContext facesContext,
-                                         ValueBindingExpression valueBindingExpression,
-                                         ELHelper elHelper)
+    protected void processBypassValidation(FacesContext facesContext,
+                                           ValueBindingExpression valueBindingExpression,
+                                           ELHelper elHelper,
+                                           Class... parameterTypes)
     {
         Object base = elHelper.getValueOfExpression(facesContext, valueBindingExpression.getBaseExpression());
 
@@ -95,11 +137,10 @@ public class ExtValViewRootInterceptor i
 
         Method actionMethod = ReflectionUtils.tryToGetMethod(ProxyUtils.getUnproxiedClass(base.getClass()), methodName);
 
-        //check for an action-listener
         if (actionMethod == null)
         {
             actionMethod = ReflectionUtils.tryToGetMethod(ProxyUtils.getUnproxiedClass(base.getClass()),
-                    methodName, ActionEvent.class);
+                    methodName, parameterTypes);
         }
 
         if (actionMethod == null)

Modified: myfaces/extensions/validator/branches/branch_for_jsf_2_0/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationViewRootInterceptor.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/branch_for_jsf_2_0/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationViewRootInterceptor.java?rev=1585490&r1=1585489&r2=1585490&view=diff
==============================================================================
--- myfaces/extensions/validator/branches/branch_for_jsf_2_0/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationViewRootInterceptor.java (original)
+++ myfaces/extensions/validator/branches/branch_for_jsf_2_0/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationViewRootInterceptor.java Mon Apr  7 14:18:41 2014
@@ -23,6 +23,7 @@ import org.apache.myfaces.extensions.val
 import org.apache.myfaces.extensions.validator.beanval.group.SkipValidation;
 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.factory.ExtValAjaxBehavior;
 import org.apache.myfaces.extensions.validator.core.interceptor.ViewRootInterceptor;
 import org.apache.myfaces.extensions.validator.util.ExtValUtils;
 import org.apache.myfaces.extensions.validator.util.ProxyUtils;
@@ -30,11 +31,15 @@ import org.apache.myfaces.extensions.val
 
 import javax.el.MethodExpression;
 import javax.faces.component.ActionSource2;
+import javax.faces.component.EditableValueHolder;
 import javax.faces.component.UIComponent;
+import javax.faces.component.behavior.AjaxBehavior;
 import javax.faces.context.FacesContext;
 import javax.faces.event.ActionEvent;
+import javax.faces.event.AjaxBehaviorEvent;
 import javax.faces.event.FacesEvent;
 import java.lang.reflect.Method;
+import java.util.List;
 
 public class BeanValidationViewRootInterceptor implements ViewRootInterceptor
 {
@@ -45,6 +50,11 @@ public class BeanValidationViewRootInter
         {
             tryToProcessActionMethod((ActionSource2)event.getComponent());
         }
+        if (event instanceof AjaxBehaviorEvent && uiComponent instanceof EditableValueHolder &&
+                ((AjaxBehaviorEvent)event).getBehavior() instanceof AjaxBehavior)
+        {
+            tryToProcessAjaxListener(((AjaxBehavior)((AjaxBehaviorEvent)event).getBehavior()));
+        }
     }
 
     private void tryToProcessActionMethod(ActionSource2 commandComponent)
@@ -72,12 +82,45 @@ public class BeanValidationViewRootInter
             return;
         }
 
-        processBypassValidation(facesContext, valueBindingExpression, elHelper);
+        processBypassValidation(facesContext, valueBindingExpression, elHelper, ActionEvent.class);
+    }
+
+    private void tryToProcessAjaxListener(AjaxBehavior ajaxBehavior)
+    {
+        if (!(ajaxBehavior instanceof ExtValAjaxBehavior))
+        {
+            return;
+        }
+
+        List<MethodExpression> listenerExpressions = ((ExtValAjaxBehavior)ajaxBehavior).getListenerExpressions();
+
+        ELHelper elHelper = ExtValUtils.getELHelper();
+
+        for (MethodExpression listenerExpression : listenerExpressions)
+        {
+            String actionString = listenerExpression.getExpressionString();
+            if(!elHelper.isELTermWellFormed(actionString))
+            {
+                continue;
+            }
+
+            ValueBindingExpression valueBindingExpression = new ValueBindingExpression(actionString);
+
+            FacesContext facesContext = FacesContext.getCurrentInstance();
+            if (!ExtValUtils.getELHelper().isELTermValid(
+                    facesContext, valueBindingExpression.getBaseExpression().getExpressionString()))
+            {
+                continue;
+            }
+
+            processBypassValidation(facesContext, valueBindingExpression, elHelper, AjaxBehaviorEvent.class);
+        }
     }
 
     private void processBypassValidation(FacesContext facesContext,
                                          ValueBindingExpression valueBindingExpression,
-                                         ELHelper elHelper)
+                                         ELHelper elHelper,
+                                         Class... parameterTypes)
     {
         Object base = elHelper.getValueOfExpression(facesContext, valueBindingExpression.getBaseExpression());
 
@@ -96,11 +139,10 @@ public class BeanValidationViewRootInter
 
         Method actionMethod = ReflectionUtils.tryToGetMethod(ProxyUtils.getUnproxiedClass(base.getClass()), methodName);
 
-        //check for an action-listener
         if (actionMethod == null)
         {
             actionMethod = ReflectionUtils.tryToGetMethod(ProxyUtils.getUnproxiedClass(base.getClass()),
-                    methodName, ActionEvent.class);
+                    methodName, parameterTypes);
         }
 
         if (actionMethod == null)