package org.nutz.lang.util; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.nutz.lang.Each; import org.nutz.lang.Lang; import org.nutz.lang.Strings; public class SimpleNode<T> implements Node<T> { public SimpleNode() {} private T obj; private SimpleNode<T> parent; private SimpleNode<T> prev; private SimpleNode<T> next; private SimpleNode<T> firstChild; private SimpleNode<T> lastChild; public T get() { return obj; } public Node<T> set(T obj) { this.obj = obj; return this; } public Node<T> parent() { return parent; } public Node<T> top() { if (null == parent) return this; return parent.top(); } public Node<T> prev() { return prev; } public Node<T> prev(Node<T> node) { SimpleNode<T> nd = (SimpleNode<T>) node; this.prev = nd; nd.next = this; nd.parent = parent; return this; } public Node<T> next() { return next; } public Node<T> next(Node<T> node) { SimpleNode<T> nd = (SimpleNode<T>) node; this.next = nd; nd.prev = this; nd.parent = this; return this; } public boolean isRoot() { return null == parent; } public boolean isLast() { return null == next; } public boolean isFirst() { return null == prev; } public List<Node<T>> parents() { LinkedList<Node<T>> list = new LinkedList<Node<T>>(); Node<T> me = parent; while (me != null) { list.addFirst(me); me = me.parent(); } return list; } public List<Node<T>> getAncestors() { List<Node<T>> list = new LinkedList<Node<T>>(); Node<T> me = parent; while (me != null) { list.add(me); me = me.parent(); } return list; } public int depth() { int re = 0; Node<T> nd = this; while (null != nd.parent()) { re++; nd = nd.parent(); } return re; } public List<Node<T>> getNextSibling() { List<Node<T>> list = new LinkedList<Node<T>>(); Node<T> me = next; while (me != null) { list.add(me); me = me.next(); } return list; } public List<Node<T>> getPrevSibling() { List<Node<T>> list = new LinkedList<Node<T>>(); Node<T> me = prev; while (me != null) { list.add(me); me = me.prev(); } return list; } public int index() { return getPrevSibling().size(); } public List<Node<T>> getChildren() { List<Node<T>> list = new LinkedList<Node<T>>(); if (null != firstChild) { list.add(firstChild); list.addAll(firstChild.getNextSibling()); } return list; } public int countChildren() { int re = 0; if (null != firstChild) { Node<T> me = firstChild; while (me != null) { re++; me = me.next(); } } return re; } public boolean hasChild() { return null != firstChild; } public Node<T> firstChild() { return firstChild; } public Node<T> lastChild() { return lastChild; } public Node<T> parent(Node<T> node) { parent = (SimpleNode<T>) node; node.add(this); return this; } public Node<T> clearChildren() { firstChild = null; lastChild = null; return this; } @SuppressWarnings("unchecked") public Node<T> add(Node<?>... nodes) { if (nodes.length == 0) { return this; } if (nodes.length == 1) { SimpleNode<T> node = (SimpleNode<T>) nodes[0]; node.parent = this; if (!this.hasChild()) { firstChild = node; lastChild = node; node.next = null; node.prev = null; } else { lastChild.next = node; node.prev = lastChild; node.next = null; lastChild = node; } } else { SimpleNode<T> theNode = (SimpleNode<T>) nodes[0]; theNode.parent = this; theNode.next = (SimpleNode<T>) nodes[1]; // 加入子节点链表 if (null == lastChild) { firstChild = theNode; } else { lastChild.next = theNode; } // 循环添加 int i = 1; for (; i < nodes.length - 1; i++) { SimpleNode<T> node = (SimpleNode<T>) nodes[i]; node.parent = this; node.prev = (SimpleNode<T>) nodes[i - 1]; node.next = (SimpleNode<T>) nodes[i + 1]; } lastChild = (SimpleNode<T>) nodes[i]; lastChild.parent = this; lastChild.prev = (SimpleNode<T>) nodes[i - 1]; } return this; } public Node<T> addFirst(Node<T> node) { ((SimpleNode<T>) node).parent = this; if (!this.hasChild()) { firstChild = (SimpleNode<T>) node; lastChild = (SimpleNode<T>) node; ((SimpleNode<T>) node).next = null; ((SimpleNode<T>) node).prev = null; } else { firstChild.prev = (SimpleNode<T>) node; ((SimpleNode<T>) node).next = firstChild; ((SimpleNode<T>) node).prev = null; firstChild = (SimpleNode<T>) node; } return this; } public Node<T> child(int index) { if (hasChild()) return firstChild.next(index); return null; } @SuppressWarnings("unchecked") public <E extends Node<T>> void eachChild(Each<E> callback) { SimpleNode<T> nd = firstChild; int i = 0; while (nd != null) { callback.invoke(i++, (E) nd, -1); nd = nd.next; if (nd == firstChild) throw Lang.makeThrow("If i am here, tell me -_-!"); } } public Node<T> desc(int... indexes) { Node<T> me = this; for (int i : indexes) { if (!me.hasChild()) return null; me = me.firstChild().next(i); } return me; } public Node<T> next(int index) { if (index < 0) return null; Node<T> me = this; while (index > 0 && me != null) { index--; me = me.next(); } if (index > 0) return null; return me; } public Node<T> prev(int index) { Node<T> me = this; while (index > 0 && me != null) { index--; me = me.prev(); } return me; } public Node<T> insertBefore(int index, Node<T> node) { SimpleNode<T> me = (SimpleNode<T>) child(index); if (null != me) { ((SimpleNode<T>) node).next = me; ((SimpleNode<T>) node).prev = me.prev; me.prev.next = (SimpleNode<T>) node; me.prev = (SimpleNode<T>) node; ((SimpleNode<T>) node).parent = this; if (firstChild == me) firstChild = (SimpleNode<T>) node; } return this; } public Node<T> pop() { if (!hasChild()) return null; SimpleNode<T> re = lastChild; lastChild = lastChild.prev; if (null == lastChild) firstChild = null; else lastChild.next = null; re.prev = null; re.next = null; return re; } public Node<T> popFirst() { if (!hasChild()) return null; SimpleNode<T> re = firstChild; firstChild = firstChild.next; if (null == firstChild) lastChild = null; else firstChild.prev = null; re.prev = null; re.next = null; return re; } public Node<T> removeChild(int index) { if (hasChild()) { SimpleNode<T> node = (SimpleNode<T>) child(index); if (null == node) return null; else if (node.isLast()) return pop(); else if (node.isFirst()) return popFirst(); node.next.prev = node.prev; node.prev.next = node.next; node.prev = null; node.next = null; return node; } return null; } public boolean remove() { int i = getIndex(); if (i < 0) return false; parent.removeChild(i); return true; } public int getIndex() { if (parent == null) return -1; int i = 0; Node<T> n = parent.firstChild(); while (n != parent.child(i)) { i++; } return i; } public String toString() { StringBuilder sb = new StringBuilder(); appendTo(this, sb, 0); return sb.toString(); } static void appendTo(Node<?> node, StringBuilder sb, int depth) { sb.append(Strings.dup(" ", depth)) .append(node.get() == null ? "NULL" : node.get().toString()); Node<?> chd = node.firstChild(); while (chd != null) { sb.append('\n'); appendTo(chd, sb, depth + 1); chd = chd.next(); } } static class InnerIterator<T> implements Iterator<Node<T>> { private Node<T> root; private Node<T> node; InnerIterator(Node<T> node) { this.root = node; if (root.hasChild()) this.node = root.child(0); else this.node = root; } public boolean hasNext() { return node != root; } public Node<T> next() { if (node == root) return null; Node<T> re = node; if (node.hasChild()) { node = node.firstChild(); } else if (!node.isLast()) { node = node.next(); } else { while (node.isLast() && !node.isRoot()) { node = node.parent(); } if (!node.isRoot()) node = node.next(); } return re; } public void remove() { throw Lang.makeThrow("No implement yet!"); } } public Iterator<Node<T>> iterator() { return new InnerIterator<T>(this); } }