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

org.enhydra.xml.lazydom.LazyDOMTraversal Maven / Gradle / Ivy

The newest version!
/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: LazyDOMTraversal.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
 */

package org.enhydra.xml.lazydom;

import org.enhydra.xml.dom.DOMOps;
import org.enhydra.xml.dom.DOMTraversal;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

// FIXME: might be able to speed this up if we could recognize the case where
// we have switch over to the template and can't switch back. For instance,
// attributes of a template element or contents of a doctype.

//FIXME: Maybe LazyDOMOps.access methods should be used here to provide one
// common method for safely traversing the tree.

/**
 * Lazy DOM traversal class, calling handler methods for each node based on if
 * they are expanded or template nodes.  This only works if the traversal
 * starts with a node of the instance LazyDocument.  Template LazyDocuments
 * will not work with this class and should be traversed normally.
 */
public class LazyDOMTraversal extends DOMTraversal {
    /** Lazy document being traversed */
    private LazyDocument fLazyDoc;

    /**
     * Constructor.
     * @param handler The object that will be called to handle each
     *  node.
     * @param options Bit set of the option flags.
     */
    public LazyDOMTraversal(DOMTraversal.Handler handler,
                            int options) {
        super(handler, options);
    }
    
    /**
     * Default constructor, set handler later.
     */
    public LazyDOMTraversal(int options) {
        super(options);
    }

    /**
     * Traverse a DOM tree or subtree.
     *
     * @param root The root of the DOM tree or subtree that is to
     *  be traversed.
     */
    public void traverse(Node root) {
        // Don't let XMLObject cause confusion
        Node lazyRoot  = DOMOps.getActualNode(root);
        fLazyDoc = (LazyDocument)lazyRoot.getOwnerDocument();
        if (fLazyDoc == null) {
            fLazyDoc = (LazyDocument)lazyRoot;
        }
        if (fLazyDoc.isTemplateNode()) {
            throw new LazyDOMError("LazyDOMTraversal used on template document");
        }

        fDepth = 0;
        fProcessingAttribute = false;
        processNode(lazyRoot);
    }

    /**
     * Process the children of a node.  This overrides the DOMTraversal method
     * and handles switching from instance to template nodes.
     */
    public void processChildren(Node node) {
        if (node instanceof LazyParent) {
            LazyParent lazyNode = (LazyParent)node;
            if (lazyNode.isTemplateNode()) {
                // templates may switch back to instance in processNode()
                super.processChildren(lazyNode);
            } else if (lazyNode.areChildrenExpanded()) {
                // expanded instance children, handle as normal
                super.processChildren(lazyNode);
            } else {
                // switch to template
                super.processChildren(lazyNode.getTemplateNode());
            }
        }
    }

    /**
     * Process the attributes of an element.  This overrides the DOMTraversal
     * method and handles switching from instance to template nodes.
     */
    public void processAttributes(Element element) {
        LazyElement lazyElement = (LazyElement)element;
        if (lazyElement.isTemplateNode()) {
            // attribute are all template if node is template
            super.processAttributes(lazyElement);
        } else if (lazyElement.areAttributesExpanded()) {
            // expanded instance attributes, handle as normal
            super.processAttributes(lazyElement);
        } else {
            // switch to template
            super.processAttributes(lazyElement.getTemplateElement());
        }
    }

    /**
     * Process a DocumentType attribute of a Document node, if it exists. This
     * overrides the DOMTraversal method and handles switching from instance
     * to template nodes.
     */
    public void processDocumentType(Document document) {
        LazyDocument lazyDoc = (LazyDocument)document;
        if (lazyDoc.isTemplateNode()) {
            // if document is template, DocumentType is template
            super.processDocumentType(document);
        } else if (lazyDoc.isDocTypeExpanded()) {
            // expanded instance DocumentType, handle as normal
            super.processDocumentType(document);
        } else {
            // switch to template
            super.processDocumentType(lazyDoc.getTemplateDocument());
        }
    }

    /**
     * Process the contents of a DocumentType node. This overrides the
     * DOMTraversal method and handles switching from instance to template
     * nodes.
     */
    public void processDocumentTypeContents(DocumentType documentType) {
        LazyDocumentType lazyDocType = (LazyDocumentType)documentType;
        if (lazyDocType.isTemplateNode()) {
            // contents are all template if doctype is template
            super.processDocumentTypeContents(lazyDocType);
        } else if (lazyDocType.isContentsExpanded()) {
            // expanded instance content, handle as normal
            super.processDocumentTypeContents(lazyDocType);
        } else {
            // switch to template
            super.processDocumentTypeContents(lazyDocType.getTemplateDocumentType());
        }
    }

    /**
     * Processing based on node type.  All nodes go through here. This
     * overrides the DOMTraversal method and handles switching from template
     * back to instance nodes.
     */
    protected void processNode(Node node) {
        LazyNode lazyNode = (LazyNode)node;
        if (lazyNode.isTemplateNode()) {
            LazyNode instanceNode = fLazyDoc.getExpandedNode(lazyNode.getNodeId());
            if (instanceNode != null) {
                // switch back from template to instance
                super.processNode(instanceNode);
            } else {
                // not expanded, just process template
                super.processNode(lazyNode);
            }
        } else {
            // process instance node
            super.processNode(lazyNode);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy