001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jxpath.ri.model.dom;
017:
018: import org.apache.commons.jxpath.ri.compiler.NodeTest;
019: import org.apache.commons.jxpath.ri.model.NodeIterator;
020: import org.apache.commons.jxpath.ri.model.NodePointer;
021: import org.w3c.dom.Node;
022:
023: /**
024: * An iterator of children of a DOM Node.
025: *
026: * @author Dmitri Plotnikov
027: * @version $Revision: 1.11 $ $Date: 2004/04/01 02:55:32 $
028: */
029: public class DOMNodeIterator implements NodeIterator {
030: private NodePointer parent;
031: private NodeTest nodeTest;
032: private Node node;
033: private Node child = null;
034: private boolean reverse;
035: private int position = 0;
036:
037: public DOMNodeIterator(NodePointer parent, NodeTest nodeTest,
038: boolean reverse, NodePointer startWith) {
039: this .parent = parent;
040: this .node = (Node) parent.getNode();
041: if (startWith != null) {
042: this .child = (Node) startWith.getNode();
043: }
044: this .nodeTest = nodeTest;
045: this .reverse = reverse;
046: }
047:
048: public NodePointer getNodePointer() {
049: if (position == 0) {
050: setPosition(1);
051: }
052: if (child == null) {
053: return null;
054: }
055: return new DOMNodePointer(parent, child);
056: }
057:
058: public int getPosition() {
059: return position;
060: }
061:
062: public boolean setPosition(int position) {
063: while (this .position < position) {
064: if (!next()) {
065: return false;
066: }
067: }
068: while (this .position > position) {
069: if (!previous()) {
070: return false;
071: }
072: }
073: return true;
074: }
075:
076: private boolean previous() {
077: position--;
078: if (!reverse) {
079: if (position == 0) {
080: child = null;
081: } else if (child == null) {
082: child = node.getLastChild();
083: } else {
084: child = child.getPreviousSibling();
085: }
086: while (child != null && !testChild()) {
087: child = child.getPreviousSibling();
088: }
089: } else {
090: child = child.getNextSibling();
091: while (child != null && !testChild()) {
092: child = child.getNextSibling();
093: }
094: }
095: return child != null;
096: }
097:
098: private boolean next() {
099: position++;
100: if (!reverse) {
101: if (position == 1) {
102: if (child == null) {
103: child = node.getFirstChild();
104: } else {
105: child = child.getNextSibling();
106: }
107: } else {
108: child = child.getNextSibling();
109: }
110: while (child != null && !testChild()) {
111: child = child.getNextSibling();
112: }
113: } else {
114: if (position == 1) {
115: if (child == null) {
116: child = node.getLastChild();
117: } else {
118: child = child.getPreviousSibling();
119: }
120: } else {
121: child = child.getPreviousSibling();
122: }
123: while (child != null && !testChild()) {
124: child = child.getPreviousSibling();
125: }
126: }
127: return child != null;
128: }
129:
130: private boolean testChild() {
131: return DOMNodePointer.testNode(child, nodeTest);
132: }
133: }
|