You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ar...@apache.org on 2010/07/17 00:18:43 UTC

svn commit: r964964 [1/2] - in /myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main: java-templates/org/apache/myfaces/trinidad/component/ java-templates/org/apache/myfaces/trinidad/component/core/layout/ java/org/apache/myfaces...

Author: arobinson74
Date: Fri Jul 16 22:18:43 2010
New Revision: 964964

URL: http://svn.apache.org/viewvc?rev=964964&view=rev
Log:
Checkpoint

Added:
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/visit/VisitContextWrapper.java   (with props)
Modified:
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java
    myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -21,25 +21,33 @@ package org.apache.myfaces.trinidad.comp
 import java.io.IOException;
 
 import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 
 import java.util.Map;
 import java.util.Set;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
 import javax.faces.event.PhaseId;
 
 import javax.faces.render.Renderer;
+
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
 import org.apache.myfaces.trinidad.model.CollectionModel;
 import org.apache.myfaces.trinidad.model.LocalRowKeyIndex;
 import org.apache.myfaces.trinidad.model.ModelUtils;
+import org.apache.myfaces.trinidad.render.ClientRowKeyManager;
 
 /**
  * This component iterates over some given data.
  * Each child is repeatedly stamped as many times as necessary.
  * Iteration is done starting at the index given by {@link #getFirst()}
  * for as many indices as specified by {@link #getRows()}.
- * If {@link #getRows()} returns 0, then the iteration continues until 
+ * If {@link #getRows()} returns 0, then the iteration continues until
  * there are no more elements in the underlying data.
  */
 public abstract class UIXIteratorTemplate extends UIXCollection implements FlattenedComponent, LocalRowKeyIndex
@@ -67,29 +75,41 @@ public abstract class UIXIteratorTemplat
     final ComponentProcessor<S> childProcessor,
     final S callbackContext) throws IOException
   {
-    // Mimic what would normally happen in the non-flattening case for encodeBegin():
-    __processFlattenedChildrenBegin();
+    boolean processedChildren;
+
+    setupVisitingContext(context);
 
-    Runner runner = new Runner(cpContext)
+    try
     {
-      @Override
-      protected void process(UIComponent kid, ComponentProcessingContext cpContext) throws IOException
+      // Mimic what would normally happen in the non-flattening case for encodeBegin():
+      __processFlattenedChildrenBegin();
+
+      Runner runner = new IndexedRunner(cpContext)
+      {
+        @Override
+        protected void process(UIComponent kid, ComponentProcessingContext cpContext) throws IOException
+        {
+          childProcessor.processComponent(context, cpContext, kid, callbackContext);
+        }
+      };
+
+      processedChildren = runner.run();
+      Exception exp = runner.getException();
+      if (exp != null)
       {
-        childProcessor.processComponent(context, cpContext, kid, callbackContext);
+        if (exp instanceof RuntimeException)
+          throw (RuntimeException) exp;
+
+        if (exp instanceof IOException)
+          throw (IOException) exp;
+        throw new IllegalStateException(exp);
       }
-    };
-    boolean processedChildren = runner.run();
-    Exception exp = runner.exception;
-    if (exp != null)
-    {
-      if (exp instanceof RuntimeException)
-        throw (RuntimeException) exp;
-
-      if (exp instanceof IOException)
-        throw (IOException) exp;
-      throw new IllegalStateException(exp);
     }
-    
+    finally
+    {
+      tearDownVisitingContext(context);
+    }
+
     return processedChildren;
   }
 
@@ -125,7 +145,7 @@ public abstract class UIXIteratorTemplat
     }
     else // this is not the table. it must be the iterator
     {
-      Runner runner = new Runner()
+      Runner runner = new IndexedRunner()
       {
         @Override
         protected void process(UIComponent kid,
@@ -135,7 +155,7 @@ public abstract class UIXIteratorTemplat
         }
       };
       runner.run();
-      Exception exp = runner.exception;
+      Exception exp = runner.getException();
       if (exp != null)
       {
         if (exp instanceof RuntimeException)
@@ -167,7 +187,7 @@ public abstract class UIXIteratorTemplat
       public Object get(Object key)
       {
         // some of these keys are from <c:forEach>, ie:
-        // javax.servlet.jsp.jstl.core.LoopTagStatus 
+        // javax.servlet.jsp.jstl.core.LoopTagStatus
         if ("begin".equals(key)) // from jstl
         {
           return Integer.valueOf(getFirst());
@@ -188,7 +208,7 @@ public abstract class UIXIteratorTemplat
         }
         return map.get(key);
       }
-    
+
       @Override
       public Set<Map.Entry<String, Object>> entrySet()
       {
@@ -202,7 +222,7 @@ public abstract class UIXIteratorTemplat
     CollectionModel current,
     Object value)
   {
-    CollectionModel model = ModelUtils.toCollectionModel(value); 
+    CollectionModel model = ModelUtils.toCollectionModel(value);
     // initialize to -1. we need to do this incase some application logic
     // changed this index. Also, some JSF1.0 RI classes were initially starting
     // with a rowIndex of 0.
@@ -217,7 +237,7 @@ public abstract class UIXIteratorTemplat
     final FacesContext context,
     final PhaseId phaseId)
   {
-    Runner runner = new Runner()
+    Runner runner = new IndexedRunner()
     {
       @Override
       protected void process(UIComponent kid, ComponentProcessingContext cpContext)
@@ -227,7 +247,140 @@ public abstract class UIXIteratorTemplat
     };
     runner.run();
   }
-  
+
+  // Extract the current row token from the clientId
+  private String _getClientToken(String clientIdPrefix, String cellClientId)
+  {
+    int tokenStartIndex = clientIdPrefix.length() + 1;
+    int tokenEndIndex = cellClientId.indexOf(':', tokenStartIndex);
+
+    if (tokenEndIndex != -1)
+    {
+      return cellClientId.substring(tokenStartIndex, tokenEndIndex);
+    }
+    else
+    {
+      return null;
+    }
+  }
+
+  @Override
+  protected boolean visitData(
+    final VisitContext  visitContext,
+    final VisitCallback visitCallback)
+  {
+    Collection<String> subtreeIds = visitContext.getSubtreeIdsToVisit(this);
+
+    // create a special VisitContext that doesn't visit the Facets
+    // of column components since they aren't visited on each row
+    final VisitContext noColumnFacetContext = new NoColumnFacetsVisitContext(visitContext);
+
+    // runner to use to process the rows
+    Runner runner;
+
+    if (VisitContext.ALL_IDS.equals(subtreeIds))
+    {
+      // we're processing all of the rows, so use the indexed runner (plus, we can't call size() on
+      // the ALL_IDS collection, so we don't have a whole lot of choice here
+      runner = new IndexedRunner()
+      {
+        @Override
+        protected void process(UIComponent kid, ComponentProcessingContext cpContext)
+        {
+          if (kid.getChildCount() > 0)
+          {
+            for (UIComponent grandKid : kid.getChildren())
+            {
+              if (UIXComponent.visitTree(noColumnFacetContext, grandKid, visitCallback))
+              {
+                throw new AbortProcessingException();
+              }
+            }
+          }
+        }
+      };
+    }
+    else
+    {
+      // We are only visiting a subset of the tree, so figure out which rows to visit
+
+      String ourClientIdPrefix = getClientId(visitContext.getFacesContext());
+
+      int subtreeIdCount = subtreeIds.size();
+
+      // build up a set of the row keys to visit rather than iterating
+      // and visiting every row
+      Set<String> rowsToVisit;
+
+      if (subtreeIdCount > 1)
+      {
+        rowsToVisit = new HashSet<String>(subtreeIdCount);
+
+        for (String currClientId : subtreeIds)
+        {
+          String clientToken = _getClientToken(ourClientIdPrefix, currClientId);
+
+          if (clientToken != null)
+          {
+            rowsToVisit.add(clientToken);
+          }
+        }
+      }
+      else
+      {
+        String clientToken = _getClientToken(ourClientIdPrefix,
+                                             subtreeIds.iterator().next());
+
+        if (clientToken != null)
+        {
+          rowsToVisit = Collections.singleton(clientToken);
+        }
+        else
+        {
+          rowsToVisit = Collections.emptySet();
+        }
+      }
+
+      // we didn't visit any data
+      if (rowsToVisit.isEmpty())
+        return false;
+
+      // visit only the rows we need to
+      runner = new KeyedRunner(rowsToVisit)
+      {
+        @Override
+        protected void process(
+          UIComponent                kid,
+          ComponentProcessingContext cpContext
+          ) throws IOException
+        {
+          if (kid.getChildCount() > 0)
+          {
+            for (UIComponent grandKid : kid.getChildren())
+            {
+              if (UIXComponent.visitTree(noColumnFacetContext, grandKid, visitCallback))
+              {
+                throw new AbortProcessingException();
+              }
+            }
+          }
+        }
+      };
+    }
+
+    try
+    {
+      runner.run();
+    }
+    finally
+    {
+      return (runner.getException() instanceof AbortProcessingException);
+    }
+  }
+
+  /**
+   * Abstract class for processing rows
+   */
   private abstract class Runner implements ComponentProcessor<Object>
   {
     public Runner()
@@ -239,11 +392,81 @@ public abstract class UIXIteratorTemplat
     {
       _cpContext = cpContext;
     }
-    
+
+    public abstract boolean run();
+
+    /**
+     * Sets up the context for the child and processes it
+     */
+    public void processComponent(
+      FacesContext context,
+      ComponentProcessingContext cpContext,
+      UIComponent component,
+      Object callbackContext) throws IOException
+    {
+      try
+      {
+        process(component, cpContext);
+      }
+      catch (IOException ioe)
+      {
+        throw ioe;
+      }
+      catch (AbortProcessingException ape)
+      {
+        // we're done, so abort
+        _exception = ape;
+        throw ape;
+      }
+      catch (Exception e)
+      {
+        _exception = e;
+      }
+    }
+
+    public Exception getException()
+    {
+      return _exception;
+    }
+
+    protected abstract void process(UIComponent comp, ComponentProcessingContext cpContext)
+      throws Exception;
+
+    protected final ComponentProcessingContext getComponentProcessingContext()
+    {
+      return _cpContext;
+    }
+
+    public final void setException(Exception e)
+    {
+      _exception = e;
+    }
+
+    private Exception _exception = null;
+
+    private final ComponentProcessingContext _cpContext;
+  }
+
+  /**
+   * Class for visiting getRows() by index rows starting getFirst()
+   */
+  private abstract class IndexedRunner extends Runner
+  {
+    public IndexedRunner()
+    {
+      this(null);
+    }
+
+    public IndexedRunner(ComponentProcessingContext cpContext)
+    {
+      super(cpContext);
+    }
+
     public final boolean run()
     {
       FacesContext context = FacesContext.getCurrentInstance();
-      
+      ComponentProcessingContext cpContext = getComponentProcessingContext();
+
       List<UIComponent> stamps = getStamps();
       int oldIndex = getRowIndex();
       int first = getFirst();
@@ -251,9 +474,9 @@ public abstract class UIXIteratorTemplat
       int end = (rows <= 0) //show everything
         ? Integer.MAX_VALUE
         : first + rows;
-      
+
       boolean processedChild = false;
-      
+
       try
       {
         for(int i=first; i<end; i++)
@@ -262,8 +485,8 @@ public abstract class UIXIteratorTemplat
           if (isRowAvailable())
           {
             // latch processedChild the first time we process a child
-            processedChild |= (_cpContext != null)
-              ? UIXComponent.processFlattenedChildren(context, _cpContext, this, stamps, null)
+            processedChild |= (cpContext != null)
+              ? UIXComponent.processFlattenedChildren(context, cpContext, this, stamps, null)
               : UIXComponent.processFlattenedChildren(context, this, stamps, null);
           }
           else
@@ -272,45 +495,70 @@ public abstract class UIXIteratorTemplat
       }
       catch (IOException e)
       {
-        exception = e;
+        setException(e);
       }
       finally
       {
         setRowIndex(oldIndex);
       }
-      
+
       return processedChild;
     }
+  }
 
-    /**
-     * Sets up the context for the child and processes it
-     */
-    public void processComponent(
-      FacesContext context,
-      ComponentProcessingContext cpContext,
-      UIComponent component,
-      Object callbackContext) throws IOException
+  /**
+   * Runner that visits the rows specified by the client row key tokens
+   */
+  private abstract class KeyedRunner extends Runner
+  {
+    public KeyedRunner(Iterable<String> clientKeys)
+    {
+      super();
+      _clientKeys = clientKeys;
+    }
+
+    public final boolean run()
     {
+      FacesContext context = FacesContext.getCurrentInstance();
+
+      List<UIComponent> stamps = getStamps();
+      int oldIndex = getRowIndex();
+
+      boolean processedChild = false;
+
       try
       {
-        process(component, cpContext);
+        // need to convert row key tokens to row keys
+        ClientRowKeyManager rowKeyManager = getClientRowKeyManager();
+
+        for(String clientKey : _clientKeys)
+        {
+          Object rowKey = rowKeyManager.getRowKey(context, UIXIterator.this, clientKey);
+
+          if (rowKey != null)
+          {
+            setRowKey(rowKey);
+            if (isRowAvailable())
+            {
+              // latch processedChild the first time we process a child
+              processedChild |= UIXComponent.processFlattenedChildren(context, this, stamps, null);
+            }
+          }
+        }
       }
-      catch (IOException ioe)
+      catch (IOException e)
       {
-        throw ioe;
+        setException(e);
       }
-      catch (Exception e)
+      finally
       {
-        exception = e;
+        setRowIndex(oldIndex);
       }
-    }
 
-    protected abstract void process(UIComponent comp, ComponentProcessingContext cpContext)
-      throws Exception;
-
-    public Exception exception = null;
+      return processedChild;
+    }
 
-    private final ComponentProcessingContext _cpContext;
+    private final Iterable<String> _clientKeys;
   }
 
   @Override
@@ -355,7 +603,7 @@ public abstract class UIXIteratorTemplat
           first = 0;
         else
         {
-          // scroll to the last page: 
+          // scroll to the last page:
           first = size - rows;
           model.setRowIndex(first);
           // make sure the row is indeed available:
@@ -375,5 +623,4 @@ public abstract class UIXIteratorTemplat
       model.setRowIndex(oldIndex);
     }
   }
-
 }

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -18,16 +18,21 @@
  */
 package org.apache.myfaces.trinidad.component;
 
+import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;
 
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+
 
 /**
  * Base class for the NavigationLevel component.
  *
  * @version $Name:  $ ($Revision$) $Date$
  */
-abstract public class UIXNavigationLevelTemplate extends UIXNavigationHierarchy
+abstract public class UIXNavigationLevelTemplate
+  extends UIXNavigationHierarchy
 {
 /**/ // Abstract methods implemented by code gen
 /**/  abstract public int getLevel();
@@ -48,8 +53,52 @@ abstract public class UIXNavigationLevel
     TableUtils.__processChildren(context, this, phaseId);
   }
 
+  @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    boolean done = visitData(visitContext, callback);
 
+    if (!done)
+    {
+      // process the children
+      int childCount = getChildCount();
+      if (childCount > 0)
+      {
+        for (UIComponent child : getChildren())
+        {
+          done = UIXComponent.visitTree(visitContext, child, callback);
+
+          if (done)
+            break;
+        }
+      }
+    }
 
+    return done;
+  }
 
+  @Override
+  protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    Object oldKey = getRowKey();
+
+    boolean done;
+
+    HierarchyUtils.__setStartDepthPath(this, getLevel());
+
+    try
+    {
+      done = visitLevel(visitContext, callback, getStamps());
+    }
+    finally
+    {
+      setRowKey(oldKey);
+    }
 
+    return done;
+  }
 }

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -25,33 +25,36 @@ import javax.faces.component.UIComponent
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;
 
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+
 
 /**
  * Base class for the NavigationPath component.
  *
  * @version $Name:  $ ($Revision$) $Date$
  */
-abstract public class UIXNavigationPathTemplate extends UIXNavigationHierarchy
+abstract public class UIXNavigationPathTemplate
+  extends UIXNavigationHierarchy
 {
-	
   @Override
   protected void processFacetsAndChildren(
     FacesContext context,
-    PhaseId phaseId)
+    PhaseId      phaseId)
   {
     Object oldPath = getRowKey();
-    
+
     Object focusPath = getFocusRowKey();
-    
+
     if (focusPath != null )
     {
-      List<Object> paths = 
+      List<Object> paths =
         new ArrayList<Object>(getAllAncestorContainerRowKeys(focusPath));
-      
+
       paths.add(focusPath);
       int focusPathSize = paths.size();
       UIComponent nodeStamp = getFacet("nodeStamp");
-      
+
       if (nodeStamp != null)
       {
         for (int i = 0; i < focusPathSize; i++)
@@ -61,12 +64,84 @@ abstract public class UIXNavigationPathT
         }
       }
     }
-    
+
     setRowKey(oldPath);
-    
+
     // process the children
     TableUtils.__processChildren(context, this, phaseId);
-  }  
+  }
+
+
+  @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    boolean done = visitData(visitContext, callback);
+
+    if (!done)
+    {
+      // process the children
+      int childCount = getChildCount();
+      if (childCount > 0)
+      {
+        for (UIComponent child : getChildren())
+        {
+          done = UIXComponent.visitTree(visitContext, child, callback);
+
+          if (done)
+            break;
+        }
+      }
+    }
+
+    return done;
+  }
+
+  @Override
+  protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    Object focusPath = getFocusRowKey();
+    Object oldRowKey = null;
+
+    boolean done = false;
+
+    // start from the focused area
+    if (focusPath != null)
+    {
+      List<UIComponent> stamps = getStamps();
+
+      if (!stamps.isEmpty())
+      {
+        List<Object> paths =  new ArrayList<Object>(getAllAncestorContainerRowKeys(focusPath));
+        paths.add(focusPath);
+
+        int focusPathSize = paths.size();
+
+        try
+        {
+          for (int i = 0; i < focusPathSize && !done; i++)
+          {
+            setRowKey(paths.get(i));
+
+            for (UIComponent stamp : stamps)
+            {
+              done = UIXComponent.visitTree(visitContext, stamp, callback);
+
+              if (done)
+                break;
+            }
+          }
+        }
+        finally
+        {
+          setRowKey(oldRowKey);
+        }
+      }
+    }
 
-    
+    return done;
+  }
 }

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java Fri Jul 16 22:18:43 2010
@@ -29,6 +29,9 @@ import javax.faces.event.PhaseId;
 
 import org.apache.myfaces.trinidad.bean.FacesBean;
 import org.apache.myfaces.trinidad.bean.PropertyKey;
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitHint;
 import org.apache.myfaces.trinidad.model.CollectionModel;
 import org.apache.myfaces.trinidad.model.RowKeySet;
 import org.apache.myfaces.trinidad.model.RowKeySetTreeImpl;
@@ -103,6 +106,43 @@ abstract public class UIXNavigationTreeT
   }
 
   @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    return visitData(visitContext, callback);
+  }
+
+  @Override
+  protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    Object oldRowKey = getRowKey();
+
+    // if we are only visiting rendered stamps, then pass in the disclosed row keys, otherwise
+    // pass in null, indicating that all row keys should be visited
+    RowKeySet disclosedRowKeys = (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
+                                   ? getDisclosedRowKeys()
+                                   : null;
+
+    boolean done;
+
+    HierarchyUtils.__setStartDepthPath(this, getStartLevel());
+
+    try
+    {
+      done = visitHierarchy(visitContext, callback, getStamps(), disclosedRowKeys);
+    }
+    finally
+    {
+      setRowKey(oldRowKey);
+    }
+
+    return done;
+  }
+
+  @Override
   void __encodeBegin(FacesContext context) throws IOException
   {
     HierarchyUtils.__handleEncodeBegin(this, getDisclosedRowKeys());

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java Fri Jul 16 22:18:43 2010
@@ -32,6 +32,9 @@ import javax.faces.event.PhaseId;
 
 import org.apache.myfaces.trinidad.bean.FacesBean;
 import org.apache.myfaces.trinidad.bean.PropertyKey;
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitHint;
 import org.apache.myfaces.trinidad.model.CollectionModel;
 import org.apache.myfaces.trinidad.model.RowKeySet;
 import org.apache.myfaces.trinidad.model.RowKeySetTreeImpl;
@@ -49,6 +52,7 @@ abstract public class UIXPageTemplate ex
 /**/  public abstract void setDisclosedRowKeys(RowKeySet state);
 /**/  public abstract MethodBinding getRowDisclosureListener();
 /**/  static public final PropertyKey DISCLOSED_ROW_KEYS_KEY = null;
+/**/  public abstract UIComponent getNodeStamp();
 
   /**
    * Sets the phaseID of UI events depending on the "immediate" property.
@@ -119,6 +123,89 @@ abstract public class UIXPageTemplate ex
   }
 
   @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    boolean done = visitData(visitContext, callback);
+
+    if (!done)
+    {
+      // process the children
+      int childCount = getChildCount();
+      if (childCount > 0)
+      {
+        for (UIComponent child : getChildren())
+        {
+          done = UIXComponent.visitTree(visitContext, child, callback);
+
+          if (done)
+            break;
+        }
+      }
+
+      // process the non-stamp facet children
+      if (!done)
+      {
+        // Visit the facets except for the node stamp
+        int facetCount = getFacetCount();
+
+        if (facetCount > 0)
+        {
+          UIComponent nodeStamp = getNodeStamp();
+
+          // if our only facet is the node stamp, we don't need to do this
+          if ((facetCount > 1) || (nodeStamp == null))
+          {
+            for (UIComponent facet : getFacets().values())
+            {
+              // ignore the nodeStamp facet, since it is stamped
+              if (facet != nodeStamp)
+              {
+                if (UIXComponent.visitTree(visitContext, facet, callback))
+                {
+                  done = true;
+                  break;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    return done;
+  }
+
+  @Override
+  protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    Object oldPath = getRowKey();
+
+    // if we are only visiting rendered stamps, then pass in the disclosed row keys, otherwise
+    // pass in null, indicating that all row keys should be visited
+    RowKeySet disclosedRowKeys = (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
+                                   ? getDisclosedRowKeys()
+                                   : null;
+
+    setRowKey(null);
+
+    boolean done;
+
+    try
+    {
+      done = visitHierarchy(visitContext, callback, getStamps(), disclosedRowKeys);
+    }
+    finally
+    {
+      setRowKey(oldPath);
+    }
+
+    return done;
+  }
+  @Override
   void __encodeBegin(FacesContext context) throws IOException
   {
     HierarchyUtils.__handleEncodeBegin(this, getDisclosedRowKeys());

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -18,35 +18,86 @@
  */
 package org.apache.myfaces.trinidad.component;
 
+import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;
 
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+
 
 /**
  * Base class for the Process component, which shows the steps of a process.
  *
  * @version $Name:  $ ($Revision$) $Date$
  */
-abstract public class UIXProcessTemplate extends UIXMenuHierarchy
+abstract public class UIXProcessTemplate
+  extends UIXMenuHierarchy
 {
-  
   @Override
   protected void processFacetsAndChildren(
     FacesContext context,
     PhaseId phaseId)
   {
     Object oldPath = getRowKey();
-    Object focusPath = getFocusRowKey();    
-    setRowKey(focusPath);      
-    // process stamp for one level 
-    HierarchyUtils.__processLevel(context, phaseId, this);        
-    setRowKey(oldPath);    
-    
+    Object focusPath = getFocusRowKey();
+    setRowKey(focusPath);
+    // process stamp for one level
+    HierarchyUtils.__processLevel(context, phaseId, this);
+    setRowKey(oldPath);
+
     // process the children
     TableUtils.__processChildren(context, this, phaseId);
-    
-  }  
 
-  
-  
+  }
+
+  @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    boolean done = visitData(visitContext, callback);
+
+    if (!done)
+    {
+      // process the children
+      int childCount = getChildCount();
+      if (childCount > 0)
+      {
+        for (UIComponent child : getChildren())
+        {
+          done = UIXComponent.visitTree(visitContext, child, callback);
+
+          if (done)
+            break;
+        }
+      }
+    }
+
+    return done;
+  }
+
+  @Override
+  protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    Object oldKey = getRowKey();
+
+    Object focusPath = getFocusRowKey();
+    setRowKey(focusPath);
+
+    boolean done;
+
+    try
+    {
+      done = visitLevel(visitContext, callback, getStamps());
+    }
+    finally
+    {
+      setRowKey(oldKey);
+    }
+
+    return done;
+  }
 }

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -25,6 +25,9 @@ import javax.faces.event.AbortProcessing
 import javax.faces.event.FacesEvent;
 import javax.faces.event.PhaseId;
 
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitHint;
 import org.apache.myfaces.trinidad.event.DisclosureEvent;
 
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
@@ -85,12 +88,12 @@ abstract public class UIXShowDetailTempl
     {
       // Do not update the disclosed if "transient"
       if (!isDisclosedTransient())
-      {      
+      {
         // Expand or collapse this showDetail
         boolean isDisclosed = ((DisclosureEvent) event).isExpanded();
-        // If the component is already in that disclosure state, we 
+        // If the component is already in that disclosure state, we
         // have a renderer bug.  Either it delivered an unnecessary event,
-        // or even worse it set disclosed on its own instead of waiting 
+        // or even worse it set disclosed on its own instead of waiting
         // for the disclosure event to do that, which will lead to lifecycle
         // problems.  So in either case, warn the developer.
         if (isDisclosed == isDisclosed())
@@ -101,12 +104,12 @@ abstract public class UIXShowDetailTempl
         {
           setDisclosed(isDisclosed);
         }
-  
+
         //pu: Implicitly record a Change for 'disclosed' attribute
         addAttributeChange("disclosed",
                            isDisclosed ? Boolean.TRUE : Boolean.FALSE);
       }
-      
+
       if (isImmediate())
         getFacesContext().renderResponse();
 
@@ -133,5 +136,16 @@ abstract public class UIXShowDetailTempl
     super.queueEvent(e);
   }
 
+  @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    return
+      (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED) == false ||
+        this.isDisclosed()) &&
+      super.visitChildren(visitContext, callback);
+  }
+
   static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(UIXShowDetail.class);
 }

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -19,22 +19,27 @@
 package org.apache.myfaces.trinidad.component;
 
 import java.io.IOException;
-import java.util.List;
 
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.event.FacesEvent;
 import javax.faces.event.PhaseId;
 
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitContextWrapper;
+import org.apache.myfaces.trinidad.component.visit.VisitHint;
+import org.apache.myfaces.trinidad.component.visit.VisitResult;
 import org.apache.myfaces.trinidad.event.DisclosureEvent;
 
+
 /**
  * Base class for ShowOne component.
  * @version $Name:  $ ($Revision$) $Date$
  */
-abstract public class UIXShowOneTemplate extends UIXComponentBase
+abstract public class UIXShowOneTemplate
+  extends UIXComponentBase
 {
-	
   @Override
   @SuppressWarnings("unchecked")
   public void queueEvent(FacesEvent e)
@@ -85,6 +90,26 @@ abstract public class UIXShowOneTemplate
     super.queueEvent(e);
   }
 
+  @Override
+  public boolean visitTree(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    if (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
+    {
+      // Filter which children to be visited so that only one show detail
+      // is visited for this show one component
+      visitContext = new PartialVisitContext(visitContext);
+    }
+    return super.visitTree(visitContext, callback);
+  }
+
+  protected boolean isChildSelected(
+    UIXShowDetail component)
+  {
+    return component.isDisclosed();
+  }
+
   /**
    * State passed to the UndisclosureCallback.
    */
@@ -145,5 +170,70 @@ abstract public class UIXShowOneTemplate
     }
   }
 
+  private class PartialVisitContext
+    extends VisitContextWrapper
+  {
+    PartialVisitContext(VisitContext wrapped)
+    {
+      _wrapped = wrapped;
+    }
+
+    public VisitContext getWrapped()
+    {
+      return _wrapped;
+    }
+
+    @Override
+    public VisitResult invokeVisitCallback(
+      UIComponent   component,
+      VisitCallback visitCallback)
+    {
+      if (component instanceof UIXShowDetail)
+      {
+        UIXShowDetail showDetail = (UIXShowDetail)component;
+        if (_isShowDetailForCurrentComponent(showDetail))
+        {
+          if (_foundItemToRender || !isChildSelected(showDetail))
+          {
+            // We already visited the one to be shown
+            return VisitResult.REJECT;
+          }
+          else
+          {
+            _foundItemToRender = true;
+          }
+        }
+      }
+
+      return super.invokeVisitCallback(component, visitCallback);
+    }
+
+    private boolean _isShowDetailForCurrentComponent(
+      UIXShowDetail showDetail)
+    {
+      for (UIComponent parent = showDetail.getParent(); parent != null; parent = parent.getParent())
+      {
+        if (parent == UIXShowOne.this)
+        {
+          return true;
+        }
+
+        if (parent instanceof FlattenedComponent &&
+          ((FlattenedComponent)parent).isFlatteningChildren(getFacesContext()))
+        {
+          continue;
+        }
+
+        // The first-non flattened component is not the show one, do not filter it
+        return false;
+      }
+
+      return false;
+    }
+
+    private boolean      _foundItemToRender;
+    private VisitContext _wrapped;
+  }
+
   private final UndisclosureCallback _undisclosureCallback = new UndisclosureCallback();
 }

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -23,6 +23,10 @@ import java.io.IOException;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitHint;
+
 
 /**
  * Base class for the switcher componnet.
@@ -57,7 +61,6 @@ abstract public class UIXSwitcherTemplat
       facet.processValidators(context);
   }
 
-
   /**
    * Only process updates on the currently active facet.
    */
@@ -79,7 +82,7 @@ abstract public class UIXSwitcherTemplat
     final S callbackContext) throws IOException
   {
     UIComponent facet = _getFacet();
-    
+
     if (facet != null)
       return UIXComponent.processFlattenedChildren(context,
                                                    cpContext,
@@ -112,7 +115,6 @@ abstract public class UIXSwitcherTemplat
       __encodeRecursive(context, facet);
   }
 
-
   /**
    * Override to return true.
    */
@@ -122,6 +124,26 @@ abstract public class UIXSwitcherTemplat
     return true;
   }
 
+  @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    if (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
+    {
+      UIComponent facet = _getFacet();
+      if (facet != null)
+      {
+        return UIXComponent.visitTree(visitContext, facet, callback);
+      }
+      return false;
+    }
+    else
+    {
+      return super.visitChildren(visitContext, callback);
+    }
+  }
+
   private UIComponent _getFacet()
   {
     if (!isRendered())
@@ -141,7 +163,6 @@ abstract public class UIXSwitcherTemplat
 
     return null;
   }
-
 }
 
 

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java Fri Jul 16 22:18:43 2010
@@ -6,9 +6,9 @@
  *  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
@@ -36,6 +36,8 @@ import javax.faces.event.AbortProcessing
 import javax.faces.event.FacesEvent;
 import javax.faces.event.PhaseId;
 
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
 import org.apache.myfaces.trinidad.event.FocusEvent;
 import org.apache.myfaces.trinidad.event.RangeChangeEvent;
 import org.apache.myfaces.trinidad.event.RangeChangeListener;
@@ -59,9 +61,9 @@ abstract public class UIXTreeTableTempla
   public void decode(FacesContext context)
   {
     _resetContainerClientIdCache();
-    super.decode(context);    
+    super.decode(context);
   }
-  
+
   /**
    * Override to update the container client id cache before validations
    */
@@ -71,16 +73,16 @@ abstract public class UIXTreeTableTempla
     _resetContainerClientIdCache();
     super.processValidators(context);
   }
-  
+
   /**
    * Override to update the container client id cache before updates
-   */  
+   */
   @Override
   public void processUpdates(FacesContext context)
   {
     _resetContainerClientIdCache();
     super.processUpdates(context);
-  }  
+  }
 
   /**
    * Override to update the container client id cache before encode
@@ -101,7 +103,7 @@ abstract public class UIXTreeTableTempla
   {
     String id;
     if (_containerClientIdCache == null || _isStampedChild(child))
-    {   
+    {
       // call the UIXCollection getContainerClientId, which attaches currency string to the client id
       id = getContainerClientId(context);
     }
@@ -358,14 +360,14 @@ abstract public class UIXTreeTableTempla
                                          phaseId,
                                          this,
                                          state,
-                                         true);        
+                                         true);
 
       }
       else
       {
         TableUtils.__processStampedChildren(context, this, phaseId);
         processComponent(context, nodeStamp, phaseId); // bug 4688568
-  
+
         if (state.isContained())
         {
           enterContainer();
@@ -383,6 +385,81 @@ abstract public class UIXTreeTableTempla
     }
   }
 
+
+  @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    // need to override to do the default since our superclass
+    // UIXTree does stuff here we don't want
+    return defaultVisitChildren(visitContext, callback);
+  }
+
+  @Override
+  protected boolean visitUnstampedFacets(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    // Visit the facets except for the node stamp
+    int facetCount = getFacetCount();
+
+    if (facetCount > 0)
+    {
+      UIComponent nodeStamp = getNodeStamp();
+
+      // if our only facet is the node stamp, we don't need to do this
+      if ((facetCount > 1) || (nodeStamp == null))
+      {
+        for (UIComponent facet : getFacets().values())
+        {
+          // ignore the nodeStamp facet, since it is stamped
+          if (facet != nodeStamp)
+          {
+            if (UIXComponent.visitTree(visitContext, facet, callback))
+            {
+              return true;
+            }
+          }
+        }
+      }
+    }
+
+    return false;
+  }
+
+  @Override
+  protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    Object focusedPath = getFocusRowKey();
+    Object oldRowKey = null;
+
+    // start from the focused area
+    if (focusedPath != null)
+    {
+      oldRowKey = getRowKey();
+      setRowKey(focusedPath);
+    }
+
+    boolean done;
+
+    try
+    {
+      done = super.visitData(new NoColumnFacetsVisitContext(visitContext), callback);
+    }
+    finally
+    {
+      if (focusedPath != null)
+      {
+        setRowKey(oldRowKey);
+      }
+    }
+
+    return done;
+  }
+
   /**
    * Gets the path of the parent
    */
@@ -422,7 +499,7 @@ abstract public class UIXTreeTableTempla
       // cache nodeStamp header/footer items
       TableUtils.cacheHeaderFooterFacets(nodeStamp, _containerClientIdCache);
       // cache any nested columns in nodeStamp facet
-      TableUtils.cacheColumnHeaderFooterFacets(nodeStamp, _containerClientIdCache);      
+      TableUtils.cacheColumnHeaderFooterFacets(nodeStamp, _containerClientIdCache);
     }
   }
 
@@ -438,7 +515,7 @@ abstract public class UIXTreeTableTempla
 
     return state;
   }
-  
+
   /**
    * Sets the internal state of this component.
    * @param stampState the internal state is obtained from this object.

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java Fri Jul 16 22:18:43 2010
@@ -31,6 +31,9 @@ import javax.faces.event.PhaseId;
 
 import org.apache.myfaces.trinidad.bean.FacesBean;
 import org.apache.myfaces.trinidad.bean.PropertyKey;
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitHint;
 import org.apache.myfaces.trinidad.event.RowDisclosureEvent;
 import org.apache.myfaces.trinidad.event.SelectionEvent;
 import org.apache.myfaces.trinidad.model.CollectionModel;
@@ -149,6 +152,29 @@ abstract public class UIXTreeTemplate ex
   }
 
   @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    return visitData(visitContext, callback);
+  }
+
+  @Override
+  protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    // if we are only visiting rendered stamps, then pass in the disclosed row keys, otherwise
+    // pass in null, indicating that all row keys should be visited
+    RowKeySet disclosedRowKeys = (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
+                                   ? getDisclosedRowKeys()
+                                   : null;
+
+    return visitHierarchy(visitContext, callback, getStamps(), disclosedRowKeys);
+  }
+
+
+  @Override
   void __init()
   {
     super.__init();
@@ -158,7 +184,6 @@ abstract public class UIXTreeTemplate ex
       setSelectedRowKeys(new RowKeySetTreeImpl());
   }
 
-
   /**
    * Gets the internal state of this component.
    */

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java Fri Jul 16 22:18:43 2010
@@ -18,20 +18,29 @@
  */
 package org.apache.myfaces.trinidad.component.core.layout;
 
+import java.util.List;
+
 import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.el.MethodBinding;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.FacesEvent;
-import javax.faces.event.PhaseId;
-import java.util.List;
 
-import org.apache.myfaces.trinidad.event.DisclosureEvent;
+import org.apache.myfaces.trinidad.component.FlattenedComponent;
+import org.apache.myfaces.trinidad.component.UIXPanel;
 import org.apache.myfaces.trinidad.component.UIXShowDetail;
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitContextWrapper;
+import org.apache.myfaces.trinidad.component.visit.VisitHint;
+import org.apache.myfaces.trinidad.component.visit.VisitResult;
+import org.apache.myfaces.trinidad.event.DisclosureEvent;
+
 
-abstract public class CorePanelAccordion extends UIXPanel
+abstract public class CorePanelAccordionTemplate
+  extends UIXPanel
 {
-    /**
+/**/ public abstract boolean isDiscloseMany();
+
+  /**
    * Queues an event recursively to the root component.
    * @param event
    * @throws javax.faces.event.AbortProcessingException
@@ -67,4 +76,91 @@ abstract public class CorePanelAccordion
     super.queueEvent(event);
   }
 
+  protected boolean isChildSelected(
+    UIXShowDetail component)
+  {
+    return component.isDisclosed();
+  }
+
+  @Override
+  public boolean visitTree(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    if (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED) &&
+     !isDiscloseMany())
+    {
+      // Filter which children to be visited so that only one show detail
+      // is visited for this accordion
+      visitContext = new PartialVisitContext(visitContext);
+    }
+    return super.visitTree(visitContext, callback);
+  }
+
+  private class PartialVisitContext
+    extends VisitContextWrapper
+  {
+    PartialVisitContext(
+      VisitContext wrapped)
+    {
+      _wrapped = wrapped;
+    }
+
+    public VisitContext getWrapped()
+    {
+      return _wrapped;
+    }
+
+    @Override
+    public VisitResult invokeVisitCallback(
+      UIComponent   component,
+      VisitCallback visitCallback)
+    {
+      if (component instanceof UIXShowDetail)
+      {
+        UIXShowDetail showDetail = (UIXShowDetail)component;
+        if (_isShowDetailForCurrentComponent(showDetail))
+        {
+          if (_foundItemToRender || !isChildSelected(showDetail))
+          {
+            // We already visited the one to be shown
+            return VisitResult.REJECT;
+          }
+          else
+          {
+            _foundItemToRender = true;
+          }
+        }
+      }
+
+      return super.invokeVisitCallback(component, visitCallback);
+    }
+
+    private boolean _isShowDetailForCurrentComponent(
+      UIXShowDetail showDetail)
+    {
+      for (UIComponent parent = showDetail.getParent(); parent != null;
+           parent = parent.getParent())
+      {
+        if (parent == CorePanelAccordion.this)
+        {
+          return true;
+        }
+
+        if (parent instanceof FlattenedComponent &&
+          ((FlattenedComponent)parent).isFlatteningChildren(getFacesContext()))
+        {
+          continue;
+        }
+
+        // The first-non flattened component is not the show one, do not filter it
+        return false;
+      }
+
+      return false;
+    }
+
+    private boolean      _foundItemToRender;
+    private VisitContext _wrapped;
+  }
 }
\ No newline at end of file

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java Fri Jul 16 22:18:43 2010
@@ -40,6 +40,10 @@ import javax.faces.render.Renderer;
 
 import org.apache.myfaces.trinidad.bean.FacesBean;
 import org.apache.myfaces.trinidad.bean.PropertyKey;
+import org.apache.myfaces.trinidad.component.visit.VisitCallback;
+import org.apache.myfaces.trinidad.component.visit.VisitContext;
+import org.apache.myfaces.trinidad.component.visit.VisitContextWrapper;
+import org.apache.myfaces.trinidad.component.visit.VisitResult;
 import org.apache.myfaces.trinidad.event.SelectionEvent;
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.model.CollectionModel;
@@ -1092,6 +1096,240 @@ public abstract class UIXCollection exte
   }
 
   /**
+   * <p>
+   * Override default children visiting code to visit the facets and facets of the columns
+   * before delegating to the <code>visitData</code> to visit the individual rows of data.
+   * </p><p>
+   * Subclasses should override this method if they wish to change the way in which the non-stamped
+   * children are visited.  If they wish to change the wash the the stamped children are visited,
+   * they should override <code>visitData</code> instead.
+   * </p>
+   * @param visitContext
+   * @param callback
+   * @return <code>true</code> if all of the children to visit have been visited
+   * @see #visitData
+   */
+  @Override
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    return defaultVisitChildren(visitContext, callback);
+  }
+
+  protected final boolean defaultVisitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    boolean doneVisiting;
+
+    // Clear out the row index if one is set so that
+    // we start from a clean slate.
+    int oldRowIndex = getRowIndex();
+    setRowIndex(-1);
+
+    try
+    {
+      // visit the unstamped children
+      doneVisiting = visitUnstampedFacets(visitContext, callback);
+
+      if (!doneVisiting)
+      {
+        doneVisiting = _visitStampedColumnFacets(visitContext, callback);
+
+        // visit the stamped children
+        if (!doneVisiting)
+        {
+          doneVisiting = visitData(visitContext, callback);
+        }
+      }
+    }
+    finally
+    {
+      // restore the original rowIndex
+      setRowIndex(oldRowIndex);
+    }
+
+    return doneVisiting;
+  }
+
+  /**
+   * Hook method for subclasses to override to change the behavior
+   * of how unstamped facets of the UIXCollection are visited.  The
+   * Default implementation visits all of the facets of the
+   * UIXCollection.
+   */
+  protected boolean visitUnstampedFacets(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    // Visit the facets with no row
+    if (getFacetCount() > 0)
+    {
+      for (UIComponent facet : getFacets().values())
+      {
+        if (UIXComponent.visitTree(visitContext, facet, callback))
+        {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+
+  /**
+   * VistiContext that visits the facets of the UIXColumn children, including
+   * nested UIXColumn childrem
+   */
+  private static class ColumnFacetsOnlyVisitContext
+    extends VisitContextWrapper
+  {
+    public ColumnFacetsOnlyVisitContext(VisitContext wrappedContext)
+    {
+      _wrapped = wrappedContext;
+    }
+
+    @Override
+    public VisitContext getWrapped()
+    {
+      return _wrapped;
+    }
+
+    @Override
+    public VisitResult invokeVisitCallback(
+      UIComponent   component,
+      VisitCallback callback)
+    {
+      if (component instanceof UIXColumn)
+      {
+        if (component.getFacetCount() > 0)
+        {
+          // visit the facet children without filtering for just UIXColumn children
+          for (UIComponent facetChild : component.getFacets().values())
+          {
+            if (UIXComponent.visitTree(getWrapped(), facetChild, callback))
+              return VisitResult.COMPLETE;
+          }
+
+          // visit the indexed children, recursively looking for more columns
+          for (UIComponent child : component.getChildren())
+          {
+            if (UIXComponent.visitTree(this, child, callback))
+              return VisitResult.COMPLETE;
+          }
+        }
+      }
+
+      // at this point, we either have already manually processed the UIXColumn's children, or
+      // the component wasn't a UIXColumn and shouldn't be processed
+      return VisitResult.REJECT;
+    }
+
+    private final VisitContext _wrapped;
+  }
+
+  /**
+   * VisitContext implementation that doesn't visit any of the Facets of
+   * UIXColumn children.  This is used when stamping children
+   */
+  protected static final class NoColumnFacetsVisitContext extends VisitContextWrapper
+  {
+    NoColumnFacetsVisitContext(VisitContext wrapped)
+    {
+      _wrapped = wrapped;
+    }
+
+    @Override
+    public VisitContext getWrapped()
+    {
+      return _wrapped;
+    }
+
+    @Override
+    public VisitResult invokeVisitCallback(UIComponent component, VisitCallback callback)
+    {
+      if (component instanceof UIXColumn)
+      {
+        if (component.getChildCount() > 0)
+        {
+          // visit only the indexed children of the columns
+          for (UIComponent child : component.getChildren())
+          {
+            if (UIXComponent.visitTree(this, child, callback))
+              return VisitResult.COMPLETE;
+          }
+        }
+
+        return VisitResult.REJECT;
+      }
+      else
+      {
+        if (UIXComponent.visitTree(getWrapped(), component, callback))
+          return VisitResult.COMPLETE;
+        else
+          return VisitResult.REJECT;
+      }
+    }
+
+    private final VisitContext _wrapped;
+  }
+
+  /**
+   * Implementation used to visit each stamped row
+   */
+  private boolean _visitStampedColumnFacets(
+    VisitContext      visitContext,
+    VisitCallback     callback)
+  {
+    // visit the facets of the stamped columns
+    List<UIComponent> stamps = getStamps();
+
+    if (!stamps.isEmpty())
+    {
+      VisitContext columnVisitingContext = new ColumnFacetsOnlyVisitContext(visitContext);
+
+      for (UIComponent stamp : stamps)
+      {
+        if (UIXComponent.visitTree(columnVisitingContext, stamp, callback))
+        {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+
+  /**
+   * Visit the rows and children of the columns of the collection per row-index. This should
+   * not visit row index -1 (it will be perfomed in the visitTree method). The columns
+   * themselves should not be visited, only their children in this function.
+   * <p>
+   * Note that in Trinidad 1.2 this method does nothing, but it must be overridden. It is
+   * only being made empty in order to avoid an API change of forcing subclasses to implement
+   * this function, but visiting will not work without it being implemented. In Trinidad 2
+   * this method is abstract.
+   * </p>
+   *
+   * @param visitContext The visiting context
+   * @param callback The visit callback
+   * @return true if the visiting should stop
+   * @see #visitChildren(VisitContext, VisitCallback)
+   */
+  /*protected boolean visitData(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    return false;
+  }*/
+  protected abstract boolean visitData(
+      VisitContext  visitContext,
+      VisitCallback callback);
+
+  /**
    * Gets the CollectionModel to use with this component.
    *
    * @param createIfNull  creates the collection model if necessary
@@ -1179,14 +1417,14 @@ public abstract class UIXCollection exte
     };
   }
 
-  
+
   //
   // LocalRowKeyIndex implementation
   //
 
   /**
    * Given a row index, check if a row is locally available
-   * @param rowIndex index of row to check 
+   * @param rowIndex index of row to check
    * @return true if row is locally available
    */
   public boolean isRowLocallyAvailable(int rowIndex)
@@ -1196,7 +1434,7 @@ public abstract class UIXCollection exte
 
   /**
    * Given a row key, check if a row is locally available
-   * @param rowKey row key for the row to check 
+   * @param rowKey row key for the row to check
    * @return true if row is locally available
    */
   public boolean isRowLocallyAvailable(Object rowKey)
@@ -1216,7 +1454,7 @@ public abstract class UIXCollection exte
 
   /**
    * Check if a range of rows is locally available starting from a row index
-   * @param startIndex staring index for the range  
+   * @param startIndex staring index for the range
    * @param rowCount number of rows in the range
    * @return true if range of rows is locally available
    */
@@ -1227,7 +1465,7 @@ public abstract class UIXCollection exte
 
   /**
    * Check if a range of rows is locally available starting from a row key
-   * @param startRowKey staring row key for the range  
+   * @param startRowKey staring row key for the range
    * @param rowCount number of rows in the range
    * @return true if range of rows is locally available
    */
@@ -1235,9 +1473,9 @@ public abstract class UIXCollection exte
   {
     return getCollectionModel().areRowsLocallyAvailable(startRowKey, rowCount);
   }
-  
+
   /**
-   * Convenient API to return a row count estimate.  This method can be optimized 
+   * Convenient API to return a row count estimate.  This method can be optimized
    * to avoid a data fetch which may be required to return an exact row count
    * @return estimated row count
    */
@@ -1248,14 +1486,14 @@ public abstract class UIXCollection exte
 
 
   /**
-   * Helper API to determine if the row count returned from {@link #getEstimatedRowCount} 
+   * Helper API to determine if the row count returned from {@link #getEstimatedRowCount}
    * is EXACT, or an ESTIMATE
    */
   public LocalRowKeyIndex.Confidence getEstimatedRowCountConfidence()
   {
     return getCollectionModel().getEstimatedRowCountConfidence();
   }
-  
+
   /**
    * clear all rows from the local cache
    */
@@ -1263,7 +1501,7 @@ public abstract class UIXCollection exte
   {
     getCollectionModel().clearLocalCache();
   }
-  
+
   /**
    * Clear the requested range of rows from the local cache
    * @param startingIndex starting row index for the range to clear
@@ -1273,7 +1511,7 @@ public abstract class UIXCollection exte
   {
     getCollectionModel().clearCachedRows(startingIndex, rowsToClear);
   }
-  
+
   /**
    * Clear the requested range of rows from the local cache
    * @param startingRowKey starting row key for the range to clear
@@ -1283,7 +1521,7 @@ public abstract class UIXCollection exte
   {
     getCollectionModel().clearCachedRows(startingRowKey, rowsToClear);
   }
-  
+
   /**
    * Clear a row from the local cache by row index
    * @param index row index for the row to clear from the cache
@@ -1292,16 +1530,16 @@ public abstract class UIXCollection exte
   {
     getCollectionModel().clearCachedRow(index);
   }
-  
+
   /**
    * Clear a row from the local cache by row key
    * @param rowKey row key for the row to clear from the cache
    */
   public void clearCachedRow(Object rowKey)
   {
-    getCollectionModel().clearCachedRow(rowKey);    
+    getCollectionModel().clearCachedRow(rowKey);
   }
-  
+
   /**
    * Indicates the caching strategy supported by the model
    * @see LocalCachingStrategy
@@ -1311,7 +1549,7 @@ public abstract class UIXCollection exte
   {
     return getCollectionModel().getCachingStrategy();
   }
-  
+
 
   /**
    * override this method to place initialization code that must run

Modified: myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java?rev=964964&r1=964963&r2=964964&view=diff
==============================================================================
--- myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java (original)
+++ myfaces/trinidad/branches/anrobins_1.2.12.3_visitTree/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java Fri Jul 16 22:18:43 2010
@@ -251,7 +251,7 @@ abstract public class UIXComponent exten
   {
     ComponentProcessingContext processingContext = new ComponentProcessingContext();
     processingContext.__setIsRendering();
-    
+
     return processFlattenedChildren(context,
                                     processingContext,
                                     childProcessor,
@@ -327,6 +327,81 @@ abstract public class UIXComponent exten
   }
 
   /**
+   * Hook for subclasses to override the manner in which the component's children are visited.  The default
+   * implementation visits all of the children and facets of the Component.
+   * <code>setupChildrenVisitingContext</code> will have been called before this method is
+   * invoked and <code>tearDownChildrenVisitingContext</code> will be called after.
+   * respectively.  If the purpose of this visit was to encode the component and the
+   * component uses a CoreRenderer, the CoreRenderer's
+   * <code>setupChildrenEncodingContext</code> and <code>tearDownChildrenEncodingContext</code>
+   * will be called before and after this method is invoked, respectively.
+   * @param visitContext the <code>VisitContext</code> for this visit
+   * @param callback the <code>VisitCallback</code> instance
+   * @return <code>true</code> if the visit is complete.
+   * @see #setupChildrenVisitingContext
+   * @see #tearDownChildrenVisitingContext
+   * @see org.apache.myfaces.trinidad.render.CoreRenderer#setupChildrenEncodingContext
+   * @see org.apache.myfaces.trinidad.render.CoreRenderer#tearDownChildrenEncodingContext
+   */
+  protected boolean visitChildren(
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    // See if this is during encoding, if so, allow the renderer to control the visitation of
+    // the children so that any special encoding context may be applied around the visitation
+    // of each child.
+    if (_isEncodingVisit(visitContext))
+    {
+      Renderer renderer = getRenderer(visitContext.getFacesContext());
+      if (renderer instanceof CoreRenderer)
+      {
+        CoreRenderer coreRenderer = (CoreRenderer)renderer;
+        return coreRenderer.visitChildrenForEncoding(this, visitContext, callback);
+      }
+    }
+
+    // visit all of the children of the component
+    return _visitAllChildren(this, visitContext, callback);
+  }
+
+  /**
+   * Default implementation of visiting children that visits all children without iterating
+   * @param visitContext the <code>VisitContext</code> for this visit
+   * @param callback the <code>VisitCallback</code> instance
+   * @return <code>true</code> if the visit is complete.
+   */
+  private static boolean _visitAllChildren(
+    UIComponent   component,
+    VisitContext  visitContext,
+    VisitCallback callback)
+  {
+    // visit the children of the component
+    Iterator<UIComponent> kids = component.getFacetsAndChildren();
+
+    while (kids.hasNext())
+    {
+      // If any kid visit returns true, we are done.
+      UIComponent kid = kids.next();
+      if (kid instanceof UIXComponent)
+      {
+        if (((UIXComponent)kid).visitTree(visitContext, callback))
+        {
+          return true;
+        }
+      }
+      else
+      {
+        if (visitTree(visitContext, kid, callback))
+        {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  /**
   * <p>Perform a tree visit starting at the specified node in the tree.</p>
   *
   * <p>UIXComponent.visitTree() implementations do not invoke the
@@ -350,7 +425,7 @@ abstract public class UIXComponent exten
   * @see VisitContext#invokeVisitCallback VisitContext.invokeVisitCallback()
   */
   public static boolean visitTree(
-    VisitContext visitContext,
+    VisitContext  visitContext,
     UIComponent   component,
     VisitCallback callback)
   {
@@ -374,113 +449,105 @@ abstract public class UIXComponent exten
       uixComponent = null;
     }
 
-    // invoke the callback for this component
-    VisitResult result = visitContext.invokeVisitCallback(component, callback);
-
-    if (result == VisitResult.COMPLETE)
-      return true;
-    else if (result == VisitResult.ACCEPT)
-    {
-      // now visit the children
-      FacesContext context = visitContext.getFacesContext();
-      PhaseId phaseId = visitContext.getPhaseId();
-      RenderingContext rc = (PhaseId.RENDER_RESPONSE == phaseId)
-                              ? RenderingContext.getCurrentInstance()
-                              : null;
+    FacesContext facesContext = visitContext.getFacesContext();
+    RenderingContext rc = null;
+    if (uixComponent != null)
+    {
+      // We only need the rendering context if we are visiting a UIXComponent
+      rc = (uixComponent != null && _isEncodingVisit(visitContext))
+                                  ? RenderingContext.getCurrentInstance()
+                                  : null;
+
+      // UIXComponents are allowed to set up their context differently for encoding
+      // than normal processing, so behave differently if this is the RenderResponse
+      // phase
+      if (rc != null)
+      {
+        uixComponent.setUpEncodingContext(facesContext, rc);
+      }
+      else
+      {
+        uixComponent.setupVisitingContext(facesContext);
+      }
+    }
+    try
+    {
+      // invoke the callback for this component
+      VisitResult result = visitContext.invokeVisitCallback(component, callback);
 
-      if (uixComponent != null)
+      if (result == VisitResult.COMPLETE)
+        return true;
+      else if (result == VisitResult.ACCEPT)
       {
-        // assume that all UIXComponent NamingContainers always act as NamingContainers,
-        // (unlike <h:form>) and this it is OK to put the optimization where we
-        // don't visit the children if we know that we don't have any ids in this
-        // subtree to visit
-        if (uixComponent instanceof NamingContainer)
+        // now visit the children
+        if (uixComponent != null)
         {
-          if (visitContext.getSubtreeIdsToVisit(uixComponent).isEmpty())
-            return false;
+          // assume that all UIXComponent NamingContainers always act as NamingContainers,
+          // (unlike <h:form>) and this it is OK to put the optimization where we
+          // don't visit the children if we know that we don't have any ids in this
+          // subtree to visit
+          if (uixComponent instanceof NamingContainer)
+          {
+            if (visitContext.getSubtreeIdsToVisit(uixComponent).isEmpty())
+              return false;
+          }
+        }
+        else
+        {
+          // we only optimize walking into non-UIXComponent NamingContainers
+          // if they are UINamingConainer (which is used by <f:subview>
+          if (UINamingContainer.class == component.getClass())
+          {
+            if (visitContext.getSubtreeIdsToVisit(component).isEmpty())
+              return false;
+          }
         }
 
-        // UIXComponents are allowed to set up their context differently for encoding
-        // than normal processing, so behave differently if this is the RenderResponse
-        // phase
-        if (PhaseId.RENDER_RESPONSE == phaseId)
+        if (uixComponent != null)
         {
-          uixComponent.setUpEncodingContext(context, rc);
+          return uixComponent.visitChildren(visitContext, callback);
         }
         else
         {
-          uixComponent.setupVisitingContext(context);
+          return _visitAllChildren(component, visitContext, callback);
         }
       }
       else
       {
-        // we only optimize walking into non-UIXComponent NamingContainers
-        // if they are UINamingConainer (which is used by <f:subview>
-        if (UINamingContainer.class == component.getClass())
-        {
-          if (visitContext.getSubtreeIdsToVisit(component).isEmpty())
-            return false;
-        }
+        assert(result == VisitResult.REJECT);
       }
-
-      // visit the children of the component
-      try
+    }
+    finally
+    {
+      if (uixComponent != null)
       {
-        Iterator<UIComponent> kids = component.getFacetsAndChildren();
-
-        while(kids.hasNext())
+        if (rc != null)
         {
-          boolean done;
-
-          UIComponent currChild = kids.next();
-
-          if (currChild instanceof UIXComponent)
-          {
-            UIXComponent uixChild = (UIXComponent)currChild;
-
-            // delegate to UIXComponent's visitTree implementation to allow
-            // subclassses to modify the behavior
-            done = uixChild.visitTree(visitContext, callback);
-          }
-          else
-          {
-            // use generic visit implementation
-            done = visitTree(visitContext, currChild, callback);
-          }
-
-          // If any kid visit returns true, we are done.
-          if (done)
-          {
-            return true;
-          }
+          uixComponent.tearDownEncodingContext(facesContext, rc);
         }
-      }
-      finally
-      {
-        // tear down the context we set up in order to visit our children
-        if (uixComponent != null)
+        else
         {
-          if (PhaseId.RENDER_RESPONSE == phaseId)
-          {
-            uixComponent.tearDownEncodingContext(context, rc);
-          }
-          else
-          {
-            uixComponent.tearDownVisitingContext(context);
-          }
+          uixComponent.tearDownVisitingContext(facesContext);
         }
       }
     }
-    else
-    {
-      assert(result == VisitResult.REJECT);
-    }
 
     // if we got this far, we're not done
     return false;
   }
 
   /**
+   * Returns <code>true</code> if the components are being visited
+   * for the purpose of encoding.
+   */
+  private static boolean _isEncodingVisit(
+    VisitContext visitContext)
+  {
+    return (visitContext.getHints().contains(VisitHint.EXECUTE_LIFECYCLE) &&
+      visitContext.getPhaseId() == PhaseId.RENDER_RESPONSE);
+  }
+
+  /**
    * Add a component as a partial target to the current request. This code handles the
    * delegation to {@link #setPartialTarget(FacesContext, PartialPageContext)}
    * for UIXComponents or assumes for {@link UIComponent} that components with a renderer