    1   /*
    2    * Copyright 1999-2004 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jxpath.ri.model.dom;
    17
    18  import org.apache.commons.jxpath.ri.compiler.NodeTest;
    19  import org.apache.commons.jxpath.ri.model.NodeIterator;
    20  import org.apache.commons.jxpath.ri.model.NodePointer;
    21  import org.w3c.dom.Node;
    22
    23  /***
    24   * An iterator of children of a DOM Node.
    25   *
    26   * @author Dmitri Plotnikov
    27   * @version $Revision: 1.11 $ $Date: 2004/04/01 02:55:32 $
    28   */
    29  public class DOMNodeIterator implements NodeIterator {
    30      private NodePointer parent;
    31      private NodeTest nodeTest;
    32      private Node node;
    33      private Node child = null;
    34      private boolean reverse;
    35      private int position = 0;
    36
    37      public DOMNodeIterator(
    38          NodePointer parent,
    39          NodeTest nodeTest,
    40          boolean reverse,
    41          NodePointer startWith)
    42      {
    43          this.parent = parent;
    44          this.node = (Node) parent.getNode();
    45          if (startWith != null) {
    46              this.child = (Node) startWith.getNode();
    47          }
    48          this.nodeTest = nodeTest;
    49          this.reverse = reverse;
    50      }
    51
    52      public NodePointer getNodePointer() {
    53          if (position == 0) {
    54              setPosition(1);
    55          }
    56          if (child == null) {
    57              return null;
    58          }
    59          return new DOMNodePointer(parent, child);
    60      }
    61
    62      public int getPosition() {
    63          return position;
    64      }
    65
    66      public boolean setPosition(int position) {
    67          while (this.position < position) {
    68              if (!next()) {
    69                  return false;
    70              }
    71          }
    72          while (this.position > position) {
    73              if (!previous()) {
    74                  return false;
    75              }
    76          }
    77          return true;
    78      }
    79
    80      private boolean previous() {
    81          position--;
    82          if (!reverse) {
    83              if (position == 0) {
    84                  child = null;
    85              }
    86              else if (child == null) {
    87                  child = node.getLastChild();
    88              }
    89              else {
    90                  child = child.getPreviousSibling();
    91              }
    92              while (child != null && !testChild()) {
    93                  child = child.getPreviousSibling();
    94              }
    95          }
    96          else {
    97              child = child.getNextSibling();
    98              while (child != null && !testChild()) {
    99                  child = child.getNextSibling();
    100             }
    101         }
    102         return child != null;
    103     }
    104
    105     private boolean next() {
    106         position++;
    107         if (!reverse) {
    108             if (position == 1) {
    109                 if (child == null) {
    110                     child = node.getFirstChild();
    111                 }
    112                 else {
    113                     child = child.getNextSibling();
    114                 }
    115             }
    116             else {
    117                 child = child.getNextSibling();
    118             }
    119             while (child != null && !testChild()) {
    120                 child = child.getNextSibling();
    121             }
    122         }
    123         else {
    124             if (position == 1) {
    125                 if (child == null) {
    126                     child = node.getLastChild();
    127                 }
    128                 else {
    129                     child = child.getPreviousSibling();
    130                 }
    131             }
    132             else {
    133                 child = child.getPreviousSibling();
    134             }
    135             while (child != null && !testChild()) {
    136                 child = child.getPreviousSibling();
    137             }
    138         }
    139         return child != null;
    140     }
    141
    142     private boolean testChild() {
    143         return DOMNodePointer.testNode(child, nodeTest);
    144     }
    145 }