Clover coverage report -
Coverage timestamp: Sun Nov 1 2009 23:08:24 UTC
file stats: LOC: 358   Methods: 17
NCLOC: 194   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
TreeWalkerImpl.java 17.4% 27.8% 23.5% 24.7%
coverage coverage
 1    /*
 2    * Licensed to the Apache Software Foundation (ASF) under one or more
 3    * contributor license agreements. See the NOTICE file distributed with
 4    * this work for additional information regarding copyright ownership.
 5    * The ASF licenses this file to You under the Apache License, Version 2.0
 6    * (the "License"); you may not use this file except in compliance with
 7    * the License. You may obtain a copy of the License at
 8    *
 9    * http://www.apache.org/licenses/LICENSE-2.0
 10    *
 11    * Unless required by applicable law or agreed to in writing, software
 12    * distributed under the License is distributed on an "AS IS" BASIS,
 13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14    * See the License for the specific language governing permissions and
 15    * limitations under the License.
 16    *
 17    * $Id: TreeWalkerImpl.java 541508 2007-05-25 01:54:12Z vgritsenko $
 18    */
 19   
 20    package org.apache.xindice.xml.dom.traversal;
 21   
 22    import org.apache.xindice.xml.dom.NodeImpl;
 23   
 24    import org.w3c.dom.DOMException;
 25    import org.w3c.dom.Node;
 26    import org.w3c.dom.traversal.NodeFilter;
 27    import org.w3c.dom.traversal.NodeIterator;
 28    import org.w3c.dom.traversal.TreeWalker;
 29   
 30    /**
 31    * TreeWalkerImpl
 32    *
 33    * @version $Revision: 541508 $, $Date: 2007-05-24 18:54:12 -0700 (Thu, 24 May 2007) $
 34    */
 35    public final class TreeWalkerImpl implements TreeWalker, NodeIterator {
 36    protected boolean valid;
 37    protected Node root;
 38    protected Node current;
 39    protected int whatToShow;
 40    protected NodeFilter filter;
 41    protected boolean expand;
 42   
 43   
 44  471 public TreeWalkerImpl(Node root, int whatToShow, NodeFilter filter, boolean entityReferenceExpansion) throws DOMException {
 45  471 this.valid = true;
 46  471 this.root = root;
 47  471 this.current = root;
 48  471 this.whatToShow = whatToShow;
 49  471 this.filter = filter;
 50  471 this.expand = entityReferenceExpansion;
 51    }
 52   
 53  5266 private int getShowType(Node node) {
 54  5266 switch (node.getNodeType()) {
 55  0 case Node.ATTRIBUTE_NODE:
 56  0 return NodeFilter.SHOW_ATTRIBUTE;
 57  6 case Node.CDATA_SECTION_NODE:
 58  6 return NodeFilter.SHOW_CDATA_SECTION;
 59  6 case Node.COMMENT_NODE:
 60  6 return NodeFilter.SHOW_COMMENT;
 61  0 case Node.DOCUMENT_FRAGMENT_NODE:
 62  0 return NodeFilter.SHOW_DOCUMENT_FRAGMENT;
 63  0 case Node.DOCUMENT_NODE:
 64  0 return NodeFilter.SHOW_DOCUMENT;
 65  0 case Node.DOCUMENT_TYPE_NODE:
 66  0 return NodeFilter.SHOW_DOCUMENT_TYPE;
 67  4115 case Node.ELEMENT_NODE:
 68  4115 return NodeFilter.SHOW_ELEMENT;
 69  0 case Node.ENTITY_NODE:
 70  0 return NodeFilter.SHOW_ENTITY;
 71  0 case Node.ENTITY_REFERENCE_NODE:
 72  0 return NodeFilter.SHOW_ENTITY_REFERENCE;
 73  0 case Node.NOTATION_NODE:
 74  0 return NodeFilter.SHOW_NOTATION;
 75  0 case Node.PROCESSING_INSTRUCTION_NODE:
 76  0 return NodeFilter.SHOW_PROCESSING_INSTRUCTION;
 77  1139 case Node.TEXT_NODE:
 78  1139 return NodeFilter.SHOW_TEXT;
 79  0 default:
 80  0 return 0;
 81    }
 82    }
 83   
 84  5266 private boolean acceptNode(Node node) {
 85  5266 return ((getShowType(node) & whatToShow) > 0)
 86    && (filter == null || filter.acceptNode(node) == NodeFilter.FILTER_ACCEPT);
 87    }
 88   
 89    /**
 90    * The root node of the Iterator, as specified when it was created.
 91    */
 92  0 public Node getRoot() {
 93  0 return root;
 94    }
 95   
 96    /**
 97    * This attribute determines which node types are presented via the
 98    * iterator. The available set of constants is defined in the
 99    * <code>NodeFilter</code> interface.
 100    */
 101  0 public int getWhatToShow() {
 102  0 return whatToShow;
 103    }
 104   
 105    /**
 106    * The filter used to screen nodes.
 107    */
 108  0 public NodeFilter getFilter() {
 109  0 return filter;
 110    }
 111   
 112    /**
 113    * The value of this flag determines whether the children of entity
 114    * reference nodes are visible to the iterator. If false, they will be
 115    * skipped over.
 116    *
 117    * <br>To produce a view of the document that has entity references
 118    * expanded and does not expose the entity reference node itself, use the
 119    * whatToShow flags to hide the entity reference node and set
 120    * expandEntityReferences to true when creating the iterator. To produce
 121    * a view of the document that has entity reference nodes but no entity
 122    * expansion, use the whatToShow flags to show the entity reference node
 123    * and set expandEntityReferences to false.
 124    */
 125  0 public boolean getExpandEntityReferences() {
 126  0 return expand;
 127    }
 128   
 129    /**
 130    * Detaches the iterator from the set which it iterated over, releasing
 131    * any computational resources and placing the iterator in the INVALID
 132    * state. After<code>detach</code> has been invoked, calls to
 133    * <code>nextNode</code> or<code>previousNode</code> will raise the
 134    * exception INVALID_STATE_ERR.
 135    */
 136  0 public void detach() {
 137  0 valid = false;
 138    }
 139   
 140    /**
 141    * The node at which the TreeWalker is currently positioned.
 142    *
 143    * <br>The value must not be null. Alterations to the DOM tree may cause
 144    * the current node to no longer be accepted by the TreeWalker's
 145    * associated filter. currentNode may also be explicitly set to any node,
 146    * whether or not it is within the subtree specified by the root node or
 147    * would be accepted by the filter and whatToShow flags. Further
 148    * traversal occurs relative to currentNode even if it is not part of the
 149    * current view by applying the filters in the requested direction (not
 150    * changing currentNode where no traversal is possible).
 151    *
 152    * @exception DOMException
 153    * NOT_SUPPORTED_ERR: Raised if the specified <code>currentNode</code>
 154    * is<code>null</code> .
 155    */
 156  0 public Node getCurrentNode() {
 157  0 return current;
 158    }
 159   
 160  0 public void setCurrentNode(Node currentNode) throws DOMException {
 161  0 if (!valid) {
 162  0 throw NodeImpl.EX_INVALID_STATE;
 163    }
 164  0 if (currentNode == null) {
 165  0 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
 166    "Current node can not be set to null.");
 167    }
 168  0 this.current = currentNode;
 169    }
 170   
 171    /**
 172    * Moves to and returns the closest visible ancestor node of the current
 173    * node. If the search for parentNode attempts to step upward from the
 174    * TreeWalker's root node, or if it fails to find a visible ancestor
 175    * node, this method retains the current position and returns null.
 176    *
 177    * @return The new parent node, or null if the current node has no parent
 178    * in the TreeWalker's logical view.
 179    */
 180  0 public Node parentNode() {
 181  0 Node node = this.current;
 182  0 while (node != null) {
 183  0 if (node == root) {
 184  0 return null;
 185    }
 186  0 node = node.getParentNode();
 187  0 if (node == null) {
 188  0 return null;
 189  0 } else if (acceptNode(node)) {
 190  0 this.current = node;
 191  0 return this.current;
 192    }
 193    }
 194  0 return null;
 195    }
 196   
 197    /**
 198    * Moves the <code>TreeWalker</code> to the first visible child of the
 199    * current node, and returns the new node. If the current node has no
 200    * visible children, returns <code>null</code> , and retains the current
 201    * node.
 202    *
 203    * @return The new node, or <code>null</code> if the current node has no
 204    * visible children in the TreeWalker's logical view.
 205    */
 206  0 public Node firstChild() {
 207  0 Node node = this.current.getFirstChild();
 208  0 while (node != null) {
 209  0 if (acceptNode(node)) {
 210  0 this.current = node;
 211  0 return this.current;
 212    }
 213   
 214  0 node = node.getNextSibling();
 215    }
 216  0 return null;
 217    }
 218   
 219    /**
 220    * Moves the <code>TreeWalker</code> to the last visible child of the
 221    * current node, and returns the new node. If the current node has no
 222    * visible children, returns <code>null</code> , and retains the current
 223    * node.
 224    *
 225    * @return The new node, or <code>null</code> if the current node has no
 226    * children in the TreeWalker's logical view.
 227    */
 228  0 public Node lastChild() {
 229  0 Node node = this.current.getLastChild();
 230  0 while (node != null) {
 231  0 if (acceptNode(node)) {
 232  0 this.current = node;
 233  0 return this.current;
 234    }
 235   
 236  0 node = node.getPreviousSibling();
 237    }
 238  0 return null;
 239    }
 240   
 241    /**
 242    * Moves the <code>TreeWalker</code> to the previous sibling of the
 243    * current node, and returns the new node. If the current node has no
 244    * visible previous sibling, returns <code>null</code> , and retains the
 245    * current node.
 246    *
 247    * @return The new node, or <code>null</code> if the current node has no
 248    * previous sibling in the TreeWalker's logical view.
 249    */
 250  0 public Node previousSibling() {
 251  0 Node node = this.current.getPreviousSibling();
 252  0 while (node != null) {
 253  0 if (acceptNode(node)) {
 254  0 this.current = node;
 255  0 return this.current;
 256    }
 257   
 258  0 node = node.getPreviousSibling();
 259    }
 260  0 return null;
 261    }
 262   
 263    /**
 264    * Moves the <code>TreeWalker</code> to the next sibling of the current
 265    * node, and returns the new node. If the current node has no visible
 266    * next sibling, returns <code>null</code> , and retains the current node.
 267    *
 268    * @return The new node, or <code>null</code> if the current node has no
 269    * next sibling in the TreeWalker's logical view.
 270    */
 271  0 public Node nextSibling() {
 272  0 Node node = this.current.getNextSibling();
 273  0 while (node != null) {
 274  0 if (acceptNode(node)) {
 275  0 this.current = node;
 276  0 return this.current;
 277    }
 278   
 279  0 node = node.getNextSibling();
 280    }
 281  0 return null;
 282    }
 283   
 284    /**
 285    * Moves the <code>TreeWalker</code> to the previous visible node in
 286    * document order relative to the current node, and returns the new node.
 287    * If the current node has no previous node, or if the search for
 288    * previousNode attempts to step upward from the TreeWalker's root node,
 289    * returns <code>null</code> , and retains the current node.
 290    *
 291    * @return The new node, or <code>null</code> if the current node has no
 292    * previous node in the TreeWalker's logical view.
 293    */
 294  0 public Node previousNode() {
 295  0 Node node = this.current;
 296  0 while (true) {
 297  0 Node tmp = node.getPreviousSibling();
 298  0 if (tmp == null) {
 299  0 if (node == root) {
 300    // Do not go out of the root
 301  0 return null;
 302    }
 303   
 304  0 tmp = node.getParentNode();
 305    } else {
 306  0 while (tmp.hasChildNodes()) {
 307  0 tmp = tmp.getLastChild();
 308    }
 309    }
 310  0 node = tmp;
 311   
 312  0 if (node == null) {
 313  0 return null;
 314  0 } else if (acceptNode(node)) {
 315  0 this.current = node;
 316  0 return this.current;
 317    }
 318    }
 319    }
 320   
 321    /**
 322    * Moves the <code>TreeWalker</code> to the next visible node in document
 323    * order relative to the current node, and returns the new node. If the
 324    * current node has no next node, or if the search for nextNode attempts
 325    * to step upward from the TreeWalker's root node, returns
 326    * <code>null</code> , and retains the current node.
 327    *
 328    * @return The new node, or <code>null</code> if the current node has no
 329    * next node in the TreeWalker's logical view.
 330    */
 331  4288 public Node nextNode() {
 332  4288 Node node = this.current;
 333  4288 while (true) {
 334  5737 if (node.hasChildNodes()) {
 335  662 node = node.getFirstChild();
 336    } else {
 337  5075 while (true) {
 338  5266 Node old = node;
 339  5266 node = node.getNextSibling();
 340  5266 if (node == null) {
 341  662 node = old;
 342  662 node = node.getParentNode();
 343  662 if (node == null || node == root) {
 344    // this.next stays the same
 345  471 return null;
 346    }
 347    } else {
 348  4604 break;
 349    }
 350    }
 351    }
 352  5266 if (node != null && acceptNode(node)) {
 353  3817 this.current = node;
 354  3817 return node;
 355    }
 356    }
 357    }
 358    }