You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/07/30 22:11:29 UTC

svn commit: r1152504 [1/5] - in /myfaces/core/trunk/impl/src: main/java/org/apache/myfaces/view/facelets/ main/java/org/apache/myfaces/view/facelets/el/ main/java/org/apache/myfaces/view/facelets/tag/ test/java/org/apache/myfaces/view/facelets/tag/comp...

Author: lu4242
Date: Sat Jul 30 20:11:17 2011
New Revision: 1152504

URL: http://svn.apache.org/viewvc?rev=1152504&view=rev
Log:
MYFACES-3251 composite component attributes with @method-signature declared should carry through as MethodExpressions, but do not (allow #{cc.attrs.xxx} on method expressions and action, actionListener, validator and valueChangeListener)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/MethodExpressionMethodExpression.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionActionListener.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValidator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValueChangeListener.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentActionListenerTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentValidatorTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentValueChangeListenerTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/SimpleComponentTagHandler.java
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionListenerNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionListenerNoTarget2_1.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionListenerTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionMethodExpressionNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionMethodExpressionNoTarget2_1.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionMethodExpressionTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeActionMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeMethodExpressionNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeMethodExpressionNoTarget2_1.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValidatorNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValidatorNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValidatorNoTarget2_1.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValidatorTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValidatorTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValueChangeListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValueChangeListenerNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValueChangeListenerNoTarget2_1.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValueChangeListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/compositeAttributeValueChangeListenerTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeActionListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeActionListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeActionListenerTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeActionMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeActionMethodExpressionTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeActionMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeValidatorNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeValidatorTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeValidatorTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeValueChangeListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeValueChangeListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/resources/testComposite/simpleAttributeValueChangeListenerTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionListenerNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionListenerTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionMethodExpressionNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionMethodExpressionTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeActionMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeMethodExpressionNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValidatorNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValidatorNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValidatorTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValidatorTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValueChangeListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValueChangeListenerNoTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValueChangeListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testCompositeAttributeValueChangeListenerTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeActionListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeActionListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeActionListenerTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeActionMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeActionMethodExpressionTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeActionMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeMethodExpressionNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeMethodExpressionTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeValidatorNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeValidatorTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeValidatorTarget2.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeValueChangeListenerNoTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeValueChangeListenerTarget.xhtml
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/testSimpleAttributeValueChangeListenerTarget2.xhtml
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagMethodExpression.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagValueExpression.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/ValueExpressionMethodExpression.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagAttributeImpl.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/CompositeComponentMethodExpressionTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/tag/composite/MockAttributeBean.java
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/tag/composite/test-facelet.taglib.xml

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=1152504&r1=1152503&r2=1152504&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Sat Jul 30 20:11:17 2011
@@ -98,8 +98,14 @@ import org.apache.myfaces.view.facelets.
 import org.apache.myfaces.view.facelets.compiler.Compiler;
 import org.apache.myfaces.view.facelets.compiler.SAXCompiler;
 import org.apache.myfaces.view.facelets.compiler.TagLibraryConfig;
+import org.apache.myfaces.view.facelets.el.CompositeComponentELUtils;
 import org.apache.myfaces.view.facelets.el.LocationMethodExpression;
 import org.apache.myfaces.view.facelets.el.LocationValueExpression;
+import org.apache.myfaces.view.facelets.el.MethodExpressionMethodExpression;
+import org.apache.myfaces.view.facelets.el.RedirectMethodExpressionValueExpressionActionListener;
+import org.apache.myfaces.view.facelets.el.RedirectMethodExpressionValueExpressionValidator;
+import org.apache.myfaces.view.facelets.el.RedirectMethodExpressionValueExpressionValueChangeListener;
+import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression;
 import org.apache.myfaces.view.facelets.el.VariableMapperWrapper;
 import org.apache.myfaces.view.facelets.impl.DefaultFaceletFactory;
 import org.apache.myfaces.view.facelets.impl.DefaultResourceResolver;
@@ -965,53 +971,63 @@ public class FaceletViewDeclarationLangu
                     // evaluated value of the targets attribute..."
                     targets = attributeName; 
                 }
-                
-                ValueExpression attributeNameValueExpression = 
-                    (ValueExpression) topLevelComponent.getAttributes().get(attributeName);
-                
-                if (attributeNameValueExpression == null)
+
+                FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance();
+
+                // If the MethodExpression attribute has been already applied, there is no need to
+                // handle it and it is probably a MethodExpression instance is on attribute map, so the
+                // inner code will cause a ClassCastException.
+                if (!mctx.isMethodExpressionAttributeApplied(topLevelComponent, attributeName))
                 {
-                    // composite:attribute has a default property, so if we can't found on the
-                    // component attribute map, we should get the default as CompositeComponentELResolver
-                    // does.
-                    attributeNameValueExpression = (ValueExpression) propertyDescriptor.getValue("default");
+
+                    ValueExpression attributeNameValueExpression = 
+                        (ValueExpression) topLevelComponent.getAttributes().get(attributeName);
+                    
                     if (attributeNameValueExpression == null)
                     {
-                        // It is only valid to log an error if the attribute is required
-                        ValueExpression ve = (ValueExpression) propertyDescriptor.getValue("required");
-                        if (ve != null)
+                        // composite:attribute has a default property, so if we can't found on the
+                        // component attribute map, we should get the default as CompositeComponentELResolver
+                        // does.
+                        attributeNameValueExpression = (ValueExpression) propertyDescriptor.getValue("default");
+                        if (attributeNameValueExpression == null)
                         {
-                            Object requiredValue = ve.getValue (elContext);
-                            Boolean required = null;
-                            if (requiredValue instanceof Boolean)
-                            {
-                                required = (Boolean) requiredValue;
-                            }
-                            else
+                            // It is only valid to log an error if the attribute is required
+                            ValueExpression ve = (ValueExpression) propertyDescriptor.getValue("required");
+                            if (ve != null)
                             {
-                                required = Boolean.getBoolean(requiredValue.toString());
-                            }
-
-                            if (required != null && required.booleanValue())
-                            {
-                                if (log.isLoggable(Level.SEVERE))
-                                    log.severe("attributeValueExpression not found under the key \""+attributeName+
-                                            "\". Looking for the next attribute");
+                                Object requiredValue = ve.getValue (elContext);
+                                Boolean required = null;
+                                if (requiredValue instanceof Boolean)
+                                {
+                                    required = (Boolean) requiredValue;
+                                }
+                                else
+                                {
+                                    required = Boolean.getBoolean(requiredValue.toString());
+                                }
+    
+                                if (required != null && required.booleanValue())
+                                {
+                                    if (log.isLoggable(Level.SEVERE))
+                                        log.severe("attributeValueExpression not found under the key \""+attributeName+
+                                                "\". Looking for the next attribute");
+                                }
                             }
+                            continue;
                         }
-                        continue;
                     }
-                }
-                
-                String [] targetsArray = StringUtils.splitShortString(targets, ' ');
-                String attributeExpressionString = attributeNameValueExpression.getExpressionString();
-                MethodExpression methodExpression = null;
-                MethodExpression methodExpression2 = null;
-                
-                FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance();
+                    
+                    String [] targetsArray = StringUtils.splitShortString(targets, ' ');
+                    String attributeExpressionString = attributeNameValueExpression.getExpressionString();
+                    MethodExpression methodExpression = null;
+                    MethodExpression methodExpression2 = null;
+
+                    //Check if the stored valueExpression is a ccRedirection, to handle it properly later.
+                    boolean ccAttrMeRedirection = 
+                            attributeNameValueExpression instanceof LocationValueExpression &&
+                                CompositeComponentELUtils.isCompositeComponentAttrsMethodExpression(
+                                attributeNameValueExpression.getExpressionString());
 
-                if (!mctx.isMethodExpressionAttributeApplied(topLevelComponent, attributeName))
-                {
                     String targetAttributeName = null;
                     ValueExpression targetAttributeNameVE = (ValueExpression)propertyDescriptor.getValue("targetAttributeName");
                     if (targetAttributeNameVE != null)
@@ -1032,14 +1048,92 @@ public class FaceletViewDeclarationLangu
                     
                     if (isKnownTargetAttributeMethod)
                     {
+                        // To add support to #{cc.attrs.action}, #{cc.attrs.actionListener}, #{cc.attrs.validator} or
+                        // #{cc.attrs.valueChangeListener} it is necessary to put a MethodExpression or a 
+                        // ValueExpression pointing to the associated java method in the component attribute map.
+                        // org.apache.myfaces.view.facelets.tag.composite.RetargetMethodExpressionRule already put
+                        // a ValueExpression, so we only need to put a MethodExpression when a non redirecting
+                        // expression is used (for example when a nested #{cc.attrs.xxx} is used).
+                        if ("action".equals(attributeName))
+                        {
+                            // target is ActionSource2
+                            methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                    createMethodExpression(elContext,
+                                            attributeExpressionString, null, EMPTY_CLASS_ARRAY), attributeNameValueExpression);
+
+                            //Store the method expression to the topLevelComponent to allow reference it through EL
+                            if (!ccAttrMeRedirection)
+                            {
+                                //Replace it with a method expression
+                                topLevelComponent.getAttributes().put(attributeName, methodExpression);
+                            }
+                            // Otherwise keep the current ValueExpression, because it will be used chain other value expressions
+                        }
+                        else if ("actionListener".equals(attributeName))
+                        {
+                            // target is ActionSource2
+                            methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                    createMethodExpression(elContext,
+                                            attributeExpressionString, Void.TYPE, ACTION_LISTENER_SIGNATURE), attributeNameValueExpression);
+                            
+                            methodExpression2 = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                createMethodExpression(elContext,
+                                        attributeExpressionString, Void.TYPE, EMPTY_CLASS_ARRAY), attributeNameValueExpression);
+                            
+                            //Store the method expression to the topLevelComponent to allow reference it through EL
+                            if (!ccAttrMeRedirection)
+                            {
+                                //Replace it with a method expression
+                                topLevelComponent.getAttributes().put(attributeName, new MethodExpressionMethodExpression(methodExpression, methodExpression2));
+                            }
+                            // Otherwise keep the current ValueExpression, because it will be used chain other value expressions
+                        }
+                        else if ("validator".equals(attributeName))
+                        {
+                            // target is EditableValueHolder
+                            methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                    createMethodExpression(elContext,
+                                        attributeExpressionString, Void.TYPE, 
+                                        VALIDATOR_SIGNATURE), attributeNameValueExpression);
+                            
+                            //Store the method expression to the topLevelComponent to allow reference it through EL
+                            if (!ccAttrMeRedirection)
+                            {
+                                //Replace it with a method expression
+                                topLevelComponent.getAttributes().put(attributeName, methodExpression);
+                            }
+                            // Otherwise keep the current ValueExpression, because it will be used chain other value expressions
+                        }
+                        else if ("valueChangeListener".equals(attributeName))
+                        {
+                            // target is EditableValueHolder
+                            methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                    createMethodExpression(elContext,
+                                            attributeExpressionString, Void.TYPE, 
+                                            VALUE_CHANGE_LISTENER_SIGNATURE), attributeNameValueExpression);
+
+                            methodExpression2 = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                    createMethodExpression(elContext,
+                                            attributeExpressionString, Void.TYPE, 
+                                            EMPTY_CLASS_ARRAY), attributeNameValueExpression);
+
+                            //Store the method expression to the topLevelComponent to allow reference it through EL
+                            if (!ccAttrMeRedirection)
+                            {
+                                //Replace it with a method expression
+                                topLevelComponent.getAttributes().put(attributeName, new MethodExpressionMethodExpression(methodExpression, methodExpression2));
+                            }
+                            // Otherwise keep the current ValueExpression, because it will be used chain other value expressions
+                        }
+
                         for (String target : targetsArray)
                         {
                             UIComponent innerComponent = topLevelComponent.findComponent(target);
                             
                             if (innerComponent == null)
                             {
-                                if (log.isLoggable(Level.SEVERE))
-                                    log.severe("Inner component " + target + " not found when retargetMethodExpressions");
+                                //if (log.isLoggable(Level.SEVERE))
+                                //    log.severe("Inner component " + target + " not found when retargetMethodExpressions");
                                 continue;
                             }
                             
@@ -1060,7 +1154,15 @@ public class FaceletViewDeclarationLangu
                                             createMethodExpression(elContext,
                                                     attributeExpressionString, null, EMPTY_CLASS_ARRAY), attributeNameValueExpression);
                                     
-                                    ((ActionSource2)innerComponent).setActionExpression(methodExpression);
+                                    // If it is a redirection, a wrapper is used to locate the right instance and call it properly. 
+                                    if (ccAttrMeRedirection)
+                                    {
+                                        ((ActionSource2)innerComponent).setActionExpression(new ValueExpressionMethodExpression(attributeNameValueExpression));
+                                    }
+                                    else
+                                    {
+                                        ((ActionSource2)innerComponent).setActionExpression(methodExpression);
+                                    }
                                 }
                                 else if ("actionListener".equals(targetAttributeName))
                                 {
@@ -1072,15 +1174,24 @@ public class FaceletViewDeclarationLangu
                                     }
                                     
                                     // target is ActionSource2
-                                    methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                    ActionListener actionListener = null;
+                                    // If it is a redirection, a wrapper is used to locate the right instance and call it properly.
+                                    if (ccAttrMeRedirection)
+                                    {
+                                        actionListener = new RedirectMethodExpressionValueExpressionActionListener(attributeNameValueExpression);
+                                    }
+                                    else
+                                    {
+                                        methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                                createMethodExpression(elContext,
+                                                        attributeExpressionString, Void.TYPE, ACTION_LISTENER_SIGNATURE), attributeNameValueExpression);
+
+                                        methodExpression2 = reWrapMethodExpression(context.getApplication().getExpressionFactory().
                                             createMethodExpression(elContext,
-                                                    attributeExpressionString, Void.TYPE, ACTION_LISTENER_SIGNATURE), attributeNameValueExpression);
-                                    
-                                    methodExpression2 = reWrapMethodExpression(context.getApplication().getExpressionFactory().
-                                        createMethodExpression(elContext,
-                                                attributeExpressionString, Void.TYPE, EMPTY_CLASS_ARRAY), attributeNameValueExpression);
-                                    
-                                    ActionListener actionListener = new MethodExpressionActionListener(methodExpression, methodExpression2);
+                                                    attributeExpressionString, Void.TYPE, EMPTY_CLASS_ARRAY), attributeNameValueExpression);
+
+                                        actionListener = new MethodExpressionActionListener(methodExpression, methodExpression2);
+                                    }
                                     ((ActionSource2)innerComponent).addActionListener(actionListener);
                                     mctx.addMethodExpressionTargeted(innerComponent, targetAttributeName, actionListener);
                                 }
@@ -1094,12 +1205,21 @@ public class FaceletViewDeclarationLangu
                                     }
                                     
                                     // target is EditableValueHolder
-                                    methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
-                                            createMethodExpression(elContext,
-                                                attributeExpressionString, Void.TYPE, 
-                                                VALIDATOR_SIGNATURE), attributeNameValueExpression);
-        
-                                    Validator validator = new MethodExpressionValidator(methodExpression); 
+                                    Validator validator = null;
+                                    // If it is a redirection, a wrapper is used to locate the right instance and call it properly.
+                                    if (ccAttrMeRedirection)
+                                    {
+                                        validator = new RedirectMethodExpressionValueExpressionValidator(attributeNameValueExpression);
+                                    }
+                                    else
+                                    {
+                                        methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                                createMethodExpression(elContext,
+                                                    attributeExpressionString, Void.TYPE, 
+                                                    VALIDATOR_SIGNATURE), attributeNameValueExpression);
+            
+                                        validator = new MethodExpressionValidator(methodExpression); 
+                                    }
                                     ((EditableValueHolder)innerComponent).addValidator( validator );
                                     mctx.addMethodExpressionTargeted(innerComponent, targetAttributeName, validator);
                                 }
@@ -1112,17 +1232,26 @@ public class FaceletViewDeclarationLangu
                                     }
                                     
                                     // target is EditableValueHolder
-                                    methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
-                                            createMethodExpression(elContext,
-                                                    attributeExpressionString, Void.TYPE, 
-                                                    VALUE_CHANGE_LISTENER_SIGNATURE), attributeNameValueExpression);
-        
-                                    methodExpression2 = reWrapMethodExpression(context.getApplication().getExpressionFactory().
-                                            createMethodExpression(elContext,
-                                                    attributeExpressionString, Void.TYPE, 
-                                                    EMPTY_CLASS_ARRAY), attributeNameValueExpression);
-        
-                                    ValueChangeListener valueChangeListener = new MethodExpressionValueChangeListener(methodExpression, methodExpression2); 
+                                    ValueChangeListener valueChangeListener = null;
+                                    // If it is a redirection, a wrapper is used to locate the right instance and call it properly.
+                                    if (ccAttrMeRedirection)
+                                    {
+                                        valueChangeListener = new RedirectMethodExpressionValueExpressionValueChangeListener(attributeNameValueExpression);
+                                    }
+                                    else
+                                    {
+                                        methodExpression = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                                createMethodExpression(elContext,
+                                                        attributeExpressionString, Void.TYPE, 
+                                                        VALUE_CHANGE_LISTENER_SIGNATURE), attributeNameValueExpression);
+            
+                                        methodExpression2 = reWrapMethodExpression(context.getApplication().getExpressionFactory().
+                                                createMethodExpression(elContext,
+                                                        attributeExpressionString, Void.TYPE, 
+                                                        EMPTY_CLASS_ARRAY), attributeNameValueExpression);
+            
+                                        valueChangeListener = new MethodExpressionValueChangeListener(methodExpression, methodExpression2);
+                                    }
                                     ((EditableValueHolder)innerComponent).addValueChangeListener( valueChangeListener );
                                     mctx.addMethodExpressionTargeted(innerComponent, targetAttributeName, valueChangeListener);
                                 }
@@ -1134,7 +1263,7 @@ public class FaceletViewDeclarationLangu
                         // composite:attribute targets property only has sense for action, actionListener,
                         // validator or valueChangeListener. This means we have to retarget the method expression
                         // to the topLevelComponent.
-                        
+
                         // Since a MethodExpression has no state, we can use it multiple times without problem, so
                         // first create it here.
                         methodSignature = methodSignature.trim();
@@ -1167,11 +1296,25 @@ public class FaceletViewDeclarationLangu
                             else
                             {
                                 //Put the retarget
-                                innerComponent.getAttributes().put(targetAttributeName, methodExpression);
+                                if (ccAttrMeRedirection)
+                                {
+                                    // Since we require here a method expression, it is necessary to wrap the ValueExpression
+                                    // into a MethodExpression that handles redirection.
+                                    innerComponent.getAttributes().put(targetAttributeName, new ValueExpressionMethodExpression(attributeNameValueExpression));
+                                }
+                                else
+                                {
+                                    innerComponent.getAttributes().put(targetAttributeName, methodExpression);
+                                }
                             }
                         }
                         //Store the method expression to the topLevelComponent to allow reference it through EL
-                        topLevelComponent.getAttributes().put(attributeName, methodExpression);
+                        if (!ccAttrMeRedirection)
+                        {
+                            //Replace it with a method expression
+                            topLevelComponent.getAttributes().put(attributeName, methodExpression);
+                        }
+                        // Othewise keep the current ValueExpression, because it will be used chain other value expressions
                     }
                     mctx.markMethodExpressionAttribute(topLevelComponent, attributeName);
                 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/MethodExpressionMethodExpression.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/MethodExpressionMethodExpression.java?rev=1152504&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/MethodExpressionMethodExpression.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/MethodExpressionMethodExpression.java Sat Jul 30 20:11:17 2011
@@ -0,0 +1,134 @@
+/*
+ * 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.view.facelets.el;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.MethodExpression;
+import javax.el.MethodInfo;
+import javax.el.MethodNotFoundException;
+import javax.el.PropertyNotFoundException;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class MethodExpressionMethodExpression extends MethodExpression implements Externalizable {
+    
+    private static final Object[] EMPTY_PARAMS = new Object[0];
+    
+    private MethodExpression methodExpressionOneArg;
+    private MethodExpression methodExpressionZeroArg;
+
+    public MethodExpressionMethodExpression()
+    {
+    }
+    
+    public MethodExpressionMethodExpression(MethodExpression methodExpressionOneArg, MethodExpression methodExpressionZeroArg) {
+        this.methodExpressionOneArg = methodExpressionOneArg;
+        this.methodExpressionZeroArg = methodExpressionZeroArg;
+    }
+
+    @Override
+    public MethodInfo getMethodInfo(ELContext context) throws NullPointerException, PropertyNotFoundException, MethodNotFoundException, ELException
+    {
+        try
+        {
+            // call to the one argument MethodExpression
+            return methodExpressionOneArg.getMethodInfo(context);
+        }
+        catch (MethodNotFoundException mnfe)
+        {
+            // call to the zero argument MethodExpression
+            return methodExpressionZeroArg.getMethodInfo(context);
+        }
+    }
+
+    @Override
+    public Object invoke(ELContext context, Object[] params) throws NullPointerException, PropertyNotFoundException, MethodNotFoundException, ELException 
+    {
+        try
+        {
+            // call to the one argument MethodExpression
+            return methodExpressionOneArg.invoke(context, params);
+        }
+        catch (MethodNotFoundException mnfe)
+        {
+            // call to the zero argument MethodExpression
+            return methodExpressionZeroArg.invoke(context, EMPTY_PARAMS);
+        }
+    }
+
+    @Override
+    public String getExpressionString()
+    {
+        try
+        {
+            // call to the one argument MethodExpression
+            return methodExpressionOneArg.getExpressionString();
+        }
+        catch (MethodNotFoundException mnfe)
+        {
+            // call to the zero argument MethodExpression
+            return methodExpressionZeroArg.getExpressionString();
+        }
+    }
+
+    @Override
+    public boolean isLiteralText()
+    {
+        return false;
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException
+    {
+        out.writeObject(methodExpressionOneArg);
+        out.writeObject(methodExpressionZeroArg);
+    }
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+    {
+        methodExpressionOneArg = (MethodExpression) in.readObject();
+        methodExpressionZeroArg = (MethodExpression) in.readObject();
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj instanceof MethodExpressionMethodExpression)
+        {
+            MethodExpressionMethodExpression me = (MethodExpressionMethodExpression) obj;
+            return methodExpressionOneArg.equals(me.methodExpressionOneArg) && methodExpressionZeroArg.equals(me.methodExpressionZeroArg);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int hash = 3;
+        hash = 19 * hash + (this.methodExpressionOneArg != null ? this.methodExpressionOneArg.hashCode() : 0);
+        hash = 19 * hash + (this.methodExpressionZeroArg != null ? this.methodExpressionZeroArg.hashCode() : 0);
+        return hash;
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionActionListener.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionActionListener.java?rev=1152504&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionActionListener.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionActionListener.java Sat Jul 30 20:11:17 2011
@@ -0,0 +1,96 @@
+/*
+ * 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.view.facelets.el;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import javax.el.ELContext;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+import javax.faces.FacesWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ActionEvent;
+import javax.faces.event.ActionListener;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class RedirectMethodExpressionValueExpressionActionListener
+       implements ActionListener, FacesWrapper<ValueExpression>, Externalizable
+{
+    private ValueExpression valueExpression;
+
+    public RedirectMethodExpressionValueExpressionActionListener()
+    {
+    }
+    
+    public RedirectMethodExpressionValueExpressionActionListener(ValueExpression valueExpression)
+    {
+        this.valueExpression = valueExpression;
+    }
+
+    public void processAction(ActionEvent actionEvent) throws AbortProcessingException
+    {
+        getMethodExpression().invoke(FacesContext.getCurrentInstance().getELContext(), new Object[]{actionEvent});
+    }
+    
+    private MethodExpression getMethodExpression()
+    {
+        return getMethodExpression(FacesContext.getCurrentInstance().getELContext());
+    }
+    
+    private MethodExpression getMethodExpression(ELContext context)
+    {
+        Object meOrVe = valueExpression.getValue(context);
+        if (meOrVe instanceof MethodExpression)
+        {
+            return (MethodExpression) meOrVe;
+        }
+        else if (meOrVe instanceof ValueExpression)
+        {
+            while (meOrVe != null && meOrVe instanceof ValueExpression)
+            {
+                meOrVe = ((ValueExpression)meOrVe).getValue(context);
+            }
+            return (MethodExpression) meOrVe;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    public ValueExpression getWrapped()
+    {
+        return valueExpression;
+    }
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+    {
+        this.valueExpression = (ValueExpression) in.readObject();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException
+    {
+        out.writeObject(this.valueExpression);
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValidator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValidator.java?rev=1152504&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValidator.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValidator.java Sat Jul 30 20:11:17 2011
@@ -0,0 +1,99 @@
+/*
+ * 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.view.facelets.el;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.el.ELContext;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+import javax.faces.FacesWrapper;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class RedirectMethodExpressionValueExpressionValidator
+       implements Validator, FacesWrapper<ValueExpression>, Externalizable
+{
+    private ValueExpression valueExpression;
+
+    public RedirectMethodExpressionValueExpressionValidator()
+    {
+    }
+    
+    public RedirectMethodExpressionValueExpressionValidator(ValueExpression valueExpression)
+    {
+        this.valueExpression = valueExpression;
+    }
+
+    public void validate(FacesContext context, UIComponent component,
+            Object value) throws ValidatorException
+    {
+        getMethodExpression().invoke(FacesContext.getCurrentInstance().getELContext(), new Object[]{context,component,value});
+    }
+
+    private MethodExpression getMethodExpression()
+    {
+        return getMethodExpression(FacesContext.getCurrentInstance().getELContext());
+    }
+    
+    private MethodExpression getMethodExpression(ELContext context)
+    {
+        Object meOrVe = valueExpression.getValue(context);
+        if (meOrVe instanceof MethodExpression)
+        {
+            return (MethodExpression) meOrVe;
+        }
+        else if (meOrVe instanceof ValueExpression)
+        {
+            while (meOrVe != null && meOrVe instanceof ValueExpression)
+            {
+                meOrVe = ((ValueExpression)meOrVe).getValue(context);
+            }
+            return (MethodExpression) meOrVe;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    public ValueExpression getWrapped()
+    {
+        return valueExpression;
+    }
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+    {
+        this.valueExpression = (ValueExpression) in.readObject();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException
+    {
+        out.writeObject(this.valueExpression);
+    }
+
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValueChangeListener.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValueChangeListener.java?rev=1152504&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValueChangeListener.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/RedirectMethodExpressionValueExpressionValueChangeListener.java Sat Jul 30 20:11:17 2011
@@ -0,0 +1,98 @@
+/*
+ * 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.view.facelets.el;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.el.ELContext;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
+import javax.faces.FacesWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.ValueChangeEvent;
+import javax.faces.event.ValueChangeListener;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class RedirectMethodExpressionValueExpressionValueChangeListener
+       implements ValueChangeListener, FacesWrapper<ValueExpression>, Externalizable
+{
+    private ValueExpression valueExpression;
+
+    public RedirectMethodExpressionValueExpressionValueChangeListener()
+    {
+    }
+    
+    public RedirectMethodExpressionValueExpressionValueChangeListener(ValueExpression valueExpression)
+    {
+        this.valueExpression = valueExpression;
+    }
+
+    public void processValueChange(ValueChangeEvent event) throws AbortProcessingException
+    {
+        getMethodExpression().invoke(FacesContext.getCurrentInstance().getELContext(), new Object[]{event});
+    }
+
+    private MethodExpression getMethodExpression()
+    {
+        return getMethodExpression(FacesContext.getCurrentInstance().getELContext());
+    }
+    
+    private MethodExpression getMethodExpression(ELContext context)
+    {
+        Object meOrVe = valueExpression.getValue(context);
+        if (meOrVe instanceof MethodExpression)
+        {
+            return (MethodExpression) meOrVe;
+        }
+        else if (meOrVe instanceof ValueExpression)
+        {
+            while (meOrVe != null && meOrVe instanceof ValueExpression)
+            {
+                meOrVe = ((ValueExpression)meOrVe).getValue(context);
+            }
+            return (MethodExpression) meOrVe;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    public ValueExpression getWrapped()
+    {
+        return valueExpression;
+    }
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+    {
+        this.valueExpression = (ValueExpression) in.readObject();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException
+    {
+        out.writeObject(this.valueExpression);
+    }
+
+}

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagMethodExpression.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagMethodExpression.java?rev=1152504&r1=1152503&r2=1152504&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagMethodExpression.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagMethodExpression.java Sat Jul 30 20:11:17 2011
@@ -70,19 +70,19 @@ public final class TagMethodExpression e
         }
         catch (PropertyNotFoundException pnfe)
         {
-            throw new ContextAwarePropertyNotFoundException(getLocation(), getExpressionString(), getQName(), pnfe);
+            throw new ContextAwarePropertyNotFoundException(getLocation(), getLocalExpressionString(), getQName(), pnfe);
         }
         catch (MethodNotFoundException mnfe)
         {
-            throw new ContextAwareMethodNotFoundException(getLocation(), getExpressionString(), getQName(), mnfe);
+            throw new ContextAwareMethodNotFoundException(getLocation(), getLocalExpressionString(), getQName(), mnfe);
         }
         catch (ELException e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         } 
         catch (Exception e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
     }
 
@@ -94,22 +94,37 @@ public final class TagMethodExpression e
         }
         catch (PropertyNotFoundException pnfe)
         {
-            throw new ContextAwarePropertyNotFoundException(getLocation(), getExpressionString(), getQName(), pnfe);
+            throw new ContextAwarePropertyNotFoundException(getLocation(), getLocalExpressionString(), getQName(), pnfe);
         }
         catch (MethodNotFoundException mnfe)
         {
-            throw new ContextAwareMethodNotFoundException(getLocation(), getExpressionString(), getQName(), mnfe);
+            throw new ContextAwareMethodNotFoundException(getLocation(), getLocalExpressionString(), getQName(), mnfe);
         }
         catch (ELException e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
         catch (Exception e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
     }
 
+        
+    private String getLocalExpressionString()
+    {
+        String expressionString = null;
+        try
+        {
+            expressionString = getExpressionString();
+        }
+        catch (Throwable t)
+        {
+            //swallo it because it is not important
+        }
+        return expressionString;
+    }
+
     public String getExpressionString()
     {
         return _wrapped.getExpressionString();

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagValueExpression.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagValueExpression.java?rev=1152504&r1=1152503&r2=1152504&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagValueExpression.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/TagValueExpression.java Sat Jul 30 20:11:17 2011
@@ -74,15 +74,15 @@ public class TagValueExpression extends 
         }
         catch (PropertyNotFoundException pnfe)
         {
-            throw new ContextAwarePropertyNotFoundException(getLocation(), getExpressionString(), getQName(), pnfe);
+            throw new ContextAwarePropertyNotFoundException(getLocation(), getLocalExpressionString(), getQName(), pnfe);
         }
         catch (ELException e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
         catch (Exception e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e); 
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e); 
         }
     }
 
@@ -94,17 +94,31 @@ public class TagValueExpression extends 
         }
         catch (PropertyNotFoundException pnfe)
         {
-            throw new ContextAwarePropertyNotFoundException(getLocation(), getExpressionString(), getQName(), pnfe);
+            throw new ContextAwarePropertyNotFoundException(getLocation(), getLocalExpressionString(), getQName(), pnfe);
         }
         catch (ELException e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
         catch (Exception e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
     }
+    
+    private String getLocalExpressionString()
+    {
+        String expressionString = null;
+        try
+        {
+            expressionString = getExpressionString();
+        }
+        catch (Throwable t)
+        {
+            //swallo it because it is not important
+        }
+        return expressionString;
+    }
 
     public boolean isReadOnly(ELContext context)
     {
@@ -114,15 +128,15 @@ public class TagValueExpression extends 
         }
         catch (PropertyNotFoundException pnfe)
         {
-            throw new ContextAwarePropertyNotFoundException(getLocation(), getExpressionString(), getQName(), pnfe);
+            throw new ContextAwarePropertyNotFoundException(getLocation(), getLocalExpressionString(), getQName(), pnfe);
         }
         catch (ELException e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
         catch (Exception e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
         
     }
@@ -135,19 +149,19 @@ public class TagValueExpression extends 
         }
         catch (PropertyNotFoundException pnfe)
         {
-            throw new ContextAwarePropertyNotFoundException(getLocation(), getExpressionString(), getQName(), pnfe);
+            throw new ContextAwarePropertyNotFoundException(getLocation(), getLocalExpressionString(), getQName(), pnfe);
         }
         catch (PropertyNotWritableException pnwe)
         {
-            throw new ContextAwarePropertyNotWritableException(getLocation(), getExpressionString(), getQName(), pnwe);
+            throw new ContextAwarePropertyNotWritableException(getLocation(), getLocalExpressionString(), getQName(), pnwe);
         }
         catch (ELException e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
         catch (Exception e)
         {
-            throw new ContextAwareELException(getLocation(), getExpressionString(), getQName(), e);
+            throw new ContextAwareELException(getLocation(), getLocalExpressionString(), getQName(), e);
         }
     }
     

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/ValueExpressionMethodExpression.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/ValueExpressionMethodExpression.java?rev=1152504&r1=1152503&r2=1152504&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/ValueExpressionMethodExpression.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/el/ValueExpressionMethodExpression.java Sat Jul 30 20:11:17 2011
@@ -77,7 +77,8 @@ public class ValueExpressionMethodExpres
     @Override
     public String getExpressionString()
     {
-        return getMethodExpression().getExpressionString();
+        //getMethodExpression().getExpressionString()
+        return valueExpression.getExpressionString();
     }
 
     @Override
@@ -99,7 +100,23 @@ public class ValueExpressionMethodExpres
     
     private MethodExpression getMethodExpression(ELContext context)
     {
-        return (MethodExpression) valueExpression.getValue(context);
+        Object meOrVe = valueExpression.getValue(context);
+        if (meOrVe instanceof MethodExpression)
+        {
+            return (MethodExpression) meOrVe;
+        }
+        else if (meOrVe instanceof ValueExpression)
+        {
+            while (meOrVe != null && meOrVe instanceof ValueExpression)
+            {
+                meOrVe = ((ValueExpression)meOrVe).getValue(context);
+            }
+            return (MethodExpression) meOrVe;
+        }
+        else
+        {
+            return null;
+        }
     }
 
     public ValueExpression getWrapped()

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagAttributeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagAttributeImpl.java?rev=1152504&r1=1152503&r2=1152504&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagAttributeImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/TagAttributeImpl.java Sat Jul 30 20:11:17 2011
@@ -241,7 +241,7 @@ public final class TagAttributeImpl exte
                             + "pointing to cc.attrs");
                 }
                 
-                ValueExpression valueExpr = this.getValueExpression(ctx, MethodExpression.class);
+                ValueExpression valueExpr = this.getValueExpression(ctx, Object.class);
                 methodExpression = new ValueExpressionMethodExpression(valueExpr);
             }
             else