Author: nbelaevski
Date: 2007-11-02 12:15:41 -0400 (Fri, 02 Nov 2007)
New Revision: 3726
Added:
trunk/framework/api/src/main/java/org/richfaces/model/CacheableTreeDataModel.java
trunk/framework/api/src/main/java/org/richfaces/model/ClassicCacheableTreeDataModel.java
trunk/framework/api/src/main/java/org/richfaces/model/SwingCacheableTreeDataModel.java
Modified:
trunk/framework/api/src/main/java/org/richfaces/model/ClassicTreeDataModel.java
trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeDataModel.java
trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeNodeImpl.java
trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModel.java
trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModelNodeAdaptor.java
Log:
http://jira.jboss.com/jira/browse/RF-864
Added: trunk/framework/api/src/main/java/org/richfaces/model/CacheableTreeDataModel.java
===================================================================
--- trunk/framework/api/src/main/java/org/richfaces/model/CacheableTreeDataModel.java
(rev 0)
+++
trunk/framework/api/src/main/java/org/richfaces/model/CacheableTreeDataModel.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -0,0 +1,138 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.model;
+
+import java.io.IOException;
+
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.model.DataVisitor;
+import org.ajax4jsf.model.Range;
+
+/**
+ * Extension of {@link TreeDataModel} supporting lazy data fetching for caching
+ *
+ * created 08.01.2007
+ *
+ * @author Nick - mailto:nbelaevski@exadel.com
+ */
+public abstract class CacheableTreeDataModel<T> extends TreeDataModel<T> {
+
+ private final class Visitor implements DataVisitor, LastElementAware {
+ private final DataVisitor visitor;
+
+ private Visitor(DataVisitor visitor) {
+ this.visitor = visitor;
+ }
+
+ public void process(FacesContext context, Object rowKey, Object argument)
+ throws IOException {
+ TreeRowKey treeRowKey = (TreeRowKey) rowKey;
+ treeDataModel.setRowKey(treeRowKey);
+ setDefaultNodeData(locateTreeNode(treeRowKey, true), treeDataModel.getRowData());
+
+ if (visitor != null) {
+ visitor.process(context, rowKey, argument);
+ }
+ }
+
+ public void resetLastElement() {
+ if (visitor instanceof LastElementAware) {
+ ((LastElementAware) visitor).resetLastElement();
+
+ }
+ }
+
+ public void setLastElement() {
+ if (visitor instanceof LastElementAware) {
+ ((LastElementAware) visitor).setLastElement();
+
+ }
+ }
+ }
+
+ private TreeDataModel<T> treeDataModel;
+
+ public boolean isLeaf() {
+ TreeRowKey rowKey = (TreeRowKey) getRowKey();
+ T treeNode = locateTreeNode(rowKey);
+ if (treeNode != null && !nodeAdaptor.isLeaf(treeNode)) {
+ return false;
+ }
+
+ treeNode = treeDataModel.locateTreeNode(rowKey);
+ if (treeNode != null) {
+ return nodeAdaptor.isLeaf(treeNode);
+ }
+
+ return false;
+ }
+
+ public CacheableTreeDataModel(TreeDataModel<T> model) {
+ super(model.getClazz(), model.getNodeAdaptor());
+ setWrappedData(createDefaultNode());
+ setTreeDataModel(model);
+ }
+
+ public void walkModel(FacesContext context, DataVisitor visitor,
+ Range range, Object key, Object argument, boolean last)
+ throws IOException {
+ treeDataModel.walkModel(context, new Visitor(visitor), range, key,
+ argument, last);
+ }
+
+ public void setTreeDataModel(TreeDataModel<T> treeDataModel) {
+ this.treeDataModel = treeDataModel;
+ }
+
+ public TreeDataModel<T> getTreeDataModel() {
+ return treeDataModel;
+ }
+
+ public void walk(FacesContext context, final DataVisitor dataVisitor,
+ Range range, Object rowKey, Object argument, boolean last)
+ throws IOException {
+
+ T cachedTreeNode = locateTreeNode((TreeRowKey) rowKey);
+ T treeNode = treeDataModel.locateTreeNode((TreeRowKey) rowKey);
+
+ if (treeNode != null) {
+ if (cachedTreeNode == null || (nodeAdaptor.isLeaf(cachedTreeNode) &&
!nodeAdaptor.isLeaf(treeNode))) {
+ //fill cache
+ treeDataModel.walk(context, new Visitor(dataVisitor), range,
+ rowKey, argument, last);
+ } else {
+ super.walk(context, dataVisitor, range, rowKey, argument, last);
+ }
+ }
+ }
+
+ public void setTransient(boolean newTransientValue) {
+ if (!newTransientValue) {
+ throw new IllegalArgumentException(
+ "ReplaceableTreeDataModel shouldn't be transient!");
+ }
+ }
+
+ protected abstract void setDefaultNodeData(T node, Object data);
+
+}
Added:
trunk/framework/api/src/main/java/org/richfaces/model/ClassicCacheableTreeDataModel.java
===================================================================
---
trunk/framework/api/src/main/java/org/richfaces/model/ClassicCacheableTreeDataModel.java
(rev 0)
+++
trunk/framework/api/src/main/java/org/richfaces/model/ClassicCacheableTreeDataModel.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -0,0 +1,54 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.model;
+
+/**
+ * {@link CacheableTreeDataModel} implementation for classic {@link TreeNode} instances
+ *
+ * Created 01.11.2007
+ *
+ * @author Nick Belaevski
+ * @since 3.2
+ */
+
+public class ClassicCacheableTreeDataModel extends CacheableTreeDataModel<TreeNode>
{
+
+ public ClassicCacheableTreeDataModel(TreeDataModel<TreeNode> model) {
+ super(model);
+ }
+
+ @Override
+ protected TreeNode createDefaultNode() {
+ return new TreeNodeImpl();
+ }
+
+ @Override
+ protected void setDefaultNodeData(TreeNode node, Object data) {
+ ((TreeNodeImpl) node).setData(data);
+ }
+
+ @Override
+ protected void addChild(TreeNode parent, Object key, TreeNode node) {
+ parent.addChild(key, node);
+ }
+
+}
Modified: trunk/framework/api/src/main/java/org/richfaces/model/ClassicTreeDataModel.java
===================================================================
---
trunk/framework/api/src/main/java/org/richfaces/model/ClassicTreeDataModel.java 2007-11-02
15:43:03 UTC (rev 3725)
+++
trunk/framework/api/src/main/java/org/richfaces/model/ClassicTreeDataModel.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -22,7 +22,10 @@
package org.richfaces.model;
/**
+ * {@link TreeDataModel} implementation for classic {@link TreeNode} instances
+ *
* Created 01.11.2007
+ *
* @author Nick Belaevski
* @since 3.2
*/
@@ -42,4 +45,14 @@
"No tree element available or row key not set!");
}
+ @Override
+ protected void addChild(TreeNode parent, Object key, TreeNode node) {
+ parent.addChild(key, node);
+ }
+
+ @Override
+ protected TreeNode createDefaultNode() {
+ throw new UnsupportedOperationException();
+ }
+
}
Added:
trunk/framework/api/src/main/java/org/richfaces/model/SwingCacheableTreeDataModel.java
===================================================================
---
trunk/framework/api/src/main/java/org/richfaces/model/SwingCacheableTreeDataModel.java
(rev 0)
+++
trunk/framework/api/src/main/java/org/richfaces/model/SwingCacheableTreeDataModel.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -0,0 +1,60 @@
+/**
+ * License Agreement.
+ *
+ * JBoss RichFaces - Ajax4jsf Component Library
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package org.richfaces.model;
+
+import javax.swing.tree.TreeNode;
+
+/**
+ * {@link CacheableTreeDataModel} implementation for Swing {@link TreeNode} instances
+ *
+ * Created 01.11.2007
+ *
+ * @author Nick Belaevski
+ * @since 3.2
+ */
+
+public class SwingCacheableTreeDataModel extends CacheableTreeDataModel<TreeNode>
{
+
+ public SwingCacheableTreeDataModel(TreeDataModel<TreeNode> model) {
+ super(model);
+ }
+
+ @Override
+ protected TreeNode createDefaultNode() {
+ return new SwingTreeNodeImpl();
+ }
+
+ @Override
+ protected void setDefaultNodeData(TreeNode node, Object data) {
+ ((SwingTreeNodeImpl) node).setData(data);
+ }
+
+ @Override
+ protected void addChild(TreeNode parent, Object key, TreeNode node) {
+ SwingTreeNodeImpl parentNode = (SwingTreeNodeImpl) parent;
+ SwingTreeNodeImpl childNode = (SwingTreeNodeImpl) node;
+
+ parentNode.addChild(key, node);
+ childNode.setParent(parentNode);
+ }
+
+}
Modified: trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeDataModel.java
===================================================================
---
trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeDataModel.java 2007-11-02
15:43:03 UTC (rev 3725)
+++
trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeDataModel.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -27,7 +27,10 @@
import javax.swing.tree.TreeNode;
/**
+ * {@link TreeDataModel} implementation for classic {@link TreeNode} instances
+ *
* Created 01.11.2007
+ *
* @author Nick Belaevski
* @since 3.2
*/
@@ -49,21 +52,22 @@
public void setWrappedData(Object data) {
if (data != null) {
SwingTreeNodeImpl treeNodeImpl = new SwingTreeNodeImpl();
+ int counter = 0;
if (data instanceof Collection<?>) {
Collection<?> collection = (Collection<?>) data;
for (Iterator<?> iterator = collection.iterator(); iterator
.hasNext();) {
- treeNodeImpl.addChild((TreeNode) iterator.next());
+ treeNodeImpl.addChild(Integer.valueOf(counter++), (TreeNode) iterator.next());
}
} else if (data.getClass().isArray()) {
Object[] nodes = (Object[]) data;
for (int i = 0; i < nodes.length; i++) {
- treeNodeImpl.addChild((TreeNode) nodes[i]);
+ treeNodeImpl.addChild(Integer.valueOf(counter++), (TreeNode) nodes[i]);
}
} else {
- treeNodeImpl.addChild((TreeNode) data);
+ treeNodeImpl.addChild(Integer.valueOf(counter++), (TreeNode) data);
}
this.treeNode = treeNodeImpl;
@@ -73,13 +77,15 @@
super.setWrappedData(data);
}
-
- /* (non-Javadoc)
- * @see org.richfaces.model.AbstractTreeDataModel#getTreeNode()
- */
+
@Override
- public org.richfaces.model.TreeNode getTreeNode() {
- return null;
+ protected void addChild(TreeNode parent, Object key, TreeNode node) {
+ throw new UnsupportedOperationException();
}
+ @Override
+ protected TreeNode createDefaultNode() {
+ throw new UnsupportedOperationException();
+ }
+
}
Modified: trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeNodeImpl.java
===================================================================
---
trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeNodeImpl.java 2007-11-02
15:43:03 UTC (rev 3725)
+++
trunk/framework/api/src/main/java/org/richfaces/model/SwingTreeNodeImpl.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -21,26 +21,45 @@
package org.richfaces.model;
+import java.util.ArrayList;
import java.util.Enumeration;
-import java.util.Vector;
+import java.util.Iterator;
+import java.util.List;
import javax.swing.tree.TreeNode;
/**
+ * Map-based Swing {@link TreeNode} implementation
+ *
* Created 01.11.2007
+ *
* @author Nick Belaevski
* @since 3.2
*/
public class SwingTreeNodeImpl implements TreeNode {
- private Vector<TreeNode> children = new Vector<TreeNode>();
+ private List<TreeNode> children = new ArrayList<TreeNode>();
+ private TreeNode parent;
+
+ private Object data;
+
/* (non-Javadoc)
* @see javax.swing.tree.TreeNode#children()
*/
public Enumeration children() {
- return children.elements();
+ return new Enumeration() {
+ private Iterator<?> iterator = children.iterator();
+
+ public boolean hasMoreElements() {
+ return iterator.hasNext();
+ }
+
+ public Object nextElement() {
+ return iterator.next();
+ }
+ };
}
/* (non-Javadoc)
@@ -74,16 +93,31 @@
* @see javax.swing.tree.TreeNode#getIndex(javax.swing.tree.TreeNode)
*/
public int getIndex(TreeNode node) {
- return children.indexOf(node);
+ if (node != null) {
+ int counter = 0;
+ for (Iterator<TreeNode> iterator = children.iterator(); iterator.hasNext();) {
+ if (node.equals(iterator.next())) {
+ return counter;
+ }
+
+ counter++;
+ }
+ }
+
+ return -1;
}
/* (non-Javadoc)
* @see javax.swing.tree.TreeNode#getParent()
*/
public TreeNode getParent() {
- return null;
+ return parent;
}
+ public void setParent(TreeNode parent) {
+ this.parent = parent;
+ }
+
/* (non-Javadoc)
* @see javax.swing.tree.TreeNode#isLeaf()
*/
@@ -91,8 +125,20 @@
return children.isEmpty();
}
- public void addChild(TreeNode node) {
- children.add(node);
+ public void addChild(Object key, TreeNode node) {
+ if (Integer.valueOf(children.size()).equals(key)) {
+ children.add(node);
+ } else {
+ throw new IllegalArgumentException();
+ }
}
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
}
Modified: trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModel.java
===================================================================
--- trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModel.java 2007-11-02
15:43:03 UTC (rev 3725)
+++ trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModel.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -45,6 +45,7 @@
private TreeRowKey oldRowKey;
+ private Boolean rowAvailable = Boolean.FALSE;
private T rowTreeData;
protected final TreeDataModelNodeAdaptor<T> nodeAdaptor;
@@ -70,10 +71,12 @@
if (rowKey != null) {
ListRowKey newRowKey = (ListRowKey) rowKey;
this.currentRowKey = newRowKey;
+ this.rowAvailable = null;
} else {
this.currentRowKey = null;
this.oldRowKey = null;
this.rowTreeData = null;
+ this.rowAvailable = Boolean.FALSE;
}
}
@@ -201,9 +204,11 @@
if (childRowTreeData == null) {
if (!allowCreate) {
+ //TODO nick - reset rowTreeData
return null;
} else {
- childRowTreeData = nodeAdaptor.addChild(rowTreeData, pathSegment);
+ childRowTreeData = createDefaultNode();
+ addChild(rowTreeData, pathSegment, childRowTreeData);
}
}
@@ -220,6 +225,10 @@
}
public boolean isRowAvailable() {
+ if (Boolean.FALSE.equals(rowAvailable)) {
+ return false;
+ }
+
T data = locateTreeNode(this.currentRowKey);
if (data != null) {
@@ -273,4 +282,13 @@
protected T getData() {
return clazz.cast(wrappedData);
}
+
+ public TreeNode getTreeNode() {
+ return null;
+ }
+
+ protected abstract T createDefaultNode();
+
+ protected abstract void addChild(T parent, Object key, T node);
+
}
Modified:
trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModelNodeAdaptor.java
===================================================================
---
trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModelNodeAdaptor.java 2007-11-02
15:43:03 UTC (rev 3725)
+++
trunk/framework/api/src/main/java/org/richfaces/model/TreeDataModelNodeAdaptor.java 2007-11-02
16:15:41 UTC (rev 3726)
@@ -29,7 +29,11 @@
import javax.swing.tree.TreeNode;
/**
+ * {@link TreeDataModel} adaptor for generic types. Contains adaptors for Swing &
classic ({@link TreeNode})
+ * tree node types embedded into this interface as static instances
+ *
* Created 01.11.2007
+ *
* @author Nick Belaevski
* @since 3.2
*/
@@ -39,28 +43,18 @@
public boolean isLeaf(T node);
- public T addChild(T node, Object key);
-
public T getChild(T node, Object key);
public Iterator<Map.Entry<Object, T>> getChildren(T node);
public Object getRowData(T node);
- public void setRowData(T node, Object rowData);
-
+ /**
+ * Instance of {@link TreeDataModelNodeAdaptor} for {@link org.richfaces.model.TreeNode}
nodes handling
+ */
public static final TreeDataModelNodeAdaptor<org.richfaces.model.TreeNode>
classicTreeNodeAdaptor =
new TreeDataModelNodeAdaptor<org.richfaces.model.TreeNode>() {
- public org.richfaces.model.TreeNode addChild(org.richfaces.model.TreeNode node,
- Object key) {
- //TODO nick - review implementation usage inside interface
- TreeNodeImpl impl = new TreeNodeImpl();
- node.addChild(key, impl);
-
- return impl;
- }
-
public org.richfaces.model.TreeNode getChild(org.richfaces.model.TreeNode node, Object
key) {
return node.getChild(key);
}
@@ -82,13 +76,11 @@
return node.isLeaf();
}
- public void setRowData(org.richfaces.model.TreeNode node,
- Object rowData) {
- node.setData(rowData);
- }
-
};
+ /**
+ * Instance of {@link TreeDataModelNodeAdaptor} for {@link javax.swing.tree.TreeNode}
nodes handling
+ */
public static final TreeDataModelNodeAdaptor<javax.swing.tree.TreeNode>
swingTreeNodeAdaptor =
new TreeDataModelNodeAdaptor<javax.swing.tree.TreeNode>() {
@@ -119,17 +111,15 @@
};
- public javax.swing.tree.TreeNode addChild(
- javax.swing.tree.TreeNode node, Object key) {
-
- throw new UnsupportedOperationException();
- }
-
public javax.swing.tree.TreeNode getChild(
javax.swing.tree.TreeNode node, Object key) {
- Integer intKey = (Integer) key;
- return node.getChildAt(intKey.intValue());
+ int intKey = ((Integer) key).intValue();
+ if (intKey < node.getChildCount() && intKey >= 0) {
+ return node.getChildAt(intKey);
+ }
+
+ return null;
}
public Iterator<Entry<Object, javax.swing.tree.TreeNode>> getChildren(
@@ -174,10 +164,5 @@
public boolean isLeaf(javax.swing.tree.TreeNode node) {
return !node.getAllowsChildren() || node.isLeaf();
}
-
- public void setRowData(TreeNode node, Object rowData) {
- throw new UnsupportedOperationException();
- }
-
};
}