package yuku.atree;
import java.io.*;
public class TreePath implements Serializable {
private TreeNode[] elements;
private TreePath parent;
private final int pathCount;
public TreePath(final TreeNode[] path) {
pathCount = path.length;
elements = new TreeNode[pathCount];
System.arraycopy(path, 0, elements, 0, pathCount);
parent = null;
}
public TreePath(final TreeNode singlePath) {
elements = new TreeNode[] {singlePath};
pathCount = 1;
parent = null;
}
protected TreePath() {
elements = new TreeNode[] {null};
pathCount = 1;
parent = null;
}
protected TreePath(final TreeNode[] path, final int length) {
pathCount = length;
elements = new TreeNode[pathCount];
System.arraycopy(path, 0, elements, 0, pathCount);
parent = null;
}
protected TreePath(final TreePath parentPath, final TreeNode lastElement) {
elements = new TreeNode[] {lastElement};
parent = parentPath;
pathCount = (parent != null) ? parent.getPathCount() + 1 : 1;
}
@Override public boolean equals(final Object o) {
if (!(o instanceof TreePath)) {
return false;
}
TreePath path = (TreePath)o;
final int numPathComponents = getPathCount();
if (path.getPathCount() != numPathComponents) {
return false;
}
for (int i = 0; i < numPathComponents; i++) {
if (!path.getPathComponent(i).equals(getPathComponent(i))) {
return false;
}
}
return true;
}
public TreeNode getLastPathComponent() {
return elements[elements.length - 1];
}
public TreePath getParentPath() {
if (parent != null) {
return parent;
}
int numParentPaths = getPathCount() - 1;
if (numParentPaths <= 0) {
return null;
}
return new TreePath(getPath(), numParentPaths);
}
public TreeNode[] getPath() {
if (parent == null) {
return elements;
}
TreeNode[] parentPath = parent.getPath();
TreeNode[] result = new TreeNode[parentPath.length + 1];
System.arraycopy(parentPath, 0, result, 0, parentPath.length);
result[result.length - 1] = getLastPathComponent();
elements = result.clone();
parent = null;
return result;
}
public TreeNode getPathComponent(final int element) {
final int pathCount = getPathCount();
if (element < 0 || element >= pathCount) {
throw new IllegalArgumentException("element index out of bounds"); //$NON-NLS-1$
}
if (parent == null) {
return elements[element];
}
return (element < pathCount - 1) ? parent.getPathComponent(element) :
getLastPathComponent();
}
public int getPathCount() {
return pathCount;
}
public boolean isDescendant(final TreePath child) {
if (child == null) {
return false;
}
final int numPathComponents = getPathCount();
if (child.getPathCount() < numPathComponents) {
return false;
}
for (int i = 0; i < numPathComponents; i++) {
if (!child.getPathComponent(i).equals(getPathComponent(i))) {
return false;
}
}
return true;
}
public TreePath pathByAddingChild(final TreeNode child) {
return new TreePath(this, child);
}
@Override public int hashCode() {
return getLastPathComponent().hashCode();
}
@Override public String toString() {
String result = null;
final int numPathComponents = getPathCount();
for (int i = 0; i < numPathComponents; i++) {
if (result != null) {
result += ", ";
} else {
result = "";
}
result += getPathComponent(i);
}
return "[" + result + "]";
}
}