You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by de...@apache.org on 2017/09/17 12:30:06 UTC
[myfaces-trinidad] 02/10: Checkpoint
This is an automated email from the ASF dual-hosted git repository.
deki pushed a commit to branch anrobins_1.2.12.3_visitTree_4
in repository https://gitbox.apache.org/repos/asf/myfaces-trinidad.git
commit d135e77a71beefcb3e4323204454e3c3d8f1b96e
Author: Andrew Robinson <ar...@apache.org>
AuthorDate: Fri Jul 16 22:18:43 2010 +0000
Checkpoint
---
.../trinidad/component/UIXIteratorTemplate.java | 359 +++++++++++++++++----
.../component/UIXNavigationLevelTemplate.java | 55 +++-
.../component/UIXNavigationPathTemplate.java | 103 +++++-
.../component/UIXNavigationTreeTemplate.java | 40 +++
.../trinidad/component/UIXPageTemplate.java | 87 +++++
.../trinidad/component/UIXProcessTemplate.java | 79 ++++-
.../trinidad/component/UIXShowDetailTemplate.java | 28 +-
.../trinidad/component/UIXShowOneTemplate.java | 100 +++++-
.../trinidad/component/UIXSwitcherTemplate.java | 33 +-
.../trinidad/component/UIXTreeTableTemplate.java | 101 +++++-
.../trinidad/component/UIXTreeTemplate.java | 27 +-
.../core/layout/CorePanelAccordionTemplate.java | 110 ++++++-
.../myfaces/trinidad/component/UIXCollection.java | 270 +++++++++++++++-
.../myfaces/trinidad/component/UIXComponent.java | 229 ++++++++-----
.../myfaces/trinidad/component/UIXHierarchy.java | 124 +++++--
.../component/visit/VisitContextWrapper.java | 80 +++++
.../myfaces/trinidad/render/CoreRenderer.java | 44 ++-
17 files changed, 1627 insertions(+), 242 deletions(-)
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java
index 7152e2b..de9a83f 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXIteratorTemplate.java
@@ -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.component;
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 UIXIteratorTemplate extends UIXCollection implements Flatt
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)
+ }
+ finally
{
- if (exp instanceof RuntimeException)
- throw (RuntimeException) exp;
-
- if (exp instanceof IOException)
- throw (IOException) exp;
- throw new IllegalStateException(exp);
+ tearDownVisitingContext(context);
}
-
+
return processedChildren;
}
@@ -125,7 +145,7 @@ public abstract class UIXIteratorTemplate extends UIXCollection implements Flatt
}
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 UIXIteratorTemplate extends UIXCollection implements Flatt
}
};
runner.run();
- Exception exp = runner.exception;
+ Exception exp = runner.getException();
if (exp != null)
{
if (exp instanceof RuntimeException)
@@ -167,7 +187,7 @@ public abstract class UIXIteratorTemplate extends UIXCollection implements Flatt
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 UIXIteratorTemplate extends UIXCollection implements Flatt
}
return map.get(key);
}
-
+
@Override
public Set<Map.Entry<String, Object>> entrySet()
{
@@ -202,7 +222,7 @@ public abstract class UIXIteratorTemplate extends UIXCollection implements Flatt
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 UIXIteratorTemplate extends UIXCollection implements Flatt
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 UIXIteratorTemplate extends UIXCollection implements Flatt
};
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 UIXIteratorTemplate extends UIXCollection implements Flatt
{
_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 UIXIteratorTemplate extends UIXCollection implements Flatt
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 UIXIteratorTemplate extends UIXCollection implements Flatt
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 UIXIteratorTemplate extends UIXCollection implements Flatt
}
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 UIXIteratorTemplate extends UIXCollection implements Flatt
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 UIXIteratorTemplate extends UIXCollection implements Flatt
model.setRowIndex(oldIndex);
}
}
-
}
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java
index e40e606..8577f8c 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationLevelTemplate.java
@@ -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 UIXNavigationLevelTemplate extends UIXNavigationHierarchy
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;
+ }
}
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java
index 10c7d23..bf599b9 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationPathTemplate.java
@@ -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 UIXNavigationPathTemplate extends UIXNavigationHierarchy
}
}
}
-
+
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;
+ }
}
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java
index daaf0b8..c890267 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXNavigationTreeTemplate.java
@@ -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 UIXNavigationTreeTemplate extends UIXNavigationHierarchy
}
@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());
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java
index fc79abf..ad45078 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXPageTemplate.java
@@ -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 extends UIXMenuHierarchy
/**/ 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 extends UIXMenuHierarchy
}
@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());
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java
index 0169371..9f4bca5 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXProcessTemplate.java
@@ -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;
+ }
}
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java
index fb9b19a..a1069b2 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowDetailTemplate.java
@@ -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.AbortProcessingException;
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 UIXShowDetailTemplate extends UIXComponentBase
{
// 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 UIXShowDetailTemplate extends UIXComponentBase
{
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 UIXShowDetailTemplate extends UIXComponentBase
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);
}
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java
index 4aa07a9..896580c 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java
@@ -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 extends UIXComponentBase
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 extends UIXComponentBase
}
}
+ 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();
}
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java
index 901ab83..d541f76 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXSwitcherTemplate.java
@@ -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 UIXSwitcherTemplate extends UIXComponentBase implements Fl
facet.processValidators(context);
}
-
/**
* Only process updates on the currently active facet.
*/
@@ -79,7 +82,7 @@ abstract public class UIXSwitcherTemplate extends UIXComponentBase implements Fl
final S callbackContext) throws IOException
{
UIComponent facet = _getFacet();
-
+
if (facet != null)
return UIXComponent.processFlattenedChildren(context,
cpContext,
@@ -112,7 +115,6 @@ abstract public class UIXSwitcherTemplate extends UIXComponentBase implements Fl
__encodeRecursive(context, facet);
}
-
/**
* Override to return true.
*/
@@ -122,6 +124,26 @@ abstract public class UIXSwitcherTemplate extends UIXComponentBase implements Fl
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 UIXSwitcherTemplate extends UIXComponentBase implements Fl
return null;
}
-
}
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java
index b7ff644..286c166 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTableTemplate.java
@@ -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.AbortProcessingException;
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 UIXTreeTableTemplate extends UIXTree
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 UIXTreeTableTemplate extends UIXTree
_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 UIXTreeTableTemplate extends UIXTree
{
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 UIXTreeTableTemplate extends UIXTree
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 UIXTreeTableTemplate extends UIXTree
}
}
+
+ @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 UIXTreeTableTemplate extends UIXTree
// 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 UIXTreeTableTemplate extends UIXTree
return state;
}
-
+
/**
* Sets the internal state of this component.
* @param stampState the internal state is obtained from this object.
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java
index 928c06d..f3ebd7f 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java
@@ -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 extends UIXHierarchy
}
@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 extends UIXHierarchy
setSelectedRowKeys(new RowKeySetTreeImpl());
}
-
/**
* Gets the internal state of this component.
*/
diff --git a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java
index 9515c61..544bbdc 100644
--- a/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java
+++ b/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/core/layout/CorePanelAccordionTemplate.java
@@ -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 extends UIXPanel
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
diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
index 532c395..1c02cdc 100644
--- a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
@@ -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 extends UIXComponentBase
}
/**
+ * <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 extends UIXComponentBase
};
}
-
+
//
// 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 extends UIXComponentBase
/**
* 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 extends UIXComponentBase
/**
* 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 extends UIXComponentBase
/**
* 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 extends UIXComponentBase
{
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 extends UIXComponentBase
/**
- * 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 extends UIXComponentBase
{
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 extends UIXComponentBase
{
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 extends UIXComponentBase
{
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 extends UIXComponentBase
{
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 extends UIXComponentBase
{
return getCollectionModel().getCachingStrategy();
}
-
+
/**
* override this method to place initialization code that must run
diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java
index a80aa48..a3fef4c 100644
--- a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponent.java
@@ -251,7 +251,7 @@ abstract public class UIXComponent extends UIComponent
{
ComponentProcessingContext processingContext = new ComponentProcessingContext();
processingContext.__setIsRendering();
-
+
return processFlattenedChildren(context,
processingContext,
childProcessor,
@@ -327,6 +327,81 @@ abstract public class UIXComponent extends UIComponent
}
/**
+ * 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 extends UIComponent
* @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 extends UIComponent
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)
+ 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
{
- // now visit the children
- FacesContext context = visitContext.getFacesContext();
- PhaseId phaseId = visitContext.getPhaseId();
- RenderingContext rc = (PhaseId.RENDER_RESPONSE == phaseId)
- ? RenderingContext.getCurrentInstance()
- : null;
+ // 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)
+ {
+ // 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
{
- if (visitContext.getSubtreeIdsToVisit(uixComponent).isEmpty())
- return false;
+ // 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
diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java
index a9ec25a..ee22ca6 100644
--- a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXHierarchy.java
@@ -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,11 +19,12 @@
package org.apache.myfaces.trinidad.component;
import java.util.Collections;
-
import java.util.List;
import javax.faces.component.UIComponent;
+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;
@@ -37,7 +38,7 @@ import org.apache.myfaces.trinidad.model.TreeModel;
*
* @version $Name: $ ($Revision: adfrt/faces/adf-faces-api/src/main/java/oracle/adf/view/faces/component/UIXHierarchy.java#0 $) $Date: 10-nov-2005.19:09:52 $
*/
-abstract public class UIXHierarchy extends UIXCollection implements CollectionComponent, LocalRowKeyIndex,
+abstract public class UIXHierarchy extends UIXCollection implements CollectionComponent, LocalRowKeyIndex,
TreeLocalRowKeyIndex
{
/**
@@ -58,7 +59,7 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
public CollectionModel createCollectionModel(CollectionModel current, Object value)
{
TreeModel model = ModelUtils.toTreeModel(value);
- model.setRowKey(null);
+ model.setRowKey(null);
return model;
}
@@ -80,8 +81,8 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
public int getRows()
{
return 0;
- }
-
+ }
+
/**
* Treats the current element as a parent element and steps into the children.
* A new path is constructed by appending the null value to the old path.
@@ -128,7 +129,7 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
*/
public boolean isContainerEmpty()
{
-
+
return getTreeModel().isContainerEmpty();
}
@@ -169,7 +170,7 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
{
return getTreeModel().getContainerRowKey(childKey);
}
-
+
/**
* Gets the all the rowKeys of the ancestors of the given child row.
* @see TreeModel#getAllAncestorContainerRowKeys(Object)
@@ -184,8 +185,8 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
//
/**
- * Indicates whether data for a child model (children of the current node) is
- * locally available.
+ * Indicates whether data for a child model (children of the current node) is
+ * locally available.
* @see TreeModel#isChildCollectionLocallyAvailable()
* @return true if child data is locally available
*/
@@ -196,7 +197,7 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
/**
* Indicates whether child data for the node with the given index is
- * locally available.
+ * locally available.
* @see TreeModel#isChildCollectionLocallyAvailable(int)
* @param index row index to check
* @return true if child data is available, false otherwise
@@ -208,7 +209,7 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
/**
* Indicates whether child data for the node with the given row key is
- * locally available.
+ * locally available.
* @see TreeModel#isChildCollectionLocallyAvailable(Object)
* @param rowKey row key to check
* @return true if child data is available, false otherwise
@@ -221,7 +222,7 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
/**
* Check if a range of rows is locally available starting from a row index. The range
* can include child nodes in any expanded nodes within the range.
- * @param startIndex staring index for the range
+ * @param startIndex staring index for the range
* @param rowCount number of rows in the range
* @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
* availability
@@ -237,7 +238,7 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
/**
* Check if a range of rows is locally available starting from a row key. The range
* can include child nodes in any expanded nodes within the range.
- * @param startRowKey staring row key for the range
+ * @param startRowKey staring row key for the range
* @param rowCount number of rows in the range
* @param disclosedRowKeys set of expanded nodes which may fall within the range to check for
* availability
@@ -273,8 +274,8 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
{
TreeModel model = (TreeModel) getCollectionModel();
return model;
- }
-
+ }
+
@Override
protected List<UIComponent> getStamps()
{
@@ -283,7 +284,94 @@ abstract public class UIXHierarchy extends UIXCollection implements CollectionCo
return Collections.singletonList(nodeStamp);
else
return Collections.emptyList();
- }
+ }
abstract public Object getFocusRowKey();
+
+ protected final boolean visitLevel(
+ VisitContext visitContext,
+ VisitCallback callback,
+ List<UIComponent> stamps)
+ {
+ if (getRowCount() != 0)
+ {
+ if (!stamps.isEmpty())
+ {
+ int oldRow = getRowIndex();
+ int first = getFirst();
+ int last = TableUtils.getLast(this, first);
+
+ try
+ {
+ for (int i = first; i <= last; i++)
+ {
+ setRowIndex(i);
+
+ for (UIComponent currStamp : stamps)
+ {
+ // visit the stamps. If we have visited all of the visit targets then return early
+ if (UIXComponent.visitTree(visitContext, currStamp, callback))
+ return true;
+ }
+ }
+ }
+ finally
+ {
+ setRowIndex(oldRow);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected final boolean visitHierarchy(
+ VisitContext visitContext,
+ VisitCallback callback,
+ List<UIComponent> stamps,
+ RowKeySet disclosedRowKeys)
+ {
+ int oldRow = getRowIndex();
+ int first = getFirst();
+ int last = TableUtils.getLast(this, first);
+
+ try
+ {
+ for(int i = first; i <= last; i++)
+ {
+ setRowIndex(i);
+ if (!stamps.isEmpty())
+ {
+ for (UIComponent currStamp : stamps)
+ {
+ // visit the stamps. If we have visited all of the visit targets then return early
+ if (UIXComponent.visitTree(visitContext, currStamp, callback))
+ return true;
+ }
+ }
+
+ if (isContainer() && ((disclosedRowKeys == null) || disclosedRowKeys.isContained()))
+ {
+ enterContainer();
+
+ try
+ {
+ // visit this container. If we have visited all of the visit targets then return early
+ if (visitHierarchy(visitContext, callback, stamps, disclosedRowKeys))
+ return true;
+ }
+ finally
+ {
+ exitContainer();
+ }
+ }
+ }
+ }
+ finally
+ {
+ setRowIndex(oldRow);
+ }
+
+ return false;
+ }
}
diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/visit/VisitContextWrapper.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/visit/VisitContextWrapper.java
new file mode 100644
index 0000000..3a0345b
--- /dev/null
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/visit/VisitContextWrapper.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.trinidad.component.visit;
+
+import java.util.Collection;
+import java.util.Set;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseId;
+
+
+/**
+ * A port of the JSF 2 <code>VisitContextWrapper</code> class so that we may be able to use
+ * its functionality in JSF 1.2 with Trinidad 1.2
+ */
+public abstract class VisitContextWrapper
+ extends VisitContext
+{
+ /**
+ * Get the wrapped visit context
+ */
+ public abstract VisitContext getWrapped();
+
+ @Override
+ public FacesContext getFacesContext()
+ {
+ return getWrapped().getFacesContext();
+ }
+
+ @Override
+ public PhaseId getPhaseId()
+ {
+ return getWrapped().getPhaseId();
+ }
+
+ @Override
+ public Set<VisitHint> getHints()
+ {
+ return getWrapped().getHints();
+ }
+
+ @Override
+ public Collection<String> getIdsToVisit()
+ {
+ return getWrapped().getIdsToVisit();
+ }
+
+ @Override
+ public Collection<String> getSubtreeIdsToVisit(
+ UIComponent component)
+ {
+ return getWrapped().getSubtreeIdsToVisit(component);
+ }
+
+ @Override
+ public VisitResult invokeVisitCallback(
+ UIComponent component,
+ VisitCallback callback)
+ {
+ return getWrapped().invokeVisitCallback(component, callback);
+ }
+}
diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java
index 63f6dc4..366fbe0 100644
--- a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java
@@ -161,6 +161,46 @@ public class CoreRenderer extends Renderer
tearDownEncodingContext(context, rc, (UIXComponent)component);
}
+ /**
+ * Hook to allow the renderer to customize the visitation of the children components
+ * of a component during the visitation of a component during rendering.
+ *
+ * @param component the component which owns the children to visit
+ * @param visitContext the visitation context
+ * @param callback the visit callback
+ * @return <code>true</code> if the visit is complete.
+ * @see UIXComponent#visitChildren(VisitContext, VisitCallback)
+ */
+ public boolean visitChildrenForEncoding(
+ UIXComponent 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 (UIXComponent.visitTree(visitContext, kid, callback))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
//
// COERCION HELPERS
@@ -684,9 +724,9 @@ public class CoreRenderer extends Renderer
{
return (Agent.PLATFORM_GENERICPDA.equals(rc.getAgent().getPlatformName()));
}
-
+
/**
- * This method returns true if a user-agent's platform is NokiaS60
+ * This method returns true if a user-agent's platform is NokiaS60
* @param arc - RenderingContext of a request
* @return boolean
*/
--
To stop receiving notification emails like this one, please contact
"commits@myfaces.apache.org" <co...@myfaces.apache.org>.