package com.hawkbrowser.base;
import java.util.ArrayList;
import java.util.List;
import android.util.Log;
public class Tree<T> {
private Node<T> mRoot;
public interface FindMatcher {
boolean isMatch(Object l, Object r);
}
public interface Iterator {
void iterate(Object l, Object r);
}
public Tree(T rootData) {
mRoot = new Node<T>(rootData);
}
public static class Node<T> {
private T mData;
private Node<T> mParent;
private List<Node<T>> mChildren;
public Node(T data) {
mData = data;
mParent = null;
}
public Node(T data, Node<T> parent) {
mData = data;
mParent = parent;
mChildren = null;
}
public List<Node<T>> children() {
return mChildren;
}
public T data() {
return mData;
}
}
public Node<T> root() {
return mRoot;
}
public Node<T> find(T data) {
return find(mRoot, data);
}
public void iterate(Object arg, Iterator iter) {
if(null != iter) {
iterate(mRoot, arg, iter);
}
}
public void iterate(Node<T> node, Object arg, Iterator iter) {
iter.iterate(node.mData, arg);
if(null != node.mChildren) {
for(Node<T> child : node.mChildren) {
iterate(child, arg, iter);
}
}
}
public Node<T> find(T data, FindMatcher matcher) {
return find(mRoot, data, matcher);
}
public boolean add(Node<T> parent, T data) {
Log.d("Tree", String.format("parent is %s; data is %s",
null == parent ? "null" : parent.toString(),
null == data ? "null" : data.toString()));
if(null == data || null != find(data)) {
return false;
}
if(null == parent) {
parent = mRoot;
}
if(null == parent.mChildren) {
parent.mChildren = new ArrayList<Node<T>>();
}
Log.d("Tree", String.format("add data: %s", data.toString()));
parent.mChildren.add(new Node<T>(data));
return true;
}
public boolean remove(Node<T> node) {
if(null == node.mParent) {
return false;
}
node.mParent.mChildren.remove(node);
return true;
}
private Node<T> find(Node<T> node, T data, FindMatcher matcher) {
if(matcher.isMatch(node.mData, data)) {
return node;
}
if(null != node.mChildren) {
for(Node<T> child : node.mChildren) {
if(null != find(child, data, matcher)) {
return child;
}
}
}
return null;
}
private Node<T> find(Node<T> node, T data) {
if((null != node.mData) && node.mData.equals(data)) {
return node;
}
if(null != node.mChildren) {
for(Node<T> child : node.mChildren) {
if(null != find(child, data)) {
return child;
}
}
}
return null;
}
}