DOMTreeFull.java Source code

Java tutorial

Introduction

Here is the source code for DOMTreeFull.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

import java.io.Serializable;
import java.util.Hashtable;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;

import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Notation;

/**
 * DOMTree class to enter every DOM node into a Swing JTree tree. The forward
 * and backward mappings between Nodes to TreeNodes are kept.
 * 
 * @version $Id: DOMTreeFull.java 447689 2006-09-19 02:40:36Z mrglavas $
 */
public class DOMTreeFull extends JTree {

    private static final long serialVersionUID = 3978144335541975344L;

    //
    // Constructors
    //

    /** Default constructor. */
    public DOMTreeFull() {
        this(null);
    }

    /** Constructs a tree with the specified document. */
    public DOMTreeFull(Node root) {
        super(new Model());

        // set tree properties
        setRootVisible(false);

        // set properties
        setRootNode(root);

    } // <init>()

    //
    // Public methods
    //

    /** Sets the root. */
    public void setRootNode(Node root) {
        ((Model) getModel()).setRootNode(root);
        expandRow(0);
    }

    /** Returns the root. */
    public Node getRootNode() {
        return ((Model) getModel()).getRootNode();
    }

    /** get the org.w3c.Node for a MutableTreeNode. */
    public Node getNode(Object treeNode) {
        return ((Model) getModel()).getNode(treeNode);
    }

    /** get the TreeNode for the org.w3c.Node */
    public TreeNode getTreeNode(Object node) {
        return ((Model) getModel()).getTreeNode(node);
    }

    //
    // Classes
    //

    /**
     * DOM tree model.
     * 
     */
    public static class Model extends DefaultTreeModel implements Serializable {

        private static final long serialVersionUID = 3258131375181018673L;

        //
        // Data
        //

        /** Root. */
        private Node root;

        /** Node Map. */
        private Hashtable nodeMap = new Hashtable();

        /** Tree Node Map. */
        private Hashtable treeNodeMap = new Hashtable();

        //
        // Constructors
        //

        /** Default constructor. */
        public Model() {
            this(null);
        }

        /** Constructs a model from the specified root. */
        public Model(Node node) {
            super(new DefaultMutableTreeNode());
            if (node != null)
                setRootNode(node);
        }

        //
        // Public methods
        //

        /** Sets the root. */
        public synchronized void setRootNode(Node root) {

            // save root
            this.root = root;

            // clear tree and re-populate
            DefaultMutableTreeNode where = (DefaultMutableTreeNode) getRoot();
            where.removeAllChildren();
            nodeMap.clear();
            treeNodeMap.clear();

            buildTree(root, where);

            fireTreeStructureChanged(this, new Object[] { getRoot() }, new int[0], new Object[0]);

        } // setRootNode(Node)

        /** Returns the root. */
        public Node getRootNode() {
            return root;
        }

        /** get the org.w3c.Node for a MutableTreeNode. */
        public Node getNode(Object treeNode) {
            return (Node) nodeMap.get(treeNode);
        }

        public Hashtable getAllNodes() {
            return nodeMap;
        }

        /** get the org.w3c.Node for a MutableTreeNode. */
        public TreeNode getTreeNode(Object node) {
            Object object = treeNodeMap.get(node);
            return (TreeNode) object;
        }

        //
        // Private methods
        //

        /** Builds the tree. */
        private void buildTree(Node node, MutableTreeNode where) {

            // is there anything to do?
            if (node == null) {
                return;
            }

            MutableTreeNode treeNode = insertNode(node, where);

            // iterate over children of this node
            NodeList nodes = node.getChildNodes();
            int len = (nodes != null) ? nodes.getLength() : 0;
            for (int i = 0; i < len; i++) {
                Node child = nodes.item(i);
                buildTree(child, treeNode);

            }

        } // buildTree()

        /** Inserts a node and returns a reference to the new node. */
        private MutableTreeNode insertNode(String what, MutableTreeNode where) {

            MutableTreeNode node = new DefaultMutableTreeNode(what);
            insertNodeInto(node, where, where.getChildCount());
            return node;

        } // insertNode(Node,MutableTreeNode):MutableTreeNode

        /** Inserts a text node. */
        public MutableTreeNode insertNode(Node what, MutableTreeNode where) {
            MutableTreeNode treeNode = insertNode(DOMTreeFull.toString(what), where);
            nodeMap.put(treeNode, what);
            treeNodeMap.put(what, treeNode);
            return treeNode;
        }
    } // class Model

    public static String whatArray[] = new String[] { "ALL", "ELEMENT", "ATTRIBUTE", "TEXT", "CDATA_SECTION",
            "ENTITY_REFERENCE", "ENTITY", "PROCESSING_INSTRUCTION", "COMMENT", "DOCUMENT", "DOCUMENT_TYPE",
            "DOCUMENT_FRAGMENT", "NOTATION" };

    //
    // Public methods
    //

    public static String toString(Node node) {
        StringBuffer sb = new StringBuffer();

        // is there anything to do?
        if (node == null) {
            return "";
        }

        int type = node.getNodeType();
        sb.append(whatArray[type]);
        sb.append(" : ");
        sb.append(node.getNodeName());
        String value = node.getNodeValue();
        if (value != null) {
            sb.append(" Value: \"");
            sb.append(value);
            sb.append("\"");
        }

        switch (type) {

        // document
        case Node.DOCUMENT_NODE: {
            break;
        }

        // element with attributes
        case Node.ELEMENT_NODE: {
            Attr attrs[] = sortAttributes(node.getAttributes());
            if (attrs.length > 0)
                sb.append(" ATTRS:");
            for (int i = 0; i < attrs.length; i++) {
                Attr attr = attrs[i];

                sb.append(' ');
                sb.append(attr.getNodeName());
                sb.append("=\"");
                sb.append(normalize(attr.getNodeValue()));
                sb.append('"');
            }
            sb.append('>');
            break;
        }

        // handle entity reference nodes
        case Node.ENTITY_REFERENCE_NODE: {
            break;
        }

        // cdata sections
        case Node.CDATA_SECTION_NODE: {
            break;
        }

        // text
        case Node.TEXT_NODE: {
            break;
        }

        // processing instruction
        case Node.PROCESSING_INSTRUCTION_NODE: {
            break;
        }

        // comment node
        case Node.COMMENT_NODE: {
            break;
        }
        // DOCTYPE node
        case Node.DOCUMENT_TYPE_NODE: {
            break;
        }
        // Notation node
        case Node.NOTATION_NODE: {
            sb.append("public:");
            String id = ((Notation) node).getPublicId();
            if (id == null) {
                sb.append("PUBLIC ");
                sb.append(id);
                sb.append(" ");
            }
            id = ((Notation) node).getSystemId();
            if (id == null) {
                sb.append("system: ");
                sb.append(id);
                sb.append(" ");
            }
            break;
        }
        }
        return sb.toString();
    }

    /** Normalizes the given string. */
    static protected String normalize(String s) {
        StringBuffer str = new StringBuffer();

        int len = (s != null) ? s.length() : 0;
        for (int i = 0; i < len; i++) {
            char ch = s.charAt(i);
            switch (ch) {
            case '<': {
                str.append("&lt;");
                break;
            }
            case '>': {
                str.append("&gt;");
                break;
            }
            case '&': {
                str.append("&amp;");
                break;
            }
            case '"': {
                str.append("&quot;");
                break;
            }
            case '\r':
            case '\n':
            default: {
                str.append(ch);
            }
            }
        }

        return str.toString();

    } // normalize(String):String

    /** Returns a sorted list of attributes. */
    static protected Attr[] sortAttributes(NamedNodeMap attrs) {

        int len = (attrs != null) ? attrs.getLength() : 0;
        Attr array[] = new Attr[len];
        for (int i = 0; i < len; i++) {
            array[i] = (Attr) attrs.item(i);
        }
        for (int i = 0; i < len - 1; i++) {
            String name = array[i].getNodeName();
            int index = i;
            for (int j = i + 1; j < len; j++) {
                String curName = array[j].getNodeName();
                if (curName.compareTo(name) < 0) {
                    name = curName;
                    index = j;
                }
            }
            if (index != i) {
                Attr temp = array[i];
                array[i] = array[index];
                array[index] = temp;
            }
        }

        return array;

    } // sortAttributes(NamedNodeMap):Attr[]

} // class DOMTreeFull