Author: nbelaevski
Date: 2008-08-07 11:22:38 -0400 (Thu, 07 Aug 2008)
New Revision: 9975
Modified:
trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java
trunk/ui/tree/src/main/java/org/richfaces/component/state/TreeState.java
trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java
trunk/ui/tree/src/test/java/org/richfaces/component/TreeComponentTest.java
Log:
https://jira.jboss.org/jira/browse/RF-3899
Modified: trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java
===================================================================
--- trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java 2008-08-07 15:20:19
UTC (rev 9974)
+++ trunk/ui/tree/src/main/java/org/richfaces/component/UITree.java 2008-08-07 15:22:38
UTC (rev 9975)
@@ -365,12 +365,10 @@
super.resetDataModel();
TreeState state = (TreeState) getComponentState();
- // transfer nodes delayed to open to rendering queue
- state.transferQueuedNodes();
// re-set stopInCollapsed to handle AJAX switch type change
state.setStopInCollapsed(isStopInCollapsed());
}
-
+
public void walk(FacesContext faces, DataVisitor visitor)
throws IOException {
@@ -1176,6 +1174,11 @@
public Object getParentRowKey(Object rowKey) {
return ((AbstractTreeDataModel) getExtendedDataModel()).getParentRowKey(rowKey);
}
+
+ public void transferQueuedNode() {
+ TreeState treeState = (TreeState) getComponentState();
+ treeState.transferQueuedNodes((TreeRowKey) getRowKey());
+ }
}
Modified: trunk/ui/tree/src/main/java/org/richfaces/component/state/TreeState.java
===================================================================
--- trunk/ui/tree/src/main/java/org/richfaces/component/state/TreeState.java 2008-08-07
15:20:19 UTC (rev 9974)
+++ trunk/ui/tree/src/main/java/org/richfaces/component/state/TreeState.java 2008-08-07
15:22:38 UTC (rev 9975)
@@ -23,11 +23,12 @@
import java.io.IOException;
import java.io.Serializable;
-import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.Map.Entry;
import javax.faces.application.FacesMessage;
import javax.faces.component.StateHolder;
@@ -53,63 +54,36 @@
*/
private static final long serialVersionUID = 9083705369340888171L;
- private final class Visitor implements DataVisitor {
- private TreeRowKey key;
+ enum NodeState {
+ EXPANDED, COLLAPSED;
+ }
+
+ private class ExpansionVisitor implements DataVisitor {
private UITree tree;
- public Visitor(TreeRowKey key, UITree tree) {
+ public ExpansionVisitor(UITree tree) {
super();
- this.key = key;
+
this.tree = tree;
}
public void process(FacesContext context, Object rowKey, Object argument)
throws IOException {
tree.setRowKey(context, rowKey);
- if (tree.isRowAvailable()) {
- TreeRowKey nextKey = (TreeRowKey) rowKey;
-
- if (!tree.isLeaf() && nextKey != null) {
- if (key == null || nextKey.isSubKey(key)
- || nextKey.equals(key)) {
- if (tree.isImmediate()) {
- queuedExpandedNodes.add(nextKey);
- } else {
- expandedNodes.add(nextKey);
- }
- queuedCollapsedNodes.remove(nextKey);
- }
- }
- } else {
- FacesMessage message = new FacesMessage("Row key: " + rowKey
- + " isn't available!");
- message.setSeverity(FacesMessage.SEVERITY_ERROR);
-
- context.addMessage(tree.getBaseClientId(context), message);
+ if (!tree.isLeaf()) {
+ addQueuedState((TreeRowKey) rowKey, NodeState.EXPANDED);
}
}
- }
-
- private final static TreeRange RANGE_UNCONSTRAINED = new TreeRange() {
- public boolean processChildren(TreeRowKey rowKey) {
- return true;
- }
-
- public boolean processNode(TreeRowKey rowKey) {
- return true;
- }
};
-
+
private boolean stopInCollapsed = false;
private TreeRowKey selectedNode = null;
- private Set expandedNodes = new HashSet();
+ private Set<TreeRowKey> expandedNodes = new HashSet<TreeRowKey>();
- private Set queuedExpandedNodes = new HashSet();
+ private Map<TreeRowKey, NodeState> queuedNodeStates = new HashMap<TreeRowKey,
NodeState>();
- private Set queuedCollapsedNodes = new HashSet();
-
public TreeState() {
super();
}
@@ -124,8 +98,8 @@
return true;
}
- return expandedNodes.contains(rowKey)
- || queuedExpandedNodes.contains(rowKey);
+ return expandedNodes.contains(rowKey) ||
+ NodeState.EXPANDED.equals(queuedNodeStates.get(rowKey));
}
public boolean isSelected(TreeRowKey rowKey) {
@@ -142,13 +116,7 @@
private boolean _transient;
- private transient TreeRange treeRange = null;
-
public Range getRange() {
- if (treeRange != null) {
- return treeRange;
- }
-
if (stopInCollapsed) {
return new TreeRange() {
@@ -165,7 +133,7 @@
}
};
} else {
- return RANGE_UNCONSTRAINED;
+ return TreeRange.RANGE_UNCONSTRAINED;
}
}
@@ -176,21 +144,19 @@
public void restoreState(FacesContext context, Object state) {
Object[] _state = (Object[]) state;
expandedNodes = (Set) _state[0];
- _transient = ((Boolean) _state[1]).booleanValue();
- stopInCollapsed = ((Boolean) _state[2]).booleanValue();
- selectedNode = (TreeRowKey) _state[3];
- queuedExpandedNodes = (Set) _state[4];
- queuedCollapsedNodes = (Set) _state[5];
+ queuedNodeStates = (Map) _state[1];
+ _transient = ((Boolean) _state[2]).booleanValue();
+ stopInCollapsed = ((Boolean) _state[3]).booleanValue();
+ selectedNode = (TreeRowKey) _state[4];
}
public Object saveState(FacesContext context) {
- Object[] state = new Object[6];
+ Object[] state = new Object[5];
state[0] = expandedNodes;
- state[1] = new Boolean(_transient);
- state[2] = new Boolean(stopInCollapsed);
- state[3] = selectedNode;
- state[4] = queuedExpandedNodes;
- state[5] = queuedCollapsedNodes;
+ state[1] = queuedNodeStates;
+ state[2] = Boolean.valueOf(_transient);
+ state[3] = Boolean.valueOf(stopInCollapsed);
+ state[4] = selectedNode;
return state;
}
@@ -206,96 +172,101 @@
this.stopInCollapsed = stopInCollapsed;
}
- private void visitNodes(UITree tree, TreeRange treeRange, TreeRowKey rootKey)
- throws IOException {
- try {
- this.treeRange = treeRange;
- Object oldKey = tree.getRowKey();
-
- tree.walkModel(FacesContext.getCurrentInstance(), new Visitor(
- rootKey, tree), treeRange, rootKey, null);
- tree.setRowKey(oldKey);
- } finally {
- this.treeRange = null;
- }
- }
-
public void expandAll(UITree tree) throws IOException {
- queuedCollapsedNodes.clear();
- // SubTreeChildrenAppender infoAppender = null;
- //
- // if (storedPersister != null) {
- // storedPersister.reset();
- // infoAppender = storedPersister.getAppender(null);
- // }
-
- visitNodes(tree, RANGE_UNCONSTRAINED, null);
+ queuedNodeStates = new HashMap<TreeRowKey, NodeState>();
+
+ tree.walk(FacesContext.getCurrentInstance(),
+ new ExpansionVisitor(tree), TreeRange.RANGE_UNCONSTRAINED, null, null);
}
public void collapseAll(UITree tree) throws IOException {
- expandedNodes.clear();
- queuedExpandedNodes.clear();
- // RequestUtils.setStoredPersister(tree.getBaseClientId(context),
- // context, null);
+ queuedNodeStates = new HashMap<TreeRowKey, NodeState>();
+
+ for (TreeRowKey key : expandedNodes) {
+ addQueuedState(key, NodeState.COLLAPSED);
+ }
}
- public void collapseNode(UITree tree, TreeRowKey rowKey) throws IOException {
- expandedNodes.remove(rowKey);
- queuedExpandedNodes.remove(rowKey);
- queuedCollapsedNodes.add(rowKey);
- // TreePersister storedPersister =
- // RequestUtils.getStoredPersister(tree.getBaseClientId(context),
- // context);
- // if (storedPersister != null) {
- // storedPersister.removeNode(rowKey);
- // }
+ public void addQueuedState(TreeRowKey rowKey, NodeState state) {
+ if (NodeState.EXPANDED.equals(state)) {
+ if (!expandedNodes.contains(rowKey)) {
+ queuedNodeStates.put(rowKey, NodeState.EXPANDED);
+ }
+ } else {
+ queuedNodeStates.put(rowKey, NodeState.COLLAPSED);
+ }
}
- public void expandNode(UITree tree, final TreeRowKey rowKey) throws IOException {
- // SubTreeChildrenAppender infoAppender;
- // if (storedPersister != null) {
- // infoAppender = storedPersister.getAppender(rowKey);
- // } else {
- // infoAppender = null;
- // }
-
- TreeRange range;
- // it's enough to traverse only subkeys of the node
- // we're opening
- range = new TreeRange() {
- public boolean processChildren(TreeRowKey nextKey) {
- return true;
+ public void collapseNode(UITree tree, TreeRowKey rowKey) throws IOException {
+ addQueuedState(rowKey, NodeState.COLLAPSED);
+ }
+
+ public void expandNode(UITree tree, TreeRowKey rowKey) throws IOException {
+ Object oldRowKey = tree.getRowKey();
+
+ tree.setRowKey(rowKey);
+
+ if (tree.isRowAvailable()) {
+ if (!tree.isLeaf()) {
+ TreeRowKey key = rowKey;
+
+ while (key != null && key.depth() != 0) {
+ addQueuedState(key, NodeState.EXPANDED);
+ key = (TreeRowKey) tree.getParentRowKey(key);
+ };
+
+ } else {
+ //TODO debug log
}
+ } else {
+ FacesMessage message = new FacesMessage("Row key: " + rowKey
+ + " isn't available!");
+ message.setSeverity(FacesMessage.SEVERITY_ERROR);
- public boolean processNode(TreeRowKey nextKey) {
- return (rowKey == null && nextKey == null)
- || nextKey.equals(rowKey)
- || nextKey.isSubKey(rowKey);
+ FacesContext context = FacesContext.getCurrentInstance();
+
+ context.addMessage(tree.getBaseClientId(context), message);
+ }
+
+ tree.setRowKey(oldRowKey);
+ }
+
+ private void transferState(TreeRowKey key, NodeState state) {
+ if (state != null) {
+ if (NodeState.EXPANDED.equals(state)) {
+ expandedNodes.add(key);
+ } else {
+ expandedNodes.remove(key);
}
-
- };
- visitNodes(tree, range, rowKey);
-
+ }
}
+
+ public void transferQueuedNodes(TreeRowKey rootKey) {
+ Iterator<Entry<TreeRowKey, NodeState>> itr =
queuedNodeStates.entrySet().iterator();
+ while (itr.hasNext()) {
+ Entry<TreeRowKey, NodeState> entry = itr.next();
+ TreeRowKey rowKey = entry.getKey();
+
+ if (rootKey == null || rootKey.depth() == 0 || rootKey.isSubKey(rowKey)) {
+ transferState(rowKey, entry.getValue());
+
+ itr.remove();
+ }
+ }
- public void transferQueuedNodes() {
- expandedNodes.addAll(queuedExpandedNodes);
- queuedExpandedNodes.clear();
- expandedNodes.removeAll(queuedCollapsedNodes);
- queuedCollapsedNodes.clear();
+ if (queuedNodeStates.isEmpty()) {
+ queuedNodeStates = new HashMap<TreeRowKey, NodeState>();
+ }
}
+
+ public void makeExpanded(TreeRowKey key) {
+ queuedNodeStates.remove(key);
+ expandedNodes.add(key);
+ }
- private List<TreeRowKey> getAllSubKeys(Set nodes, TreeRowKey parent) {
- List<TreeRowKey> keys = new ArrayList<TreeRowKey>();
- Iterator<TreeRowKey> iter = nodes.iterator();
- while (iter != null && iter.hasNext()) {
- TreeRowKey key = iter.next();
- if (key != null && (parent.isSubKey(key) || parent.equals(key))) {
- keys.add(key);
- }
- }
-
- return keys;
+ public void makeCollapsed(TreeRowKey key) {
+ queuedNodeStates.remove(key);
+ expandedNodes.remove(key);
}
public TreeState getSubState(TreeRowKey rowKey) {
@@ -306,24 +277,28 @@
// FIXME: whether it is needed?
subTreeState._transient = _transient;
- List<TreeRowKey> nodes = getAllSubKeys(this.expandedNodes, rowKey);
- Iterator<TreeRowKey> iter = nodes != null ? nodes.iterator() : null;
- while (iter != null && iter.hasNext()) {
- subTreeState.expandedNodes.add(iter.next().getSubKey(rowKey.depth() - 1));
+ int subKeyDepth = rowKey.depth() - 1;
+
+ for (Iterator<TreeRowKey> iter = this.expandedNodes.iterator(); iter.hasNext(); )
{
+ TreeRowKey nextKey = iter.next();
+ if (nextKey != null && rowKey.isSubKey(nextKey)) {
+ subTreeState.expandedNodes.add(nextKey.getSubKey(subKeyDepth));
+ }
}
- nodes = getAllSubKeys(this.queuedExpandedNodes, rowKey);
- iter = nodes != null ? nodes.iterator() : null;
- while (iter != null && iter.hasNext()) {
- subTreeState.queuedExpandedNodes.add(iter.next().getSubKey(rowKey.depth() - 1));
- }
+ for (Iterator<Entry<TreeRowKey, NodeState>> iter =
this.queuedNodeStates.entrySet().iterator();
+ iter.hasNext(); ) {
- nodes = getAllSubKeys(this.queuedCollapsedNodes, rowKey);
- iter = nodes != null ? nodes.iterator() : null;
- while (iter != null && iter.hasNext()) {
- subTreeState.queuedCollapsedNodes.add(iter.next().getSubKey(rowKey.depth() - 1));
+ Entry<TreeRowKey, NodeState> entry = iter.next();
+
+ TreeRowKey nextKey = entry.getKey();
+
+ if (nextKey != null && rowKey.isSubKey(nextKey)) {
+ subTreeState.queuedNodeStates.put(nextKey.getSubKey(subKeyDepth),
+ entry.getValue());
+ }
}
-
+
return subTreeState;
}
@@ -333,29 +308,26 @@
}
if (rowKey.getPath().equals("null")) { // root node
- this.expandedNodes.clear();
- this.queuedCollapsedNodes.clear();
- this.queuedExpandedNodes.clear();
- } else {
- // collect nodes to clean up
- List<TreeRowKey> nodes = getAllSubKeys(this.expandedNodes,
rowKey);
- Iterator<TreeRowKey> iter = nodes != null ?
nodes.iterator() : null;
- while (iter != null && iter.hasNext()) {
- this.expandedNodes.remove(iter.next());
- }
-
- nodes = getAllSubKeys(this.queuedExpandedNodes, rowKey);
- iter = nodes != null ? nodes.iterator() : null;
- while (iter != null && iter.hasNext()) {
- this.queuedExpandedNodes.remove(iter.next());
- }
-
- nodes = getAllSubKeys(this.queuedCollapsedNodes, rowKey);
- iter = nodes != null ? nodes.iterator() : null;
- while (iter != null && iter.hasNext()) {
- this.queuedCollapsedNodes.remove(iter.next());
- }
- }
+ this.expandedNodes.clear();
+ this.queuedNodeStates = new HashMap<TreeRowKey, NodeState>();
+ } else {
+ // collect nodes to clean up
+ for (Iterator<TreeRowKey> itr = this.expandedNodes.iterator(); itr.hasNext(); )
{
+ TreeRowKey nextKey = itr.next();
+ if (nextKey != null && rowKey.isSubKey(nextKey)) {
+ itr.remove();
+ }
+ }
+
+ for (Iterator<Entry<TreeRowKey, NodeState>> itr =
+ this.queuedNodeStates.entrySet().iterator(); itr.hasNext(); ) {
+
+ TreeRowKey nextKey = itr.next().getKey();
+ if (nextKey != null && rowKey.isSubKey(nextKey)) {
+ itr.remove();
+ }
+ }
+ }
}
public void mergeSubState(TreeRowKey rowKey, TreeState subState) {
@@ -363,28 +335,26 @@
while (iter != null && iter.hasNext()) {
TreeRowKey key = iter.next().getSubKey(1);
if (key.depth() > 0) {
- expandedNodes.add(new ListRowKey((ListRowKey)rowKey, (ListRowKey)key));
+ expandedNodes.add(new ListRowKey((ListRowKey)rowKey, (ListRowKey)key));
} else if (!expandedNodes.contains(rowKey)) {
- expandedNodes.add(rowKey);
+ expandedNodes.add(rowKey);
}
}
- iter = subState.queuedExpandedNodes.iterator();
- while (iter != null && iter.hasNext()) {
- TreeRowKey key = iter.next().getSubKey(1);
+
+ Iterator<Entry<TreeRowKey, NodeState>> sItr =
subState.queuedNodeStates.entrySet().iterator();
+ while (sItr.hasNext()) {
+ Entry<TreeRowKey, NodeState> entry = sItr.next();
+ TreeRowKey key = entry.getKey().getSubKey(1);
+
+ TreeRowKey newKey;
+
if (key.depth() > 0) {
- queuedExpandedNodes.add(new ListRowKey((ListRowKey)rowKey, (ListRowKey)key));
- } else if (!queuedExpandedNodes.contains(rowKey)) {
- queuedExpandedNodes.add(rowKey);
+ newKey = new ListRowKey((ListRowKey)rowKey, (ListRowKey)key);
+ } else {
+ newKey = rowKey;
}
+
+ addQueuedState(newKey, entry.getValue());
}
- iter = subState.queuedCollapsedNodes.iterator();
- while (iter != null && iter.hasNext()) {
- TreeRowKey key = iter.next().getSubKey(1);
- if (key.depth() > 0) {
- queuedCollapsedNodes.add(new ListRowKey((ListRowKey)rowKey, (ListRowKey)key));
- } else if (!queuedCollapsedNodes.contains(rowKey)) {
- queuedCollapsedNodes.add(rowKey);
- }
- }
}
}
Modified: trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java
===================================================================
--- trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java 2008-08-07
15:20:19 UTC (rev 9974)
+++ trunk/ui/tree/src/main/java/org/richfaces/renderkit/TreeRendererBase.java 2008-08-07
15:22:38 UTC (rev 9975)
@@ -238,10 +238,12 @@
public void process(FacesContext context, Object rowKey, Object argument)
throws IOException {
- processAdvisors(context, (TreeRowKey)rowKey);
+ TreeRowKey<?> treeRowKey = (TreeRowKey<?>) rowKey;
- navigator.followRowKey(context, (TreeRowKey) rowKey);
+ processAdvisors(context, treeRowKey);
+ navigator.followRowKey(context, treeRowKey);
+
Context c = flag.getContext();
if (c != null) {
c.setHasChildren(false);
@@ -300,7 +302,7 @@
}
public void processAdvisors(FacesContext context, TreeRowKey rowKey) throws IOException
{
- TreeState componentState = (TreeState) tree.getComponentState();
+ TreeState state = (TreeState) tree.getComponentState();
TreeStateAdvisor stateAdvisor = (TreeStateAdvisor)tree.getStateAdvisor();
if (null == stateAdvisor) {
@@ -329,26 +331,22 @@
Boolean adviseOpened = stateAdvisor.adviseNodeOpened(tree);
if (null != adviseOpened) {
if (adviseOpened.booleanValue()) {
- if (!componentState.isExpanded(rowKey)) {
- componentState.expandNode(tree, rowKey);
- }
+ state.makeExpanded(rowKey);
+ } else {
+ state.makeCollapsed(rowKey);
}
- else {
- if (componentState.isExpanded(rowKey)) {
- componentState.collapseNode(tree, rowKey);
- }
- }
}
+
Boolean adviseSelected = stateAdvisor.adviseNodeSelected(tree);
if (null != adviseSelected) {
if (adviseSelected.booleanValue()) {
- if (!componentState.isSelected(rowKey)) {
- componentState.setSelected(rowKey);
+ if (!state.isSelected(rowKey)) {
+ state.setSelected(rowKey);
}
}
else {
- if (componentState.isSelected(rowKey)) {
- componentState.setSelected(null);
+ if (state.isSelected(rowKey)) {
+ state.setSelected(null);
}
}
}
@@ -592,10 +590,6 @@
try {
input.captureOrigValue();
- if (key != null) {
- droppedDownToLevelFlag.setContext(null);
- }
-
input.setRowKey(context, key);
RendererDataModelEventNavigator levelNavigator = new
RendererDataModelEventNavigator(input, rowKey, context,
@@ -626,6 +620,9 @@
};
+ input.transferQueuedNode();
+
+ //TODO should render if current node not in range?
input.walk(context, new DataVisitorWithLastElement(droppedDownToLevelFlag, input,
levelNavigator, key), treeRange, key, null);
Modified: trunk/ui/tree/src/test/java/org/richfaces/component/TreeComponentTest.java
===================================================================
--- trunk/ui/tree/src/test/java/org/richfaces/component/TreeComponentTest.java 2008-08-07
15:20:19 UTC (rev 9974)
+++ trunk/ui/tree/src/test/java/org/richfaces/component/TreeComponentTest.java 2008-08-07
15:22:38 UTC (rev 9975)
@@ -969,7 +969,8 @@
try {
state.expandAll(tree);
} catch (Exception e) {
- System.out.println("testManipulateState expandAll failed");
+ System.out.println("testManipulateState expandAll failed");
+ fail();
}
tree.setRowKey(rowKey);