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 2009/09/25 01:42:00 UTC

svn commit: r818662 - in /myfaces/core/trunk/api/src: main/java/javax/faces/component/UIData.java test/java/javax/faces/component/UIDataTest.java

Author: lu4242
Date: Thu Sep 24 23:41:59 2009
New Revision: 818662

URL: http://svn.apache.org/viewvc?rev=818662&view=rev
Log:
MYFACES-2137 JSF 2.0 Component Tree Visiting (Thanks to Jakob Korherr for provide this patch)

Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java
    myfaces/core/trunk/api/src/test/java/javax/faces/component/UIDataTest.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java?rev=818662&r1=818661&r2=818662&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java Thu Sep 24 23:41:59 2009
@@ -30,9 +30,9 @@
 import javax.el.ValueExpression;
 import javax.faces.FacesException;
 import javax.faces.application.FacesMessage;
-import javax.faces.component.UINamingContainer.PropertyKeys;
 import javax.faces.component.visit.VisitCallback;
 import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitResult;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.event.AbortProcessingException;
@@ -1111,11 +1111,128 @@
         return (String) getStateHelper().get(PropertyKeys.var);
     }
 
+    /**
+     * Overrides the behavior in 
+     * UIComponent.visitTree(javax.faces.component.visit.VisitContext, javax.faces.component.visit.VisitCallback)
+     * to handle iteration correctly.
+     * 
+     * @param context the visit context which handles the processing details
+     * @param callback the callback to be performed
+     * @return false if the processing is not done true if we can shortcut
+     * the visiting because we are done with everything
+     * 
+     * @since 2.0
+     */
     @Override
     public boolean visitTree(VisitContext context, VisitCallback callback)
     {
-        // TODO: on MYFACES-2137 Implement traverse over all rows (See javadoc for details)
-        return super.visitTree(context, callback);
+        if (!isVisitable(context))
+        {
+            return false;
+        }
+
+        // save the current row index
+        int oldRowIndex = getRowIndex();
+        // set row index to -1 to process the facets and to get the rowless clientId
+        setRowIndex(-1);
+        // push the Component to EL
+        pushComponentToEL(context.getFacesContext(), this);
+        try
+        {
+            VisitResult visitResult = context.invokeVisitCallback(this,
+                    callback);
+            switch (visitResult)
+            {
+            //we are done nothing has to be processed anymore
+            case COMPLETE:
+                return true;
+
+            case REJECT:
+                return false;
+
+                //accept
+            default:
+                // determine if we need to visit our children 
+                Collection<String> subtreeIdsToVisit = context
+                        .getSubtreeIdsToVisit(this);
+                boolean doVisitChildren = subtreeIdsToVisit != null
+                        && !subtreeIdsToVisit.isEmpty();
+                if (doVisitChildren)
+                {
+                    // visit the facets of the component
+                    for (UIComponent facet : getFacets().values())
+                    {
+                        if (facet.visitTree(context, callback))
+                        {
+                            return true;
+                        }
+                    }
+                    // process the component's children's facets
+                    for (UIComponent child : getChildren())
+                    {
+                        // visit the children's facets
+                        for (UIComponent facet : child.getFacets().values())
+                        {
+                            if (facet.visitTree(context, callback))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                    // visit the columns
+                    for (UIComponent child : getChildren())
+                    {
+                        if (child instanceof UIColumn)
+                        {
+                            if (child.visitTree(context, callback))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                    // iterate over the rows
+                    int rowsToProcess = getRows();
+                    // if getRows() returns 0, all rows have to be processed
+                    if (rowsToProcess == 0)
+                    {
+                        rowsToProcess = getRowCount();
+                    }
+                    int rowIndex = getFirst();
+                    for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
+                    {
+                        setRowIndex(rowIndex);
+                        if (!isRowAvailable())
+                        {
+                            return false;
+                        }
+                        // visit the children of every child of the UIData that is an instance of UIColumn
+                        for (UIComponent child : getChildren())
+                        {
+                            if (child instanceof UIColumn)
+                            {
+                                for (UIComponent grandchild : child
+                                        .getChildren())
+                                {
+                                    if (grandchild.visitTree(context, callback))
+                                    {
+                                        return true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        finally
+        {
+            // pop the component from EL and restore the old row index
+            popComponentFromEL(context.getFacesContext());
+            setRowIndex(oldRowIndex);
+        }
+
+        // Return false to allow the visiting to continue
+        return false;
     }
 
     public void setVar(String var)

Modified: myfaces/core/trunk/api/src/test/java/javax/faces/component/UIDataTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/test/java/javax/faces/component/UIDataTest.java?rev=818662&r1=818661&r2=818662&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/test/java/javax/faces/component/UIDataTest.java (original)
+++ myfaces/core/trunk/api/src/test/java/javax/faces/component/UIDataTest.java Thu Sep 24 23:41:59 2009
@@ -18,14 +18,23 @@
  */
 package javax.faces.component;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.faces.component.html.HtmlPanelGroup;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
+import javax.faces.component.visit.VisitResult;
+import javax.faces.render.Renderer;
+
 import org.apache.myfaces.Assert;
 import org.apache.myfaces.TestRunner;
 import org.apache.shale.test.base.AbstractJsfTestCase;
 import org.easymock.classextension.EasyMock;
 import org.easymock.classextension.IMocksControl;
 
-import javax.faces.render.Renderer;
-
 /**
  * @author Mathias Broekelmann (latest modification by $Author$)
  * @version $Revision$ $Date$
@@ -332,5 +341,56 @@
     {
         // TODO
     }
-
+    
+    /**
+     * Test method for 
+     * {@link javax.faces.component.UIData#visitTree(javax.faces.component.visit.VisitContext, javax.faces.component.visit.VisitCallback)}.
+     */
+    public void testVisitTree() {
+        UIData uidata = new UIData();
+        // value
+        Collection<String> value = new ArrayList<String>();
+        value.add("value#1");
+        value.add("value#2");
+        uidata.setValue(value);
+        // header facet
+        UIComponent headerFacet = new HtmlPanelGroup();
+        uidata.setHeader(headerFacet);
+        // footer facet
+        UIComponent footerFacet = new HtmlPanelGroup();
+        uidata.setFooter(footerFacet);
+        // first child
+        UIComponent child1 = new UIColumn();
+        // facet of first child
+        UIComponent facetOfChild1 = new HtmlPanelGroup();
+        child1.getFacets().put("someFacet", facetOfChild1);
+        // child of first child
+        UIOutput childOfChild1 = new UIOutput();
+        child1.getChildren().add(childOfChild1);
+        uidata.getChildren().add(child1);
+        // second child (should not be processed --> != UIColumn)
+        UIComponent child2 = new HtmlPanelGroup(); 
+        uidata.getChildren().add(child2);
+        VisitCallback callback = null;
+        
+        IMocksControl control = EasyMock.createControl();
+        VisitContext visitContextMock = control.createMock(VisitContext.class);
+        EasyMock.expect(visitContextMock.getFacesContext()).andReturn(facesContext).anyTimes();
+        EasyMock.expect(visitContextMock.getHints()).andReturn(Collections.<VisitHint>emptySet()).anyTimes();
+        Collection<String> subtreeIdsToVisit = new ArrayList<String>();
+        subtreeIdsToVisit.add("1");
+        EasyMock.expect(visitContextMock.getSubtreeIdsToVisit(uidata)).andReturn(subtreeIdsToVisit);
+        EasyMock.expect(visitContextMock.invokeVisitCallback(uidata, callback)).andReturn(VisitResult.ACCEPT);
+        EasyMock.expect(visitContextMock.invokeVisitCallback(headerFacet, callback)).andReturn(VisitResult.ACCEPT);
+        EasyMock.expect(visitContextMock.invokeVisitCallback(footerFacet, callback)).andReturn(VisitResult.ACCEPT);
+        EasyMock.expect(visitContextMock.invokeVisitCallback(facetOfChild1, callback)).andReturn(VisitResult.ACCEPT);
+        EasyMock.expect(visitContextMock.invokeVisitCallback(child1, callback)).andReturn(VisitResult.ACCEPT);
+        EasyMock.expect(visitContextMock.invokeVisitCallback(childOfChild1, callback)).andReturn(VisitResult.ACCEPT).times(3);
+        control.replay();
+        
+        uidata.visitTree(visitContextMock, callback);
+        
+        control.verify();        
+    }
+       
 }