All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nutz.lang.util.SimpleNode Maven / Gradle / Ivy

Go to download

Nutz, which is a collections of lightweight frameworks, each of them can be used independently

There is a newer version: 1.r.72
Show newest version
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 implements Node {

    public SimpleNode() {}

    private T obj;
    private SimpleNode parent;
    private SimpleNode prev;
    private SimpleNode next;
    private SimpleNode firstChild;
    private SimpleNode lastChild;

    public T get() {
        return obj;
    }

    public Node set(T obj) {
        this.obj = obj;
        return this;
    }

    public Node parent() {
        return parent;
    }

    public Node top() {
        if (null == parent)
            return this;
        return parent.top();
    }

    public Node prev() {
        return prev;
    }

    public Node prev(Node node) {
        SimpleNode nd = (SimpleNode) node;
        this.prev = nd;
        nd.next = this;
        nd.parent = parent;
        return this;
    }

    public Node next() {
        return next;
    }

    public Node next(Node node) {
        SimpleNode nd = (SimpleNode) 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> parents() {
        LinkedList> list = new LinkedList>();
        Node me = parent;
        while (me != null) {
            list.addFirst(me);
            me = me.parent();
        }
        return list;
    }

    public List> getAncestors() {
        List> list = new LinkedList>();
        Node me = parent;
        while (me != null) {
            list.add(me);
            me = me.parent();
        }
        return list;
    }

    public int depth() {
        int re = 0;
        Node nd = this;
        while (null != nd.parent()) {
            re++;
            nd = nd.parent();
        }
        return re;
    }

    public List> getNextSibling() {
        List> list = new LinkedList>();
        Node me = next;
        while (me != null) {
            list.add(me);
            me = me.next();
        }
        return list;
    }

    public List> getPrevSibling() {
        List> list = new LinkedList>();
        Node me = prev;
        while (me != null) {
            list.add(me);
            me = me.prev();
        }
        return list;
    }

    public int index() {
        return getPrevSibling().size();
    }

    public List> getChildren() {
        List> list = new LinkedList>();
        if (null != firstChild) {
            list.add(firstChild);
            list.addAll(firstChild.getNextSibling());
        }
        return list;
    }

    public int countChildren() {
        int re = 0;
        if (null != firstChild) {
            Node me = firstChild;
            while (me != null) {
                re++;
                me = me.next();
            }
        }
        return re;
    }

    public boolean hasChild() {
        return null != firstChild;
    }

    public Node firstChild() {
        return firstChild;
    }

    public Node lastChild() {
        return lastChild;
    }

    public Node parent(Node node) {
        parent = (SimpleNode) node;
        node.add(this);
        return this;
    }

    public Node clearChildren() {
        firstChild = null;
        lastChild = null;
        return this;
    }

    @SuppressWarnings("unchecked")
    public Node add(Node... nodes) {
        if (nodes.length == 0) {
            return this;
        }
        if (nodes.length == 1) {
            SimpleNode node = (SimpleNode) 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 theNode = (SimpleNode) nodes[0];
            theNode.parent = this;
            theNode.next = (SimpleNode) nodes[1];
            // 加入子节点链表
            if (null == lastChild) {
                firstChild = theNode;
            } else {
                lastChild.next = theNode;
            }
            // 循环添加
            int i = 1;
            for (; i < nodes.length - 1; i++) {
                SimpleNode node = (SimpleNode) nodes[i];
                node.parent = this;
                node.prev = (SimpleNode) nodes[i - 1];
                node.next = (SimpleNode) nodes[i + 1];
            }
            lastChild = (SimpleNode) nodes[i];
            lastChild.parent = this;
            lastChild.prev = (SimpleNode) nodes[i - 1];

        }
        return this;
    }

    public Node addFirst(Node node) {
        ((SimpleNode) node).parent = this;
        if (!this.hasChild()) {
            firstChild = (SimpleNode) node;
            lastChild = (SimpleNode) node;
            ((SimpleNode) node).next = null;
            ((SimpleNode) node).prev = null;
        } else {
            firstChild.prev = (SimpleNode) node;
            ((SimpleNode) node).next = firstChild;
            ((SimpleNode) node).prev = null;
            firstChild = (SimpleNode) node;
        }
        return this;
    }

    public Node child(int index) {
        if (hasChild())
            return firstChild.next(index);
        return null;
    }

    @SuppressWarnings("unchecked")
    public > void eachChild(Each callback) {
        SimpleNode 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 desc(int... indexes) {
        Node me = this;
        for (int i : indexes) {
            if (!me.hasChild())
                return null;
            me = me.firstChild().next(i);
        }
        return me;
    }

    public Node next(int index) {
        if (index < 0)
            return null;
        Node me = this;
        while (index > 0 && me != null) {
            index--;
            me = me.next();
        }
        if (index > 0)
            return null;
        return me;
    }

    public Node prev(int index) {
        Node me = this;
        while (index > 0 && me != null) {
            index--;
            me = me.prev();
        }
        return me;
    }

    public Node insertBefore(int index, Node node) {
        SimpleNode me = (SimpleNode) child(index);
        if (null != me) {
            ((SimpleNode) node).next = me;
            ((SimpleNode) node).prev = me.prev;
            me.prev.next = (SimpleNode) node;
            me.prev = (SimpleNode) node;
            ((SimpleNode) node).parent = this;
            if (firstChild == me)
                firstChild = (SimpleNode) node;
        }
        return this;
    }

    public Node pop() {
        if (!hasChild())
            return null;
        SimpleNode re = lastChild;
        lastChild = lastChild.prev;
        if (null == lastChild)
            firstChild = null;
        else
            lastChild.next = null;

        re.prev = null;
        re.next = null;
        return re;
    }

    public Node popFirst() {
        if (!hasChild())
            return null;
        SimpleNode re = firstChild;
        firstChild = firstChild.next;
        if (null == firstChild)
            lastChild = null;
        else
            firstChild.prev = null;

        re.prev = null;
        re.next = null;
        return re;
    }

    public Node removeChild(int index) {
        if (hasChild()) {
            SimpleNode node = (SimpleNode) 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 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 implements Iterator> {

        private Node root;
        private Node node;

        InnerIterator(Node node) {
            this.root = node;
            if (root.hasChild())
                this.node = root.child(0);
            else
                this.node = root;
        }

        public boolean hasNext() {
            return node != root;
        }

        public Node next() {
            if (node == root)
                return null;
            Node 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> iterator() {
        return new InnerIterator(this);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy