KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > tinytree > SiblingEnumeration


1 package net.sf.saxon.tinytree;
2 import net.sf.saxon.om.AxisIteratorImpl;
3 import net.sf.saxon.om.Item;
4 import net.sf.saxon.om.SequenceIterator;
5 import net.sf.saxon.pattern.NodeTest;
6 import net.sf.saxon.style.StandardNames;
7 import net.sf.saxon.type.Type;
8
9 /**
10 * This class supports both the child:: and following-sibling:: axes, which are
11 * identical except for the route to the first candidate node.
12 * It enumerates either the children or the following siblings of the specified node.
13 * In the case of children, the specified node must always
14 * be a node that has children: to ensure this, construct the enumeration
15 * using NodeInfo#getEnumeration()
16 */

17
18 final class SiblingEnumeration extends AxisIteratorImpl {
19
20     private TinyTree tree;
21     private int nextNodeNr;
22     private NodeTest test;
23     private TinyNodeImpl startNode;
24     private TinyNodeImpl parentNode;
25     private boolean getChildren;
26     private boolean needToAdvance = false;
27
28     /**
29      * Return an enumeration over children or siblings of the context node
30      * @param tree The TinyTree containing the context node
31      * @param node The context node, the start point for the iteration
32      * @param nodeTest Test that the selected nodes must satisfy, or null indicating
33      * that all nodes are selected
34      * @param getChildren True if children of the context node are to be returned, false
35      * if following siblings are required
36      */

37
38     SiblingEnumeration(TinyTree tree, TinyNodeImpl node,
39                               NodeTest nodeTest, boolean getChildren) {
40         this.tree = tree;
41         test = nodeTest;
42         startNode = node;
43         this.getChildren = getChildren;
44         if (getChildren) { // child:: axis
45
parentNode = node;
46             // move to first child
47
// ASSERT: we don't invoke this code unless the node has children
48
nextNodeNr = node.nodeNr + 1;
49
50         } else { // following-sibling:: axis
51
parentNode = (TinyNodeImpl)node.getParent();
52             if (parentNode == null) {
53                 nextNodeNr = -1;
54             } else {
55                 // move to next sibling
56
nextNodeNr = tree.next[node.nodeNr];
57                 while (tree.nodeKind[nextNodeNr] == Type.PARENT_POINTER) {
58                     // skip dummy nodes
59
nextNodeNr = tree.next[nextNodeNr];
60                 }
61                 if (nextNodeNr < node.nodeNr) {
62                     // if "next" pointer goes backwards, it's really an owner pointer from the last sibling
63
nextNodeNr = -1;
64                 }
65             }
66         }
67
68         // check if this matches the conditions
69
if (nextNodeNr >= 0 && nodeTest != null) {
70             if (!nodeTest.matches(this.tree, nextNodeNr)) {
71                 needToAdvance = true;
72             }
73         }
74     }
75
76     public Item next() {
77          // if needToAdvance == false, we are already on the correct node.
78
if (needToAdvance) {
79             final int thisNode = nextNodeNr;
80             if (test==null) {
81                 do {
82                     nextNodeNr = tree.next[nextNodeNr];
83                 } while (tree.nodeKind[nextNodeNr] == Type.PARENT_POINTER);
84             } else {
85                 do {
86                     nextNodeNr = tree.next[nextNodeNr];
87                 } while ( nextNodeNr >= thisNode &&
88                         !test.matches(tree, nextNodeNr));
89             }
90
91             if (nextNodeNr < thisNode) { // indicates we've got to the last sibling
92
nextNodeNr = -1;
93                 needToAdvance = false;
94                 current = null;
95                 position = -1;
96                 return null;
97             }
98         }
99
100         if (nextNodeNr == -1) {
101             return null;
102         }
103         needToAdvance = true;
104         position++;
105
106         // if the caller only wants the atomized value, get it directly
107
// in the case where it's an untyped atomic value
108

109         if (isAtomizing() && tree.getTypeAnnotation(nextNodeNr) == StandardNames.XDT_UNTYPED) {
110             current = tree.getUntypedAtomicValue(nextNodeNr);
111             return current;
112         } else {
113             current = tree.getNode(nextNodeNr);
114             ((TinyNodeImpl)current).setParentNode(parentNode);
115             return current;
116         }
117     }
118
119     /**
120     * Get another enumeration of the same nodes
121     */

122
123     public SequenceIterator getAnother() {
124         return new SiblingEnumeration(tree, startNode, test, getChildren);
125     }
126
127 }
128
129
130 //
131
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
132
// you may not use this file except in compliance with the License. You may obtain a copy of the
133
// License at http://www.mozilla.org/MPL/
134
//
135
// Software distributed under the License is distributed on an "AS IS" basis,
136
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
137
// See the License for the specific language governing rights and limitations under the License.
138
//
139
// The Original Code is: all this file.
140
//
141
// The Initial Developer of the Original Code is Michael H. Kay.
142
//
143
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
144
//
145
// Contributor(s): none.
146
//
147
Popular Tags