package net.pechorina.kontempl.data; import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author vp */ public class GenericTreeNode<T> { static final Logger logger = LoggerFactory.getLogger(GenericTreeNode.class); private T data; private int items; private List<GenericTreeNode<T>> children; private GenericTreeNode<T> parent; public GenericTreeNode() { super(); children = new ArrayList<>(); items = 0; } public GenericTreeNode(T data) { this(); setData(data); } public List<GenericTreeNode<T>> getChildren() { return children; } public void setChildren(List<GenericTreeNode<T>> children) { for (GenericTreeNode<T> child : children) { child.parent = this; } this.children = children; } public T getData() { return data; } public void setData(T data) { this.data = data; } public GenericTreeNode<T> getParent() { return parent; } public void setParent(GenericTreeNode<T> parent) { this.parent = parent; } public int getItems() { return items; } public void setItems(int items) { this.items = items; } public int getNumberOfChildren() { return getChildren().size(); } public boolean hasChildren() { return (getNumberOfChildren() > 0); } public void addChild(GenericTreeNode<T> child) { child.parent = this; children.add(child); } public void addChildAt(int index, GenericTreeNode<T> child) throws IndexOutOfBoundsException { child.parent = this; children.add(index, child); } public void removeChildren() { this.children = new ArrayList<>(); } public void removeChildAt(int index) throws IndexOutOfBoundsException { children.remove(index); } public List<GenericTreeNode<T>> traceParents() { //logger.debug("traceParents"); List <GenericTreeNode<T>> parents = new ArrayList<>(); boolean reachedRoot = false; int maxIterations = 100; int i = 0; GenericTreeNode<T> currentNode = this; while (!reachedRoot) { i++; //logger.debug("Iteration: " + i); if (i > maxIterations) { logger.warn("Too deep recursion, breaking"); break; } GenericTreeNode<T> p = currentNode.getParent(); if (p != null) { //logger.debug("Adding parent: " + p.getData().toString()); parents.add(p); currentNode = p; } else { //logger.debug("this node is a root node: " + currentNode.getData().toString()); reachedRoot = true; } } return parents; } public GenericTreeNode<T> getChildAt(int index) throws IndexOutOfBoundsException { return children.get(index); } @Override public String toString() { return getData().toString(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } GenericTreeNode<?> other = (GenericTreeNode<?>) obj; if (data == null) { if (other.data != null) { return false; } } else if (!data.equals(other.data)) { return false; } return true; } @Override public int hashCode() { int hash = 7; hash = 67 * hash + (this.data != null ? this.data.hashCode() : 0); hash = 67 * hash + (this.children != null ? this.children.hashCode() : 0); return hash; } }