Android Open Source - Cafe Tree Node






From Project

Back to project page Cafe.

License

The source code is released under:

Apache License

If you think the Android project Cafe listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2011 Baidu.com Inc/*from www  .  j  av  a 2  s.  c  om*/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.baidu.cafe.utils;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

/*
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
*/

/**
 * a muti-node tree is not thread-safe
 * 
 * @author luxiaoyu01@baidu.com
 * @date 2011-5-13
 * @version
 * @todo
 */
public class TreeNode<T> {
    public static String           vertical       = null;
    public static String           horizontal     = null;
    public static String           big_horizontal = null;
    public static String           vertical_T     = null;
    public static String           horizontal_T   = null;
    public static String           left           = null;

    private T                      data           = null;
    private int                    index          = -1;
    private TreeNode<T>            parent         = null;
    private ArrayList<TreeNode<T>> children       = null;

    // load string to avoid to compile unicode 
    static {
//        try {
//            Document doc = new SAXReader().read(new FileInputStream(new File("res/strings.xml")));
//            Element rootElement = doc.getRootElement();
//            List<Element> strings = rootElement.elements("string");
//            vertical = strings.get(0).getStringValue();
//            horizontal = strings.get(1).getStringValue();
//            big_horizontal = strings.get(2).getStringValue();
//            vertical_T = strings.get(3).getStringValue();
//            horizontal_T = strings.get(4).getStringValue();
//            left = strings.get(5).getStringValue();
//        } catch (FileNotFoundException e) {
            vertical = "|";
            horizontal = "-";
            big_horizontal = "--";
            vertical_T = "T";
            horizontal_T = "|-";
            left = "'-";
            //e.printStackTrace();
//        } catch (DocumentException e) {
//            e.printStackTrace();
//        }
    }

    @Override
    public String toString() {
        return data.toString();
    }

    public TreeNode(T data) {
        this.data = data;
        this.children = new ArrayList<TreeNode<T>>();
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public int getIndex() {
        return index;
    }

    public TreeNode<T> getParent() {
        return parent;
    }

    public ArrayList<TreeNode<T>> getBrothers() {
        ArrayList<TreeNode<T>> brothers = new ArrayList<TreeNode<T>>();
        if (parent != null) {
            for (TreeNode<T> child : parent.getChildren()) {
                if (!child.equals(this)) {
                    brothers.add(child);
                }
            }
        }

        return brothers;
    }

    public ArrayList<TreeNode<T>> getChildren() {
        return children;
    }

    public void addChild(TreeNode<T> child) {
        child.index = children.size();
        children.add(child);
        child.parent = this;
    }

    public void addChildren(ArrayList<TreeNode<T>> children) {
        for (TreeNode<T> child : children) {
            addChild(child);
        }
    }

    public void removeChild(TreeNode<T> node) {
        int childrenSize = children.size();
        for (int i = 0; i < childrenSize; i++) {
            if (children.get(i) == node) {
                children.remove(i);
            }
        }
    }

    private void insertFrontWhitespace(TreeNode<T> root, TreeNode<T> node, StringBuffer sb) {
        int number = 2 + node.parent.data.toString().length();
        for (int i = 0; i < number; i++) {
            sb.append(" ");
        }
        if (node.parent == root) {
            return;
        }
        sb.append(vertical);
        insertFrontWhitespace(root, node.parent, sb);
    }

    private void drawFamily(StringBuffer sb, TreeNode<T> root) {
        int childrenSize = children.size();

        // draw itself
        sb.append(horizontal + data);
        if (childrenSize == 0) {
            sb.append("\n");
            return;
        }

        // draw the first child
        if (childrenSize == 1) {
            sb.append(big_horizontal);
        } else {
            sb.append(vertical_T);
        }
        children.get(0).drawFamily(sb, root);

        // draw middle children
        int i = 1;
        for (; i < childrenSize - 1; i++) {
            StringBuffer t = new StringBuffer();
            insertFrontWhitespace(root, children.get(i), t);
            sb.append(t.reverse());
            sb.append(horizontal_T);
            children.get(i).drawFamily(sb, root);
        }

        // draw the last child
        if (childrenSize > 1) {
            StringBuffer t = new StringBuffer();
            insertFrontWhitespace(root, children.get(i), t);
            sb.append(t.reverse());
            sb.append(left);
            children.get(i).drawFamily(sb, root);
        }
    }

    public String drawTree() {
        StringBuffer sb = new StringBuffer(1024 * 10);
        drawFamily(sb, this);
        return sb.toString();
    }

    public interface NodeCallBack<T> {
        void doSomething(TreeNode<T> node, int depth);

        boolean shouldRepeat(TreeNode<T> node);

        void doWhenCompleted(TreeNode<T> node, int depth);

        boolean shouldStop(TreeNode<T> node);
    }

    /**
     * travel the tree with preorder and do something at every tree node
     * 
     * @param callBack
     * @param maxDepth
     *            the depth of root is 1
     * @return should continue
     */
    public boolean preorderTraversal(NodeCallBack<T> callBack, int maxDepth) {
        if (callBack.shouldStop(this)) {
            return false;
        }

        callBack.doSomething(this, maxDepth);

        if (maxDepth > 0) {
            for (int i = 0; i < children.size(); i++) {
                TreeNode<T> child = children.get(i);
                if (!child.preorderTraversal(callBack, maxDepth - 1)) {
                    return false;
                }
                if (callBack.shouldRepeat(this)) {
                    //Logger.println("Repeat: " + this.data.toString());
                    callBack.doSomething(this, maxDepth);
                }
            }
        }

        callBack.doWhenCompleted(this, maxDepth);
        return true;
    }

    public void breadthFirstTraversal(NodeCallBack<T> callBack, int maxDepth) {
        Queue<TreeNode<T>> queue = new LinkedList<TreeNode<T>>();
        queue.offer(this);
        while (queue.size() != 0) {
            TreeNode<T> head = queue.poll();
            if (countDistance(head, this) > maxDepth - 1) {
                break;
            }
            callBack.doSomething(head, maxDepth);
            for (int i = 0; i < head.children.size(); i++) {
                queue.offer(head.children.get(i));
            }
            //            printQueue(queue);
        }
    }

    private int countDistance(final TreeNode<T> child, TreeNode<T> ancestor) {
        int distance = 0;
        TreeNode<T> node = child;
        while (node != ancestor) {
            node = node.getParent();
            distance++;
        }
        return distance;
    }

    private void printQueue(Queue<TreeNode<T>> queue) {
        //        System.out.println("******************* print queue *********************");
        for (TreeNode<T> node : queue) {
            System.out.println(node);
        }
    }

    public static void main(String[] args) {
        //      Map map = new HashMap();
        //      Iterator iter = map.entrySet().iterator();
        //      while (iter.hasNext()) {
        //          Entry entry = (Entry) iter.next();
        //          Object key = entry.getKey();
        //          Object val = entry.getValue();
        //      }

        TreeNode<String> root = new TreeNode<String>("0");
        TreeNode<String> node1 = new TreeNode<String>("1");
        TreeNode<String> node2 = new TreeNode<String>("22");
        TreeNode<String> node3 = new TreeNode<String>("333");
        TreeNode<String> node4 = new TreeNode<String>("4444");
        TreeNode<String> node5 = new TreeNode<String>("55555");
        TreeNode<String> node6 = new TreeNode<String>("666666");
        TreeNode<String> node7 = new TreeNode<String>("7777777");
        TreeNode<String> node8 = new TreeNode<String>("88888888");
        TreeNode<String> node9 = new TreeNode<String>("999999999");
        root.addChild(node1);
        root.addChild(node2);
        root.addChild(node7);
        node1.addChild(node3);
        node1.addChild(node4);
        node2.addChild(node5);
        node2.addChild(node6);
        node4.addChild(node8);

        // test draw tree
        System.out.println(root.drawTree());
        System.out.println(node1.drawTree());
        System.out.println(node4.drawTree());
        System.out.println(node7.drawTree());

        System.out.println("test remove child");
        node1.removeChild(node4);
        System.out.println(root.drawTree());

        System.out.println("test preorderTraversal");
        node1.addChild(node4);
        node8.addChild(node9);
        System.out.println(root.drawTree());
        root.preorderTraversal(new NodeCallBack<String>() {

            @Override
            public void doSomething(TreeNode<String> node, int maxDepth) {
                System.out.print(node.getData() + "(" + (3 - maxDepth) + "), ");
            }

            @Override
            public void doWhenCompleted(TreeNode<String> node, int maxDepth) {

            }

            @Override
            public boolean shouldRepeat(TreeNode<String> node) {
                return false;
            }

            @Override
            public boolean shouldStop(TreeNode<String> node) {
                return "55555".equals(node.getData());
            }
        }, 3);
        System.out.println("");

        System.out.println("test getBrothers");
        ArrayList<TreeNode<String>> brothers = node1.getBrothers();
        for (TreeNode<String> brother : brothers) {
            System.out.print(brother.getData() + ", ");
        }
        System.out.println("");

        System.out.println("test breadthFirstTraversal");
        System.out.println(root.drawTree());
        root.breadthFirstTraversal(new NodeCallBack<String>() {

            @Override
            public boolean shouldRepeat(TreeNode<String> node) {
                return false;
            }

            @Override
            public void doSomething(TreeNode<String> node, int maxDepth) {
                System.out.print(node.getData() + ", ");
            }

            @Override
            public void doWhenCompleted(TreeNode<String> node, int depth) {
            }

            @Override
            public boolean shouldStop(TreeNode<String> node) {
                return false;
            }
        }, 2);
        System.out.println("");
    }

}




Java Source Code List

com.baidu.cafe.CafeExceptionHandler.java
com.baidu.cafe.CafeListener.java
com.baidu.cafe.CafeServiceTestCase.java
com.baidu.cafe.CafeTestCase.java
com.baidu.cafe.CafeTestRunner.java
com.baidu.cafe.TearDownHelper.java
com.baidu.cafe.local.DESEncryption.java
com.baidu.cafe.local.FPSTracer.java
com.baidu.cafe.local.FileUtils.java
com.baidu.cafe.local.LocalLib.java
com.baidu.cafe.local.Log.java
com.baidu.cafe.local.NetworkUtils.java
com.baidu.cafe.local.SnapshotHelper.java
com.baidu.cafe.local.record.CafeWebViewClient.java
com.baidu.cafe.local.record.OutputEvent.java
com.baidu.cafe.local.record.ViewRecorderSDK.java
com.baidu.cafe.local.record.ViewRecorder.java
com.baidu.cafe.local.record.WebElementRecorder.java
com.baidu.cafe.local.traveler.APPTraveler.java
com.baidu.cafe.local.traveler.Logger.java
com.baidu.cafe.local.traveler.Operation.java
com.baidu.cafe.local.traveler.Util.java
com.baidu.cafe.local.traveler.ViewHelper.java
com.baidu.cafe.remote.ArmsBinder.java
com.baidu.cafe.remote.ArmsBootupReceiver.java
com.baidu.cafe.remote.Arms.java
com.baidu.cafe.remote.Armser.java
com.baidu.cafe.remote.BatteryState.java
com.baidu.cafe.remote.LockActivity.java
com.baidu.cafe.remote.Log.java
com.baidu.cafe.remote.MonkeyNetwork.java
com.baidu.cafe.remote.MyIntent.java
com.baidu.cafe.remote.SystemLib.java
com.baidu.cafe.remote.UILib.java
com.baidu.cafe.remote.ViewPropertyProvider.java
com.baidu.cafe.utils.CommandResult.java
com.baidu.cafe.utils.ReflectHelper.java
com.baidu.cafe.utils.ShellExecute.java
com.baidu.cafe.utils.Strings.java
com.baidu.cafe.utils.TreeNode.java