You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xindice-dev@xml.apache.org by vg...@apache.org on 2004/08/27 18:13:39 UTC

cvs commit: xml-xindice/java/tests/src/org/apache/xindice/xml/dom TreeWalkerTest.java

vgritsenko    2004/08/27 09:13:39

  Modified:    .        status.xml
               java/src/org/apache/xindice/xml/dom/traversal
                        TreeWalkerImpl.java
  Added:       java/tests/src/org/apache/xindice/xml/dom
                        TreeWalkerTest.java
  Log:
  Fix TreeWalker implementation. Add unit test.
  
  Revision  Changes    Path
  1.47      +4 -0      xml-xindice/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/xml-xindice/status.xml,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- status.xml	27 Aug 2004 15:55:29 -0000	1.46
  +++ status.xml	27 Aug 2004 16:13:39 -0000	1.47
  @@ -74,6 +74,10 @@
   
       <changes>
           <release version="1.1b5-dev">
  +            <action dev="VG" type="fix">
  +                Fixed bugs in TreeWalkerImpl, methods getRoot, getCurrentNode,
  +                nextNode, previousNode. Added TreeWalker unit test.
  +            </action>
               <action dev="VG" type="update">
                   Make SymbolTableSymbols singleton.
               </action>
  
  
  
  1.9       +100 -93   xml-xindice/java/src/org/apache/xindice/xml/dom/traversal/TreeWalkerImpl.java
  
  Index: TreeWalkerImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xindice/java/src/org/apache/xindice/xml/dom/traversal/TreeWalkerImpl.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- TreeWalkerImpl.java	8 Feb 2004 03:11:57 -0000	1.8
  +++ TreeWalkerImpl.java	27 Aug 2004 16:13:39 -0000	1.9
  @@ -32,28 +32,24 @@
    * @version CVS $Revision$, $Date$
    */
   public final class TreeWalkerImpl implements TreeWalker, NodeIterator {
  -    protected boolean valid = true;
  -    protected Node root = null;
  -    protected Node next = null;
  -    protected int whatToShow = NodeFilter.SHOW_ALL;
  -    protected NodeFilter filter = null;
  -    protected boolean expand = false;
  +    protected boolean valid;
  +    protected Node root;
  +    protected Node current;
  +    protected int whatToShow;
  +    protected NodeFilter filter;
  +    protected boolean expand;
   
   
       public TreeWalkerImpl(Node root, int whatToShow, NodeFilter filter, boolean entityReferenceExpansion) throws DOMException {
  -        this.root = null;
  -        next = root;
  +        this.valid = true;
  +        this.root = root;
  +        this.current = root;
           this.whatToShow = whatToShow;
           this.filter = filter;
           this.expand = entityReferenceExpansion;
  -        if (acceptNode(root)) {
  -            next = root;
  -        } else {
  -            nextNode();
  -        }
       }
   
  -    public int getShowType(Node node) {
  +    private int getShowType(Node node) {
           switch (node.getNodeType()) {
               case Node.ATTRIBUTE_NODE:
                   return NodeFilter.SHOW_ATTRIBUTE;
  @@ -84,20 +80,20 @@
           }
       }
   
  -    public boolean acceptNode(Node node) {
  +    private boolean acceptNode(Node node) {
           return ((getShowType(node) & whatToShow) > 0)
                   && (filter == null || filter.acceptNode(node) == NodeFilter.FILTER_ACCEPT);
       }
   
       /**
  -     *  The root node of the Iterator, as specified when it was created.
  +     * The root node of the Iterator, as specified when it was created.
        */
       public Node getRoot() {
           return root;
       }
   
       /**
  -     *  This attribute determines which node types are presented via the
  +     * This attribute determines which node types are presented via the
        * iterator. The available set of constants is defined in the
        * <code>NodeFilter</code> interface.
        */
  @@ -106,17 +102,18 @@
       }
   
       /**
  -     *  The filter used to screen nodes.
  +     * The filter used to screen nodes.
        */
       public NodeFilter getFilter() {
           return filter;
       }
   
       /**
  -     *  The value of this flag determines whether the children of entity
  +     * The value of this flag determines whether the children of entity
        * reference nodes are visible to the iterator. If false, they will be
        * skipped over.
  -     * <br> To produce a view of the document that has entity references
  +     *
  +     * <br>To produce a view of the document that has entity references
        * expanded and does not expose the entity reference node itself, use the
        * whatToShow flags to hide the entity reference node and set
        * expandEntityReferences to true when creating the iterator. To produce
  @@ -129,7 +126,7 @@
       }
   
       /**
  -     *  Detaches the iterator from the set which it iterated over, releasing
  +     * Detaches the iterator from the set which it iterated over, releasing
        * any computational resources and placing the iterator in the INVALID
        * state. After<code>detach</code> has been invoked, calls to
        * <code>nextNode</code> or<code>previousNode</code> will raise the
  @@ -140,8 +137,9 @@
       }
   
       /**
  -     *  The node at which the TreeWalker is currently positioned.
  -     * <br> The value must not be null. Alterations to the DOM tree may cause
  +     * The node at which the TreeWalker is currently positioned.
  +     *
  +     * <br>The value must not be null. Alterations to the DOM tree may cause
        * the current node to no longer be accepted by the TreeWalker's
        * associated filter. currentNode may also be explicitly set to any node,
        * whether or not it is within the subtree specified by the root node or
  @@ -149,31 +147,37 @@
        * traversal occurs relative to currentNode even if it is not part of the
        * current view by applying the filters in the requested direction (not
        * changing currentNode where no traversal is possible).
  +     *
        * @exception DOMException
        *    NOT_SUPPORTED_ERR: Raised if the specified <code>currentNode</code>
        *   is<code>null</code> .
        */
       public Node getCurrentNode() {
  -        return next;
  +        return current;
       }
   
       public void setCurrentNode(Node currentNode) throws DOMException {
           if (!valid) {
               throw NodeImpl.EX_INVALID_STATE;
           }
  -        next = currentNode;
  +        if (currentNode == null) {
  +            throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
  +                                   "Current node can not be set to null.");
  +        }
  +        this.current = currentNode;
       }
   
       /**
  -     *  Moves to and returns the closest visible ancestor node of the current
  +     * Moves to and returns the closest visible ancestor node of the current
        * node. If the search for parentNode attempts to step upward from the
        * TreeWalker's root node, or if it fails to find a visible ancestor
        * node, this method retains the current position and returns null.
  +     *
        * @return  The new parent node, or null if the current node has no parent
  -     *   in the TreeWalker's logical view.
  +     *          in the TreeWalker's logical view.
        */
       public Node parentNode() {
  -        Node node = next;
  +        Node node = this.current;
           while (node != null) {
               if (node == root) {
                   return null;
  @@ -182,119 +186,133 @@
               if (node == null) {
                   return null;
               } else if (acceptNode(node)) {
  -                next = node;
  -                return next;
  +                this.current = node;
  +                return this.current;
               }
           }
           return null;
       }
   
       /**
  -     *  Moves the <code>TreeWalker</code> to the first visible child of the
  +     * Moves the <code>TreeWalker</code> to the first visible child of the
        * current node, and returns the new node. If the current node has no
        * visible children, returns <code>null</code> , and retains the current
        * node.
  +     *
        * @return  The new node, or <code>null</code> if the current node has no
  -     *   visible children in the TreeWalker's logical view.
  +     *          visible children in the TreeWalker's logical view.
        */
       public Node firstChild() {
  -        Node node = next.getFirstChild();
  +        Node node = this.current.getFirstChild();
           while (node != null) {
               if (acceptNode(node)) {
  -                next = node;
  -                return next;
  -            } else
  -                node = node.getNextSibling();
  +                this.current = node;
  +                return this.current;
  +            }
  +
  +            node = node.getNextSibling();
           }
           return null;
       }
   
       /**
  -     *  Moves the <code>TreeWalker</code> to the last visible child of the
  +     * Moves the <code>TreeWalker</code> to the last visible child of the
        * current node, and returns the new node. If the current node has no
        * visible children, returns <code>null</code> , and retains the current
        * node.
  +     *
        * @return  The new node, or <code>null</code> if the current node has no
  -     *   children  in the TreeWalker's logical view.
  +     *          children  in the TreeWalker's logical view.
        */
       public Node lastChild() {
  -        Node node = next.getLastChild();
  +        Node node = this.current.getLastChild();
           while (node != null) {
               if (acceptNode(node)) {
  -                next = node;
  -                return next;
  -            } else
  -                node = node.getPreviousSibling();
  +                this.current = node;
  +                return this.current;
  +            }
  +
  +            node = node.getPreviousSibling();
           }
           return null;
       }
   
       /**
  -     *  Moves the <code>TreeWalker</code> to the previous sibling of the
  +     * Moves the <code>TreeWalker</code> to the previous sibling of the
        * current node, and returns the new node. If the current node has no
        * visible previous sibling, returns <code>null</code> , and retains the
        * current node.
  +     *
        * @return  The new node, or <code>null</code> if the current node has no
  -     *   previous sibling in the TreeWalker's logical view.
  +     *          previous sibling in the TreeWalker's logical view.
        */
       public Node previousSibling() {
  -        Node node = next.getPreviousSibling();
  +        Node node = this.current.getPreviousSibling();
           while (node != null) {
               if (acceptNode(node)) {
  -                next = node;
  -                return next;
  -            } else
  -                node = node.getPreviousSibling();
  +                this.current = node;
  +                return this.current;
  +            }
  +
  +            node = node.getPreviousSibling();
           }
           return null;
       }
   
       /**
  -     *  Moves the <code>TreeWalker</code> to the next sibling of the current
  +     * Moves the <code>TreeWalker</code> to the next sibling of the current
        * node, and returns the new node. If the current node has no visible
        * next sibling, returns <code>null</code> , and retains the current node.
  +     *
        * @return  The new node, or <code>null</code> if the current node has no
  -     *   next sibling in the TreeWalker's logical view.
  +     *          next sibling in the TreeWalker's logical view.
        */
       public Node nextSibling() {
  -        Node node = next.getNextSibling();
  +        Node node = this.current.getNextSibling();
           while (node != null) {
               if (acceptNode(node)) {
  -                next = node;
  -                return next;
  -            } else {
  -                node = node.getNextSibling();
  +                this.current = node;
  +                return this.current;
               }
  +
  +            node = node.getNextSibling();
           }
           return null;
       }
   
       /**
  -     *  Moves the <code>TreeWalker</code> to the previous visible node in
  +     * Moves the <code>TreeWalker</code> to the previous visible node in
        * document order relative to the current node, and returns the new node.
        * If the current node has no previous node,  or if the search for
        * previousNode attempts to step upward from the TreeWalker's root node,
        * returns <code>null</code> , and retains the current node.
  +     *
        * @return  The new node, or <code>null</code> if the current node has no
  -     *   previous node in the TreeWalker's logical view.
  +     *          previous node in the TreeWalker's logical view.
        */
       public Node previousNode() {
  -        Node node = next;
  +        Node node = this.current;
           while (true) {
  -            node = node.getPreviousSibling();
  -            if (node == null) {
  -                node = node.getParentNode();
  +            Node tmp = node.getPreviousSibling();
  +            if (tmp == null) {
  +                if (node == root) {
  +                    // Do not go out of the root
  +                    return null;
  +                }
  +
  +                tmp = node.getParentNode();
               } else {
  -                while (node.hasChildNodes()) {
  -                    node = node.getLastChild();
  +                while (tmp.hasChildNodes()) {
  +                    tmp = tmp.getLastChild();
                   }
               }
  -            
  -            if (node != null && acceptNode(node)) {
  -                next = node;
  -                return next;
  -            } else if (node == null) {
  +            node = tmp;
  +
  +            if (node == null) {
                   return null;
  +            } else if (acceptNode(node)) {
  +                this.current = node;
  +                return this.current;
               }
           }
       }
  @@ -305,18 +323,12 @@
        * current node has no next node,  or if the search for nextNode attempts
        * to step upward from the TreeWalker's root node, returns
        * <code>null</code> , and retains the current node.
  +     *
        * @return  The new node, or <code>null</code> if the current node has no
  -     *   next node  in the TreeWalker's logical view.
  +     *          next node  in the TreeWalker's logical view.
        */
       public Node nextNode() {
  -        Node result = null;
  -        if (next != null) {
  -            result = next;
  -        } else {
  -            return null;
  -        }
  -        
  -        Node node = next;
  +        Node node = this.current;
           while (true) {
               if (node.hasChildNodes()) {
                   node = node.getFirstChild();
  @@ -326,24 +338,19 @@
                       node = node.getNextSibling();
                       if (node == null) {
                           node = old;
  -                        /*
  -                        if ( node == root ) {
  -                           next = null;
  -                           return result;
  -                        }
  -                         */
                           node = node.getParentNode();
                           if (node == null || node == root) {
  -                            next = null;
  -                            return result;
  +                            // this.next stays the same
  +                            return null;
                           }
  -                    } else
  +                    } else {
                           break;
  +                    }
                   }
               }
               if (node != null && acceptNode(node)) {
  -                next = node;
  -                return result;
  +                this.current = node;
  +                return node;
               }
           }
       }
  
  
  
  1.1                  xml-xindice/java/tests/src/org/apache/xindice/xml/dom/TreeWalkerTest.java
  
  Index: TreeWalkerTest.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   *
   * 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.
   *
   * CVS $Id: TreeWalkerTest.java,v 1.1 2004/08/27 16:13:39 vgritsenko Exp $
   */
  
  package org.apache.xindice.xml.dom;
  
  import org.apache.xindice.xml.dom.traversal.TreeWalkerImpl;
  
  import junit.framework.TestCase;
  import org.w3c.dom.Node;
  import org.w3c.dom.traversal.NodeFilter;
  import org.w3c.dom.traversal.TreeWalker;
  
  /**
   * Tests TreeWalker class
   *
   * @version CVS $Revision: 1.1 $, $Date: 2004/08/27 16:13:39 $
   */
  public class TreeWalkerTest extends TestCase {
  
      private static final String XML =
              "<a>" +
                "<b/>" +
                "<c>" +
                  "<d>" +
                    "<e/>" +
                    "<f/>" +
                  "</d>" +
                  "<g/>" +
                  "<h/>" +
                "</c>" +
                "<i/>" +
              "</a>";
  
      private Node dom;
  
      public void setUp() throws Exception {
          dom = DOMParser.toDocument(XML).getDocumentElement();
      }
  
      public void testRootNode() throws Exception {
          TreeWalker tw = new TreeWalkerImpl(dom, NodeFilter.SHOW_ALL, null, false);
          assertEquals("a", tw.getRoot().getLocalName());
      }
  
      public void testNextNode() throws Exception {
          TreeWalker tw = new TreeWalkerImpl(dom, NodeFilter.SHOW_ALL, null, false);
          assertEquals("a", tw.getCurrentNode().getLocalName());
  
          assertEquals("b", tw.nextNode().getLocalName());
          assertEquals("c", tw.nextNode().getLocalName());
          assertEquals("d", tw.nextNode().getLocalName());
          assertEquals("e", tw.nextNode().getLocalName());
          assertEquals("f", tw.nextNode().getLocalName());
          assertEquals("g", tw.nextNode().getLocalName());
          assertEquals("h", tw.nextNode().getLocalName());
          assertEquals("i", tw.nextNode().getLocalName());
          assertEquals(null, tw.nextNode());
      }
  
      public void testPreviousNode() throws Exception {
          TreeWalker tw = new TreeWalkerImpl(dom, NodeFilter.SHOW_ALL, null, false);
          tw.setCurrentNode(dom.getLastChild());
          assertEquals("i", tw.getCurrentNode().getLocalName());
  
          assertEquals("h", tw.previousNode().getLocalName());
          assertEquals("g", tw.previousNode().getLocalName());
          assertEquals("f", tw.previousNode().getLocalName());
          assertEquals("e", tw.previousNode().getLocalName());
          assertEquals("d", tw.previousNode().getLocalName());
          assertEquals("c", tw.previousNode().getLocalName());
          assertEquals("b", tw.previousNode().getLocalName());
          assertEquals("a", tw.previousNode().getLocalName());
          assertEquals(null, tw.previousNode());
      }
  
      public void testCurrentNode() throws Exception {
          TreeWalker tw = new TreeWalkerImpl(dom, NodeFilter.SHOW_ALL, null, false);
  
          assertEquals("a", tw.getCurrentNode().getLocalName());
          assertEquals(null, tw.previousNode());
          assertEquals("a", tw.getCurrentNode().getLocalName());
  
          tw.setCurrentNode(dom.getLastChild());
          assertEquals("i", tw.getCurrentNode().getLocalName());
          assertEquals(null, tw.nextNode());
          assertEquals("i", tw.getCurrentNode().getLocalName());
      }
  }