001: package net.sf.saxon.tinytree;
002:
003: import net.sf.saxon.om.AxisIteratorImpl;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.om.SequenceIterator;
006: import net.sf.saxon.pattern.NodeTest;
007:
008: /**
009: * Iterate over the following axis starting at a given node.
010: * The start node must not be a namespace or attribute node.
011: */
012:
013: final class FollowingEnumeration extends AxisIteratorImpl {
014:
015: private TinyTree tree;
016: private TinyNodeImpl startNode;
017: private NodeTest test;
018: private boolean includeDescendants;
019:
020: /**
021: * Create an iterator over the following axis
022: * @param doc the containing TinyTree
023: * @param node the start node. If the actual start was an attribute or namespace node, this will
024: * be the parent element of that attribute or namespace
025: * @param nodeTest condition that all the returned nodes must satisfy
026: * @param includeDescendants true if descendants of the start node are to be included. This will
027: * be false if the actual start was an element node, true if it was an attribute or namespace node
028: * (since the children of their parent follow the attribute or namespace in document order).
029: */
030:
031: public FollowingEnumeration(TinyTree doc, TinyNodeImpl node,
032: NodeTest nodeTest, boolean includeDescendants) {
033: tree = doc;
034: test = nodeTest;
035: startNode = node;
036: this .includeDescendants = includeDescendants;
037: }
038:
039: public Item next() {
040: int nodeNr;
041: if (position == 0) {
042: // first time call
043: nodeNr = startNode.nodeNr;
044: int depth = tree.depth[nodeNr];
045:
046: // skip the descendant nodes if any
047: if (includeDescendants) {
048: nodeNr++;
049: } else {
050: do {
051: nodeNr++;
052: if (tree.depth[nodeNr] == 0) {
053: current = null;
054: position = -1;
055: return null;
056: }
057: } while (tree.depth[nodeNr] > depth);
058: }
059: } else {
060: nodeNr = ((TinyNodeImpl) current).nodeNr + 1;
061: }
062:
063: while (true) {
064: if (tree.depth[nodeNr] == 0) {
065: current = null;
066: position = -1;
067: return null;
068: }
069: if (test.matches(tree, nodeNr)) {
070: position++;
071: current = tree.getNode(nodeNr);
072: return current;
073: }
074: nodeNr++;
075: }
076: }
077:
078: /**
079: * Get another enumeration of the same nodes
080: */
081:
082: public SequenceIterator getAnother() {
083: return new FollowingEnumeration(tree, startNode, test,
084: includeDescendants);
085: }
086: }
087:
088: //
089: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
090: // you may not use this file except in compliance with the License. You may obtain a copy of the
091: // License at http://www.mozilla.org/MPL/
092: //
093: // Software distributed under the License is distributed on an "AS IS" basis,
094: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
095: // See the License for the specific language governing rights and limitations under the License.
096: //
097: // The Original Code is: all this file.
098: //
099: // The Initial Developer of the Original Code is Michael H. Kay.
100: //
101: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
102: //
103: // Contributor(s): none.
104: //
|