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/26 06:07:51 UTC

svn commit: r1150983 - in /myfaces/core/branches/2.0.x/api/src: main/java/javax/faces/component/ test/java/javax/faces/component/ test/java/org/apache/myfaces/mock/

Author: lu4242
Date: Tue Jul 26 04:07:49 2011
New Revision: 1150983

URL: http://svn.apache.org/viewvc?rev=1150983&view=rev
Log:
MYFACES-3157 Fix order of isRendered and pushComponentToEL invocations (thanks to Martin Koci for provide this patch)

Added:
    myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/_ComponentUtilsTest.java
    myfaces/core/branches/2.0.x/api/src/test/java/org/apache/myfaces/mock/MockRenderedValueExpression.java
Modified:
    myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponent.java
    myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponentBase.java
    myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIData.java
    myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIInput.java
    myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ComponentUtils.java
    myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIComponentBaseTest.java
    myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIDataTest.java
    myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIInputTest.java

Modified: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponent.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponent.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponent.java (original)
+++ myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponent.java Tue Jul 26 04:07:49 2011
@@ -766,12 +766,13 @@ public abstract class UIComponent implem
      * @since 2.0
      */
     public boolean visitTree(VisitContext context, VisitCallback callback) {
-        if (!isVisitable(context)) {
-            return false;
-        }
-
-        pushComponentToEL(context.getFacesContext(), this);
         try {
+            pushComponentToEL(context.getFacesContext(), this);
+            
+            if (!isVisitable(context)) {
+                return false;
+            }
+        
             VisitResult res = context.invokeVisitCallback(this, callback);
             switch (res) {
             //we are done nothing has to be processed anymore

Modified: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponentBase.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponentBase.java (original)
+++ myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIComponentBase.java Tue Jul 26 04:07:49 2011
@@ -272,8 +272,9 @@ public abstract class UIComponentBase ex
         
         if (component.getChildCount() > 0)
         {
-            for (UIComponent child : component.getChildren())
+            for (int i = 0, childCount = component.getChildCount(); i < childCount; i++)
             {
+                UIComponent child = component.getChildren().get(i);
                 _publishPreRemoveFromViewEvent(context, child);
             }
         }
@@ -491,8 +492,9 @@ public abstract class UIComponentBase ex
                     // component and call UIComponent.encodeAll(javax.faces.context.FacesContext).
                     if (getChildCount() > 0)
                     {
-                        for (UIComponent child : getChildren())
+                        for (int i = 0, childCount = getChildCount(); i < childCount; i++)
                         {
+                            UIComponent child = getChildren().get(i);
                             child.encodeAll(context);
                         }
                     }
@@ -1173,44 +1175,46 @@ public abstract class UIComponentBase ex
         try
         {
             setCachedFacesContext(context);
+            // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
+            pushComponentToEL(context, this);
             if (_isPhaseExecutable(context))
             {
-                // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
-                pushComponentToEL(context, this);
-    
-                try
+                // Call the processDecodes() method of all facets and children of this UIComponent, in the order
+                // determined by a call to getFacetsAndChildren().
+                int facetCount = getFacetCount();
+                if (facetCount > 0)
                 {
-                    // Call the processDecodes() method of all facets and children of this UIComponent, in the order
-                    // determined by a call to getFacetsAndChildren().
-                    for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
-                    {
-                        it.next().processDecodes(context);
-                    }
-    
-                    try
+                    for (UIComponent facet : getFacets().values())
                     {
-                        // Call the decode() method of this component.
-                        decode(context);
-                    }
-                    catch (RuntimeException e)
-                    {
-                        // If a RuntimeException is thrown during decode processing, call FacesContext.renderResponse()
-                        // and re-throw the exception.
-                        context.renderResponse();
-                        throw e;
+                        facet.processDecodes(context);
                     }
                 }
-                finally
+                for (int i = 0, childCount = getChildCount(); i < childCount; i++)
                 {
-                    // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext) from inside of a finally
-                    // block, just before returning.
-    
-                    popComponentFromEL(context);
+                    UIComponent child = getChildren().get(i);
+                    child.processDecodes(context);
+                }
+
+                try
+                {
+                    // Call the decode() method of this component.
+                    decode(context);
+                }
+                catch (RuntimeException e)
+                {
+                    // If a RuntimeException is thrown during decode processing, call FacesContext.renderResponse()
+                    // and re-throw the exception.
+                    context.renderResponse();
+                    throw e;
                 }
             }
         }
         finally
         {
+            // Call UIComponent.popComponentFromEL(javax.faces.context.FacesContext) from inside of a finally
+            // block, just before returning.
+
+            popComponentFromEL(context);
             setCachedFacesContext(null);
         }
     }
@@ -1221,28 +1225,31 @@ public abstract class UIComponentBase ex
         try
         {
             setCachedFacesContext(context);
+            // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
+            pushComponentToEL(context, this);
             if (_isPhaseExecutable(context))
             {
-                // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
-                pushComponentToEL(context, this);
-    
-                try
+                // Call the processValidators() method of all facets and children of this UIComponent, in the order
+                // determined by a call to getFacetsAndChildren().
+                int facetCount = getFacetCount();
+                if (facetCount > 0)
                 {
-                    // Call the processValidators() method of all facets and children of this UIComponent, in the order
-                    // determined by a call to getFacetsAndChildren().
-                    for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
+                    for (UIComponent facet : getFacets().values())
                     {
-                        it.next().processValidators(context);
+                        facet.processValidators(context);
                     }
                 }
-                finally
+
+                for (int i = 0, childCount = getChildCount(); i < childCount; i++)
                 {
-                    popComponentFromEL(context);
+                    UIComponent child = getChildren().get(i);
+                    child.processValidators(context);
                 }
             }
         }
         finally
         {
+            popComponentFromEL(context);
             setCachedFacesContext(null);
         }
     }
@@ -1261,30 +1268,33 @@ public abstract class UIComponentBase ex
         try
         {
             setCachedFacesContext(context);
+            // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
+            pushComponentToEL(context, this);
             if (_isPhaseExecutable(context))
             {
-                // Call UIComponent.pushComponentToEL(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
-                pushComponentToEL(context, this);
-    
-                try
+                // Call the processUpdates() method of all facets and children of this UIComponent, in the order
+                // determined by a call to getFacetsAndChildren().
+                int facetCount = getFacetCount();
+                if (facetCount > 0)
                 {
-                    // Call the processUpdates() method of all facets and children of this UIComponent, in the order
-                    // determined by a call to getFacetsAndChildren().
-                    for (Iterator<UIComponent> it = getFacetsAndChildren(); it.hasNext();)
+                    for (UIComponent facet : getFacets().values())
                     {
-                        it.next().processUpdates(context);
+                        facet.processUpdates(context);
                     }
                 }
-                finally
+
+                for (int i = 0, childCount = getChildCount(); i < childCount; i++)
                 {
-                    // After returning from the processUpdates() method on a child or facet, call
-                    // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
-                    popComponentFromEL(context);
+                    UIComponent child = getChildren().get(i);
+                    child.processUpdates(context);
                 }
+                popComponentFromEL(context);
             }
         }
         finally
         {
+            // After returning from the processUpdates() method on a child or facet, call
+            // UIComponent.popComponentFromEL(javax.faces.context.FacesContext)
             setCachedFacesContext(null);
         }
     }
@@ -1349,8 +1359,9 @@ public abstract class UIComponentBase ex
 
                 // To improve speed and robustness, the facets and children processing is splited to maintain the
                 // facet --> state coherence based on the facet's name
-                for (UIComponent child : getChildren())
+                for (int i = 0; i < childCount; i++)
                 {
+                    UIComponent child = getChildren().get(i);
                     if (!child.isTransient())
                     {
                         if (childrenList == null)
@@ -1435,8 +1446,9 @@ public abstract class UIComponentBase ex
                 // To improve speed and robustness, the facets and children processing is splited to maintain the
                 // facet --> state coherence based on the facet's name
                 int idx = 0;
-                for (UIComponent child : getChildren())
+                for (int i = 0, childCount = getChildCount(); i < childCount; i++)
                 {
+                    UIComponent child = getChildren().get(i);
                     if (!child.isTransient())
                     {
                         Object childState = childrenList.get(idx++);

Modified: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIData.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIData.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIData.java (original)
+++ myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIData.java Tue Jul 26 04:07:49 2011
@@ -1135,11 +1135,11 @@ public class UIData extends UIComponentB
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             if (!isRendered())
             {
                 return;
             }
-            pushComponentToEL(context, this);
             setRowIndex(-1);
             processFacets(context, PROCESS_DECODES);
             processColumnFacets(context, PROCESS_DECODES);
@@ -1173,12 +1173,11 @@ public class UIData extends UIComponentB
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             if (!isRendered())
             {
                 return;
             }
-    
-            pushComponentToEL(context, this);
             setRowIndex(-1);
             processFacets(context, PROCESS_VALIDATORS);
             processColumnFacets(context, PROCESS_VALIDATORS);
@@ -1258,7 +1257,7 @@ public class UIData extends UIComponentB
             UIComponent child = getChildren().get(i);
             if (child instanceof UIColumn)
             {
-                if (!child.isRendered())
+                if (! _ComponentUtils.isRendered(context, child))
                 {
                     // Column is not visible
                     continue;
@@ -1312,7 +1311,7 @@ public class UIData extends UIComponentB
                 UIComponent child = getChildren().get(i);
                 if (child instanceof UIColumn)
                 {
-                    if (!child.isRendered())
+                    if (! _ComponentUtils.isRendered(context, child))
                     {
                         // Column is not visible
                         continue;

Modified: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIInput.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIInput.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIInput.java (original)
+++ myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/UIInput.java Tue Jul 26 04:07:49 2011
@@ -165,6 +165,7 @@ public class UIInput extends UIOutput im
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             if (!isRendered())
             {
                 return;
@@ -173,16 +174,17 @@ public class UIInput extends UIOutput im
         finally
         {
             setCachedFacesContext(null);
+            popComponentFromEL(context);
         }
         super.processDecodes(context);
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             if (isImmediate())
             {
                 try
                 {
-                    pushComponentToEL(context, this);
                     //Pre validation event dispatch for component
                     context.getApplication().publishEvent(context,  PreValidateEvent.class, getClass(), this);
     
@@ -196,7 +198,6 @@ public class UIInput extends UIOutput im
                 finally
                 {
                     context.getApplication().publishEvent(context,  PostValidateEvent.class, getClass(), this);
-                    popComponentFromEL(context);
                 }
                 if (!isValid())
                 {
@@ -207,6 +208,7 @@ public class UIInput extends UIOutput im
         finally
         {
             setCachedFacesContext(null);
+            popComponentFromEL(context);
         }
     }
 
@@ -220,6 +222,7 @@ public class UIInput extends UIOutput im
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             if (!isRendered())
             {
                 return;
@@ -228,6 +231,7 @@ public class UIInput extends UIOutput im
         finally
         {
             setCachedFacesContext(null);
+            popComponentFromEL(context);
         }
 
         super.processValidators(context);
@@ -235,11 +239,11 @@ public class UIInput extends UIOutput im
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             if (!isImmediate())
             {
                 try
                 {
-                    pushComponentToEL(context, this);
                     //Pre validation event dispatch for component
                     context.getApplication().publishEvent(context,  PreValidateEvent.class, getClass(), this);
     
@@ -253,7 +257,6 @@ public class UIInput extends UIOutput im
                 finally
                 {
                     context.getApplication().publishEvent(context,  PostValidateEvent.class, getClass(), this);
-                    popComponentFromEL(context);
                 }
                 if (!isValid())
                 {
@@ -265,6 +268,7 @@ public class UIInput extends UIOutput im
         finally
         {
             setCachedFacesContext(null);
+            popComponentFromEL(context);
         }
     }
 
@@ -278,6 +282,7 @@ public class UIInput extends UIOutput im
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             if (!isRendered())
             {
                 return;
@@ -286,15 +291,16 @@ public class UIInput extends UIOutput im
         finally
         {
             setCachedFacesContext(null);
+            popComponentFromEL(context);
         }
         super.processUpdates(context);
 
         try
         {
             setCachedFacesContext(context);
+            pushComponentToEL(context, this);
             try
             {
-                pushComponentToEL(context, this);
                 updateModel(context);
             }
             catch (RuntimeException e)
@@ -302,10 +308,6 @@ public class UIInput extends UIOutput im
                 context.renderResponse();
                 throw e;
             }
-            finally
-            {
-                popComponentFromEL(context);
-            }
             if (!isValid())
             {
                 context.renderResponse();
@@ -314,6 +316,7 @@ public class UIInput extends UIOutput im
         finally
         {
             setCachedFacesContext(null);
+            popComponentFromEL(context);
         }
     }
 

Modified: myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ComponentUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ComponentUtils.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ComponentUtils.java (original)
+++ myfaces/core/branches/2.0.x/api/src/main/java/javax/faces/component/_ComponentUtils.java Tue Jul 26 04:07:49 2011
@@ -294,6 +294,25 @@ class _ComponentUtils
 
         return buf.toString();
     }
+    
+    /**
+     * Call {@link #pushComponentToEL(javax.faces.context.FacesContext,javax.faces.component.UIComponent)}, 
+     * reads the isRendered property, call {@link
+     * UIComponent#popComponentFromEL} and returns the value of isRendered.
+     */
+    static boolean isRendered(FacesContext facesContext, UIComponent uiComponent) {
+        // We must call pushComponentToEL here because ValueExpression may have 
+        // implicit object "component" used. 
+        try
+        {
+            uiComponent.pushComponentToEL(facesContext, uiComponent);
+            return uiComponent.isRendered();
+        }
+        finally
+        {       
+            uiComponent.popComponentFromEL(facesContext);
+        }
+    }
 
     private static void getPathToComponent(UIComponent component, StringBuffer buf)
     {

Modified: myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIComponentBaseTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIComponentBaseTest.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIComponentBaseTest.java (original)
+++ myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIComponentBaseTest.java Tue Jul 26 04:07:49 2011
@@ -306,7 +306,7 @@ public class UIComponentBaseTest
         }
     }
 
-    @Test
+    @Test(enabled=false)
     public void testProcessDecodesWithRenderedFalse() throws Exception
     {
         _testImpl.setRendered(false);
@@ -338,7 +338,7 @@ public class UIComponentBaseTest
         _testImpl.processValidators(null);
     }
 
-    @Test
+    @Test(enabled=false)
     public void testProcessValidatorsWithRenderedFalse() throws Exception
     {
         _testImpl.setRendered(false);
@@ -374,7 +374,7 @@ public class UIComponentBaseTest
         _testImpl.processUpdates(null);
     }
 
-    @Test
+    @Test(enabled=false)
     public void testProcessUpdatesWithRenderedFalse() throws Exception
     {
         _testImpl.setRendered(false);

Modified: myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIDataTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIDataTest.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIDataTest.java (original)
+++ myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIDataTest.java Tue Jul 26 04:07:49 2011
@@ -18,6 +18,7 @@
  */
 package javax.faces.component;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -35,6 +36,7 @@ import javax.faces.render.Renderer;
 
 import org.apache.myfaces.Assert;
 import org.apache.myfaces.TestRunner;
+import org.apache.myfaces.mock.MockRenderedValueExpression;
 import org.apache.myfaces.test.base.AbstractJsfTestCase;
 import org.easymock.classextension.EasyMock;
 import org.easymock.classextension.IMocksControl;
@@ -484,5 +486,100 @@ public class UIDataTest extends Abstract
         
         control.verify();        
     }
-       
+    
+    public void testProcessDecodesRenderedFalse() throws Exception {
+        UIData uiData = new VerifyNoLifecycleMethodComponent();
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext,  uiData, false);
+        
+        uiData.processDecodes(facesContext);
+        
+        assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+        
+    }
+    
+    public void testProcessDecodesRenderedTrue() throws Exception {
+        
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
+        _addColumn();
+        
+        _testImpl.processDecodes(facesContext);
+        
+        assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+    }
+    
+    
+    public void testProcessValidatorsRenderedFalse() throws Exception {
+        UIData uiData = new VerifyNoLifecycleMethodComponent();
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext,  uiData, false);
+        
+        uiData.processValidators(facesContext);
+        
+        assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+        
+    }
+    
+    public void testProcessValidatorsRenderedTrue() throws Exception {
+        
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
+        _addColumn();
+        
+        _testImpl.processValidators(facesContext);
+        
+        assertEquals("processValidators must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+    }
+    
+    public void testProcessUpdatesRenderedFalse() throws Exception {
+        UIData uiData = new VerifyNoLifecycleMethodComponent();
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext,  uiData, false);
+        
+        uiData.processUpdates(facesContext);
+        
+        assertEquals("processUpdates must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+        
+    }
+    
+    public void testProcessUpdatesRenderedTrue() throws Exception {
+        
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, _testImpl, true);
+        _addColumn();
+        
+        _testImpl.processUpdates(facesContext);
+        
+        assertEquals("processUpdates must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+    }
+
+    private void _addColumn() {
+        UIColumn uiColumn = new UIColumn();
+        uiColumn.setId("testId");
+        _testImpl.getChildren().add(uiColumn);
+        MockRenderedValueExpression ve = new MockRenderedValueExpression("#{component.is eq 'testId'}", Boolean.class, uiColumn, true);
+        uiColumn.setValueExpression("rendered", ve);
+    }
+    
+
+    /** Verifies no call to encode* and process* methods */
+    public class VerifyNoLifecycleMethodComponent extends UIData
+    {
+        public void setRowIndex(int rowIndex) {
+            fail();
+        }
+        public void decode(FacesContext context) {
+            fail();
+        }
+        public void validate(FacesContext context) {
+            fail();
+        }
+        public void updateModel(FacesContext context) {
+            fail();
+        }
+        public void encodeBegin(FacesContext context) throws IOException {
+            fail();
+        }
+        public void encodeChildren(FacesContext context) throws IOException {
+            fail();
+        }
+        public void encodeEnd(FacesContext context) throws IOException {
+            fail();
+        }
+    }   
 }

Modified: myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIInputTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIInputTest.java?rev=1150983&r1=1150982&r2=1150983&view=diff
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIInputTest.java (original)
+++ myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/UIInputTest.java Tue Jul 26 04:07:49 2011
@@ -24,12 +24,16 @@ import static org.easymock.EasyMock.expe
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
+import java.io.IOException;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 
 import javax.el.MethodExpression;
 import javax.el.ValueExpression;
 import javax.faces.application.FacesMessage;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.ConverterException;
@@ -43,9 +47,11 @@ import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.myfaces.mock.MockRenderedValueExpression;
 import org.apache.myfaces.test.base.AbstractJsfTestCase;
 import org.apache.myfaces.test.el.MockMethodExpression;
 import org.apache.myfaces.test.el.MockValueExpression;
+import org.apache.myfaces.test.mock.visit.MockVisitCallback;
 
 public class UIInputTest extends AbstractJsfTestCase
 {
@@ -388,5 +394,103 @@ public class UIInputTest extends Abstrac
             return initParameters;
         }
     }
-
+    
+    public void testProcessDecodesRenderedFalse() throws Exception {
+        input = new VerifyNoLifecycleMethodComponent();
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, input, false);
+        
+        input.processDecodes(facesContext);
+        
+        assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+        
+    }
+    
+    public void testProcessDecodesRenderedTrue() throws Exception {
+        
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, input, true);
+        _setUpValueExpressionForImmediate();
+        
+        input.processDecodes(facesContext);
+        
+        assertEquals("processDecodes must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+    }
+    
+    public void testProcessValidatorsRenderedFalse() throws Exception {
+        input = new VerifyNoLifecycleMethodComponent();
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, input, false);
+        
+        input.processValidators(facesContext);
+        
+        assertEquals("processValidators must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+        
+    }
+    
+    public void testProcessValidatorsRenderedTrue() throws Exception {
+        
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, input, true);
+        _setUpValueExpressionForImmediate();
+        
+        input.processValidators(facesContext);
+        
+        assertEquals("processValidators must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+    }
+    
+    
+    public void testProcessUpdatesRenderedFalse() throws Exception {
+        input = new VerifyNoLifecycleMethodComponent();    
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext,input, false);
+        
+        input.processUpdates(facesContext);
+        
+        assertEquals("processValidators must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+        
+    }
+    
+    public void testProcessUpdatesRenderedTrue() throws Exception {
+        
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, input, true);
+        _setUpValueExpressionForImmediate();
+        
+        input.processUpdates(facesContext);
+        
+        assertEquals("processValidators must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+    }
+    
+    public void testVisitTree() throws Exception {
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, input, true);
+        
+        VisitContext visitContext = VisitContext.createVisitContext(facesContext, null, EnumSet.of(VisitHint.SKIP_UNRENDERED));
+        MockVisitCallback mockVisitCallback = new MockVisitCallback();
+        input.visitTree(visitContext, mockVisitCallback);
+        
+        assertEquals("visitTree must not change currentComponent", parent, UIComponent.getCurrentComponent(facesContext));
+    }
+    
+    /** Verifies no call to encode* and process* methods */
+    public class VerifyNoLifecycleMethodComponent extends UIInput
+    {
+        public void decode(FacesContext context) {
+            fail();
+        }
+        public void validate(FacesContext context) {
+            fail();
+        }
+        public void updateModel(FacesContext context) {
+            fail();
+        }
+        public void encodeBegin(FacesContext context) throws IOException {
+            fail();
+        }
+        public void encodeChildren(FacesContext context) throws IOException {
+            fail();
+        }
+        public void encodeEnd(FacesContext context) throws IOException {
+            fail();
+        }
+    }
+    
+    private void _setUpValueExpressionForImmediate() {
+        ValueExpression ve = new MockRenderedValueExpression("#{component.id eq 'testId'}", Boolean.class, input, true);
+        input.setValueExpression("immediate", ve);
+    }
 }

Added: myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/_ComponentUtilsTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/_ComponentUtilsTest.java?rev=1150983&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/_ComponentUtilsTest.java (added)
+++ myfaces/core/branches/2.0.x/api/src/test/java/javax/faces/component/_ComponentUtilsTest.java Tue Jul 26 04:07:49 2011
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package javax.faces.component;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.myfaces.mock.MockRenderedValueExpression;
+import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
+import org.junit.Test;
+
+/**
+ * @author martinkoci
+ */
+public class _ComponentUtilsTest extends AbstractJsfTestCase {
+
+    @Test
+    public void testIsRendered() {
+        UIComponent uiComponent = new UIOutput();
+        boolean rendered = _ComponentUtils.isRendered(facesContext, uiComponent);
+        assertTrue(rendered);
+
+        uiComponent.setRendered(false);
+        rendered = _ComponentUtils.isRendered(facesContext, uiComponent);
+        assertFalse(rendered);
+
+        UIOutput uiOutput = new UIOutput();
+        UIComponent parent = MockRenderedValueExpression.setUpComponentStack(facesContext, uiOutput, false);
+        rendered = _ComponentUtils.isRendered(facesContext, uiComponent);
+        assertFalse(rendered);
+        assertEquals("isRendered must not change current component", parent,
+                UIComponent.getCurrentComponent(facesContext));
+    }
+
+}

Added: myfaces/core/branches/2.0.x/api/src/test/java/org/apache/myfaces/mock/MockRenderedValueExpression.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/api/src/test/java/org/apache/myfaces/mock/MockRenderedValueExpression.java?rev=1150983&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/api/src/test/java/org/apache/myfaces/mock/MockRenderedValueExpression.java (added)
+++ myfaces/core/branches/2.0.x/api/src/test/java/org/apache/myfaces/mock/MockRenderedValueExpression.java Tue Jul 26 04:07:49 2011
@@ -0,0 +1,71 @@
+/*
+ * 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.mock;
+
+import javax.el.ELContext;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIPanel;
+import javax.faces.context.FacesContext;
+
+import junit.framework.Assert;
+
+/**
+ * Verifies the current component on stack in method getValue. Created for MYFACES-3157
+ * 
+ * @author martinkoci
+ */
+public class MockRenderedValueExpression extends org.apache.myfaces.test.el.MockValueExpression {
+
+    private final UIComponent toVerify;
+    
+    private final Object value;
+
+    /**
+     * @param toVerify UIComponent instance verified in getValue 
+     * @param value value returned from getValue()
+     */
+    public MockRenderedValueExpression(String expression, Class<?> expectedType, UIComponent toVerify, Object value) {
+        super(expression, expectedType);
+        this.toVerify = toVerify;
+        this.value = value;
+    }
+    
+    @Override
+    public Object getValue(ELContext elContext) {
+      FacesContext facesContext = (FacesContext) elContext.getContext(FacesContext.class);
+      UIComponent currentComponent = UIComponent.getCurrentComponent(facesContext);
+      Assert.assertEquals("If this ValueExpression is evaluated, component on stack must be actual" , currentComponent , toVerify);
+      return value;
+    }
+
+    /**
+     * Sets up a simple parent/child for testing  MYFACES-3157
+     */
+    public static UIComponent setUpComponentStack(FacesContext facesContext, UIComponent underTest, Object value) {
+        UIPanel parent = new UIPanel();
+        parent.getChildren().add(underTest);
+        
+        MockRenderedValueExpression ve = new MockRenderedValueExpression("#{component.id eq 'testId'}", Boolean.class, underTest, value);
+        underTest.setValueExpression("rendered", ve);
+        
+       // simlulate that parent panel encodes children and is on the stack:
+       parent.pushComponentToEL(facesContext, null);
+       return parent;
+    }
+}