Skip to content

Instantly share code, notes, and snippets.

@uklance
Last active December 18, 2015 14:18
Show Gist options
  • Save uklance/5795703 to your computer and use it in GitHub Desktop.
Save uklance/5795703 to your computer and use it in GitHub Desktop.
A more database friendly TreeModel implementation
public class LazyTreeModel<T> implements TreeModel<T> {
private final ValueEncoder<T> encoder;
private final LazyTreeModelSource<T> source;
public LazyTreeModel<T>(ValueEncoder<T> encoder, LazyTreeModelSource<T> source) {
this.encoder = encoder;
this.source = source;
}
@Override
public List<TreeNode<T>> getRootNodes() {
List<T> roots = source.getRoots();
return LazyTreeModel.createTreeNodes(encoder, source, roots);
}
@Override
public TreeNode<T> getById(String id) {
return find(encoder.toValue(id));
}
@Override
public TreeNode<T> find(T value) {
return new LazyTreeNode<T>(encoder, source, value);
}
public static List<TreeNode> createTreeNodes(ValueEncoder<T> encoder, LazyTreeModelSource<T> source, List<T> siblings) {
if (siblings == null || siblings.isEmpty()) {
return Collections.emptyList();
}
List<TreeNode> treeNodes = new ArrayList<TreeNode>(siblings.size());
for (T value : siblings) {
treeNodes.add(new LazyTreeNode<T>(encoder, source, value));
}
return treeNodes;
}
}
public interface LazyTreeModelSource<T> {
/**
* Get the label from the value. Note: for efficiency this should be sourced
* directly from the value and should not require an extra database lookup
**/
String getLabel(T value);
/**
* Get the isLeaf flag from the value. Note: for efficiency this should be sourced
* directly from the value and should not require an extra database lookup
**/
boolean isLeaf(T value);
/**
* Get the hasChildren flag from the value. Note: for efficiency this should be sourced
* directly from the value and should not require an extra database lookup
**/
boolean hasChildren(T value);
/**
* Get the children of the value
**/
List<T> getChildren(T value);
/**
* Get the roots of the TreeModel
**/
List<T> getRoots();
}
public class LazyTreeNode<T> implements TreeNode<T> {
private final ValueEncoder<T> encoder;
private final LazyTreeModelSource<T> source;
private final T value;
public LazyTreeNode<T>(ValueEncoder<T> encoder, LazyTreeModelSource<T> source, T value) {
this.encoder = encoder;
this.source = source;
this.value = value;
}
@Override
public T getValue() {
return value;
}
@Override
public String getId() {
return encoder.toClient(value);
}
@Override
public boolean isLeaf() {
return source.isLeaf(value);
}
@Override
public boolean getHasChildren() {
return source.hasChildren(value);
}
@Override
public String getLabel() {
return source.getLabel(value);
}
@Override
public List<TreeNode<T>> getChildren() {
List<T> children = source.getChildren(value);
return LazyTreeModel.createTreeNodes(encoder, source, children);
}
}
@uklance
Copy link
Author

uklance commented Jul 31, 2013

This has been implemented in tapestry-stitch demo here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment