/**
* 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.component;
import java.io.IOException;
import javax.faces.context.FacesContext;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.Range;
import org.richfaces.model.LastElementAware;
import org.richfaces.model.TreeDataModel;
import org.richfaces.model.TreeNode;
import org.richfaces.model.TreeNodeImpl;
import org.richfaces.model.TreeRowKey;
/**
* @author Nick - mailto:nbelaevski@exadel.com created 08.01.2007
*
*/
public class CacheableTreeDataModel extends TreeDataModel {
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);
locateTreeNode(treeRowKey, true).setData(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 treeDataModel;
public boolean isLeaf() {
TreeRowKey rowKey = (TreeRowKey) getRowKey();
TreeNode treeNode = locateTreeNode(rowKey);
if (treeNode != null && !treeNode.isLeaf()) {
return false;
}
treeNode = treeDataModel.locateTreeNode(rowKey);
if (treeNode != null) {
return treeNode.isLeaf();
}
return false;
}
public CacheableTreeDataModel(TreeDataModel model) {
super();
setWrappedData(new TreeNodeImpl());
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 treeDataModel) {
this.treeDataModel = treeDataModel;
}
public TreeDataModel getTreeDataModel() {
return treeDataModel;
}
public void walk(FacesContext context, final DataVisitor dataVisitor,
Range range, Object rowKey, Object argument, boolean last)
throws IOException {
TreeNode cachedTreeNode = locateTreeNode((TreeRowKey) rowKey);
TreeNode treeNode = treeDataModel.locateTreeNode((TreeRowKey) rowKey);
if (treeNode != null) {
if (cachedTreeNode == null || (cachedTreeNode.isLeaf() && !treeNode.isLeaf())) {
//fill cache
treeDataModel.walk(context, new Visitor(dataVisitor), range,
rowKey, argument, last);
} else {
super.walk(context, dataVisitor, range, rowKey, argument, last);
}
}
}
public void setRowData(Object object) {
(locateTreeNode((TreeRowKey)getRowKey())).setData(object);
}
public boolean isTransient() {
return true;
}
public void setTransient(boolean newTransientValue) {
if (!newTransientValue) {
throw new IllegalArgumentException(
"ReplaceableTreeDataModel shouldn't be transient!");
}
}
}