286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 1999-2002,2004 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/A
286N/Apackage com.sun.org.apache.xerces.internal.dom;
286N/A
286N/Aimport org.w3c.dom.DOMException;
286N/Aimport org.w3c.dom.Node;
286N/Aimport org.w3c.dom.traversal.NodeFilter;
286N/Aimport org.w3c.dom.traversal.TreeWalker;
286N/A
286N/A/** This class implements the TreeWalker interface.
286N/A *
286N/A * @xerces.internal
286N/A *
286N/A */
286N/A
286N/Apublic class TreeWalkerImpl implements TreeWalker {
286N/A
286N/A //
286N/A // Data
286N/A //
286N/A
286N/A /** When TRUE, the children of entites references are returned in the iterator. */
286N/A private boolean fEntityReferenceExpansion = false;
286N/A /** The whatToShow mask. */
286N/A int fWhatToShow = NodeFilter.SHOW_ALL;
286N/A /** The NodeFilter reference. */
286N/A NodeFilter fNodeFilter;
286N/A /** The current Node. */
286N/A Node fCurrentNode;
286N/A /** The root Node. */
286N/A Node fRoot;
286N/A
286N/A //
286N/A // Implementation Note: No state is kept except the data above
286N/A // (fWhatToShow, fNodeFilter, fCurrentNode, fRoot) such that
286N/A // setters could be created for these data values and the
286N/A // implementation will still work.
286N/A
286N/A
286N/A //
286N/A // Constructor
286N/A //
286N/A
286N/A /** Public constructor */
286N/A public TreeWalkerImpl(Node root,
286N/A int whatToShow,
286N/A NodeFilter nodeFilter,
286N/A boolean entityReferenceExpansion) {
286N/A fCurrentNode = root;
286N/A fRoot = root;
286N/A fWhatToShow = whatToShow;
286N/A fNodeFilter = nodeFilter;
286N/A fEntityReferenceExpansion = entityReferenceExpansion;
286N/A }
286N/A
286N/A public Node getRoot() {
286N/A return fRoot;
286N/A }
286N/A
286N/A /** Return the whatToShow value */
286N/A public int getWhatToShow() {
286N/A return fWhatToShow;
286N/A }
286N/A
286N/A public void setWhatShow(int whatToShow){
286N/A fWhatToShow = whatToShow;
286N/A }
286N/A /** Return the NodeFilter */
286N/A public NodeFilter getFilter() {
286N/A return fNodeFilter;
286N/A }
286N/A
286N/A /** Return whether children entity references are included in the iterator. */
286N/A public boolean getExpandEntityReferences() {
286N/A return fEntityReferenceExpansion;
286N/A }
286N/A
286N/A /** Return the current Node. */
286N/A public Node getCurrentNode() {
286N/A return fCurrentNode;
286N/A }
286N/A /** Return the current Node. */
286N/A public void setCurrentNode(Node node) {
286N/A if (node == null) {
286N/A String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
286N/A throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
286N/A }
286N/A
286N/A fCurrentNode = node;
286N/A }
286N/A
286N/A /** Return the parent Node from the current node,
286N/A * after applying filter, whatToshow.
286N/A * If result is not null, set the current Node.
286N/A */
286N/A public Node parentNode() {
286N/A
286N/A if (fCurrentNode == null) return null;
286N/A
286N/A Node node = getParentNode(fCurrentNode);
286N/A if (node !=null) {
286N/A fCurrentNode = node;
286N/A }
286N/A return node;
286N/A
286N/A }
286N/A
286N/A /** Return the first child Node from the current node,
286N/A * after applying filter, whatToshow.
286N/A * If result is not null, set the current Node.
286N/A */
286N/A public Node firstChild() {
286N/A
286N/A if (fCurrentNode == null) return null;
286N/A
286N/A Node node = getFirstChild(fCurrentNode);
286N/A if (node !=null) {
286N/A fCurrentNode = node;
286N/A }
286N/A return node;
286N/A }
286N/A /** Return the last child Node from the current node,
286N/A * after applying filter, whatToshow.
286N/A * If result is not null, set the current Node.
286N/A */
286N/A public Node lastChild() {
286N/A
286N/A if (fCurrentNode == null) return null;
286N/A
286N/A Node node = getLastChild(fCurrentNode);
286N/A if (node !=null) {
286N/A fCurrentNode = node;
286N/A }
286N/A return node;
286N/A }
286N/A
286N/A /** Return the previous sibling Node from the current node,
286N/A * after applying filter, whatToshow.
286N/A * If result is not null, set the current Node.
286N/A */
286N/A public Node previousSibling() {
286N/A
286N/A if (fCurrentNode == null) return null;
286N/A
286N/A Node node = getPreviousSibling(fCurrentNode);
286N/A if (node !=null) {
286N/A fCurrentNode = node;
286N/A }
286N/A return node;
286N/A }
286N/A
286N/A /** Return the next sibling Node from the current node,
286N/A * after applying filter, whatToshow.
286N/A * If result is not null, set the current Node.
286N/A */
286N/A public Node nextSibling(){
286N/A if (fCurrentNode == null) return null;
286N/A
286N/A Node node = getNextSibling(fCurrentNode);
286N/A if (node !=null) {
286N/A fCurrentNode = node;
286N/A }
286N/A return node;
286N/A }
286N/A
286N/A /** Return the previous Node from the current node,
286N/A * after applying filter, whatToshow.
286N/A * If result is not null, set the current Node.
286N/A */
286N/A public Node previousNode() {
286N/A Node result;
286N/A
286N/A if (fCurrentNode == null) return null;
286N/A
286N/A // get sibling
286N/A result = getPreviousSibling(fCurrentNode);
286N/A if (result == null) {
286N/A result = getParentNode(fCurrentNode);
286N/A if (result != null) {
286N/A fCurrentNode = result;
286N/A return fCurrentNode;
286N/A }
286N/A return null;
286N/A }
286N/A
286N/A // get the lastChild of result.
286N/A Node lastChild = getLastChild(result);
286N/A
286N/A Node prev = lastChild ;
286N/A while (lastChild != null) {
286N/A prev = lastChild ;
286N/A lastChild = getLastChild(prev) ;
286N/A }
286N/A
286N/A lastChild = prev ;
286N/A
286N/A // if there is a lastChild which passes filters return it.
286N/A if (lastChild != null) {
286N/A fCurrentNode = lastChild;
286N/A return fCurrentNode;
286N/A }
286N/A
286N/A // otherwise return the previous sibling.
286N/A if (result != null) {
286N/A fCurrentNode = result;
286N/A return fCurrentNode;
286N/A }
286N/A
286N/A // otherwise return null.
286N/A return null;
286N/A }
286N/A
286N/A /** Return the next Node from the current node,
286N/A * after applying filter, whatToshow.
286N/A * If result is not null, set the current Node.
286N/A */
286N/A public Node nextNode() {
286N/A
286N/A if (fCurrentNode == null) return null;
286N/A
286N/A Node result = getFirstChild(fCurrentNode);
286N/A
286N/A if (result != null) {
286N/A fCurrentNode = result;
286N/A return result;
286N/A }
286N/A
286N/A result = getNextSibling(fCurrentNode);
286N/A
286N/A if (result != null) {
286N/A fCurrentNode = result;
286N/A return result;
286N/A }
286N/A
286N/A // return parent's 1st sibling.
286N/A Node parent = getParentNode(fCurrentNode);
286N/A while (parent != null) {
286N/A result = getNextSibling(parent);
286N/A if (result != null) {
286N/A fCurrentNode = result;
286N/A return result;
286N/A } else {
286N/A parent = getParentNode(parent);
286N/A }
286N/A }
286N/A
286N/A // end , return null
286N/A return null;
286N/A }
286N/A
286N/A /** Internal function.
286N/A * Return the parent Node, from the input node
286N/A * after applying filter, whatToshow.
286N/A * The current node is not consulted or set.
286N/A */
286N/A Node getParentNode(Node node) {
286N/A
286N/A if (node == null || node == fRoot) return null;
286N/A
286N/A Node newNode = node.getParentNode();
286N/A if (newNode == null) return null;
286N/A
286N/A int accept = acceptNode(newNode);
286N/A
286N/A if (accept == NodeFilter.FILTER_ACCEPT)
286N/A return newNode;
286N/A else
286N/A //if (accept == NodeFilter.SKIP_NODE) // and REJECT too.
286N/A {
286N/A return getParentNode(newNode);
286N/A }
286N/A
286N/A
286N/A }
286N/A
286N/A /** Internal function.
286N/A * Return the nextSibling Node, from the input node
286N/A * after applying filter, whatToshow.
286N/A * The current node is not consulted or set.
286N/A */
286N/A Node getNextSibling(Node node) {
286N/A return getNextSibling(node, fRoot);
286N/A }
286N/A
286N/A /** Internal function.
286N/A * Return the nextSibling Node, from the input node
286N/A * after applying filter, whatToshow.
286N/A * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
286N/A * The current node is not consulted or set.
286N/A */
286N/A Node getNextSibling(Node node, Node root) {
286N/A
286N/A if (node == null || node == root) return null;
286N/A
286N/A Node newNode = node.getNextSibling();
286N/A if (newNode == null) {
286N/A
286N/A newNode = node.getParentNode();
286N/A
286N/A if (newNode == null || newNode == root) return null;
286N/A
286N/A int parentAccept = acceptNode(newNode);
286N/A
286N/A if (parentAccept==NodeFilter.FILTER_SKIP) {
286N/A return getNextSibling(newNode, root);
286N/A }
286N/A
286N/A return null;
286N/A }
286N/A
286N/A int accept = acceptNode(newNode);
286N/A
286N/A if (accept == NodeFilter.FILTER_ACCEPT)
286N/A return newNode;
286N/A else
286N/A if (accept == NodeFilter.FILTER_SKIP) {
286N/A Node fChild = getFirstChild(newNode);
286N/A if (fChild == null) {
286N/A return getNextSibling(newNode, root);
286N/A }
286N/A return fChild;
286N/A }
286N/A else
286N/A //if (accept == NodeFilter.REJECT_NODE)
286N/A {
286N/A return getNextSibling(newNode, root);
286N/A }
286N/A
286N/A } // getNextSibling(Node node) {
286N/A
286N/A /** Internal function.
286N/A * Return the previous sibling Node, from the input node
286N/A * after applying filter, whatToshow.
286N/A * The current node is not consulted or set.
286N/A */
286N/A Node getPreviousSibling(Node node) {
286N/A return getPreviousSibling(node, fRoot);
286N/A }
286N/A
286N/A /** Internal function.
286N/A * Return the previousSibling Node, from the input node
286N/A * after applying filter, whatToshow.
286N/A * NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
286N/A * The current node is not consulted or set.
286N/A */
286N/A Node getPreviousSibling(Node node, Node root) {
286N/A
286N/A if (node == null || node == root) return null;
286N/A
286N/A Node newNode = node.getPreviousSibling();
286N/A if (newNode == null) {
286N/A
286N/A newNode = node.getParentNode();
286N/A if (newNode == null || newNode == root) return null;
286N/A
286N/A int parentAccept = acceptNode(newNode);
286N/A
286N/A if (parentAccept==NodeFilter.FILTER_SKIP) {
286N/A return getPreviousSibling(newNode, root);
286N/A }
286N/A
286N/A return null;
286N/A }
286N/A
286N/A int accept = acceptNode(newNode);
286N/A
286N/A if (accept == NodeFilter.FILTER_ACCEPT)
286N/A return newNode;
286N/A else
286N/A if (accept == NodeFilter.FILTER_SKIP) {
286N/A Node fChild = getLastChild(newNode);
286N/A if (fChild == null) {
286N/A return getPreviousSibling(newNode, root);
286N/A }
286N/A return fChild;
286N/A }
286N/A else
286N/A //if (accept == NodeFilter.REJECT_NODE)
286N/A {
286N/A return getPreviousSibling(newNode, root);
286N/A }
286N/A
286N/A } // getPreviousSibling(Node node) {
286N/A
286N/A /** Internal function.
286N/A * Return the first child Node, from the input node
286N/A * after applying filter, whatToshow.
286N/A * The current node is not consulted or set.
286N/A */
286N/A Node getFirstChild(Node node) {
286N/A if (node == null) return null;
286N/A
286N/A if ( !fEntityReferenceExpansion
286N/A && node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
286N/A return null;
286N/A Node newNode = node.getFirstChild();
286N/A if (newNode == null) return null;
286N/A int accept = acceptNode(newNode);
286N/A
286N/A if (accept == NodeFilter.FILTER_ACCEPT)
286N/A return newNode;
286N/A else
286N/A if (accept == NodeFilter.FILTER_SKIP
286N/A && newNode.hasChildNodes())
286N/A {
286N/A Node fChild = getFirstChild(newNode);
286N/A
286N/A if (fChild == null) {
286N/A return getNextSibling(newNode, node);
286N/A }
286N/A return fChild;
286N/A }
286N/A else
286N/A //if (accept == NodeFilter.REJECT_NODE)
286N/A {
286N/A return getNextSibling(newNode, node);
286N/A }
286N/A
286N/A
286N/A }
286N/A
286N/A /** Internal function.
286N/A * Return the last child Node, from the input node
286N/A * after applying filter, whatToshow.
286N/A * The current node is not consulted or set.
286N/A */
286N/A Node getLastChild(Node node) {
286N/A
286N/A if (node == null) return null;
286N/A
286N/A if ( !fEntityReferenceExpansion
286N/A && node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
286N/A return null;
286N/A
286N/A Node newNode = node.getLastChild();
286N/A if (newNode == null) return null;
286N/A
286N/A int accept = acceptNode(newNode);
286N/A
286N/A if (accept == NodeFilter.FILTER_ACCEPT)
286N/A return newNode;
286N/A else
286N/A if (accept == NodeFilter.FILTER_SKIP
286N/A && newNode.hasChildNodes())
286N/A {
286N/A Node lChild = getLastChild(newNode);
286N/A if (lChild == null) {
286N/A return getPreviousSibling(newNode, node);
286N/A }
286N/A return lChild;
286N/A }
286N/A else
286N/A //if (accept == NodeFilter.REJECT_NODE)
286N/A {
286N/A return getPreviousSibling(newNode, node);
286N/A }
286N/A
286N/A
286N/A }
286N/A
286N/A /** Internal function.
286N/A * The node whatToShow and the filter are combined into one result. */
286N/A short acceptNode(Node node) {
286N/A /***
286N/A 7.1.2.4. Filters and whatToShow flags
286N/A
286N/A Iterator and TreeWalker apply whatToShow flags before applying Filters. If a node is rejected by the
286N/A active whatToShow flags, a Filter will not be called to evaluate that node. When a node is rejected by
286N/A the active whatToShow flags, children of that node will still be considered, and Filters may be called to
286N/A evaluate them.
286N/A ***/
286N/A
286N/A if (fNodeFilter == null) {
286N/A if ( ( fWhatToShow & (1 << node.getNodeType()-1)) != 0) {
286N/A return NodeFilter.FILTER_ACCEPT;
286N/A } else {
286N/A return NodeFilter.FILTER_SKIP;
286N/A }
286N/A } else {
286N/A if ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 ) {
286N/A return fNodeFilter.acceptNode(node);
286N/A } else {
286N/A // What to show has failed. See above excerpt from spec.
286N/A // Equivalent to FILTER_SKIP.
286N/A return NodeFilter.FILTER_SKIP;
286N/A }
286N/A }
286N/A }
286N/A}