KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jxpath > ri > axes > DescendantContext


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.axes;
17
18 import java.util.Stack JavaDoc;
19
20 import org.apache.commons.jxpath.Pointer;
21 import org.apache.commons.jxpath.ri.Compiler;
22 import org.apache.commons.jxpath.ri.EvalContext;
23 import org.apache.commons.jxpath.ri.compiler.NodeTest;
24 import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
25 import org.apache.commons.jxpath.ri.model.NodeIterator;
26 import org.apache.commons.jxpath.ri.model.NodePointer;
27
28 /**
29  * An EvalContext that walks the "descendant::" and "descendant-or-self::"
30  * axes.
31  *
32  * @author Dmitri Plotnikov
33  * @version $Revision: 1.16 $ $Date: 2004/02/29 14:17:38 $
34  */

35 public class DescendantContext extends EvalContext {
36     private NodeTest nodeTest;
37     private boolean setStarted = false;
38     private Stack JavaDoc stack;
39     private NodePointer currentNodePointer;
40     private boolean includeSelf;
41     private static final NodeTest ELEMENT_NODE_TEST =
42             new NodeTypeTest(Compiler.NODE_TYPE_NODE);
43                         
44     public DescendantContext(
45             EvalContext parentContext,
46             boolean includeSelf,
47             NodeTest nodeTest)
48     {
49         super(parentContext);
50         this.includeSelf = includeSelf;
51         this.nodeTest = nodeTest;
52     }
53
54     public boolean isChildOrderingRequired() {
55         return true;
56     }
57
58     public NodePointer getCurrentNodePointer() {
59         if (position == 0) {
60             if (!setPosition(1)) {
61                 return null;
62             }
63         }
64         return currentNodePointer;
65     }
66
67     public void reset() {
68         super.reset();
69         setStarted = false;
70     }
71
72     public boolean setPosition(int position) {
73         if (position < this.position) {
74             reset();
75         }
76
77         while (this.position < position) {
78             if (!nextNode()) {
79                 return false;
80             }
81         }
82         return true;
83     }
84
85     public boolean nextNode() {
86         if (!setStarted) {
87             setStarted = true;
88             stack = new Stack JavaDoc();
89             currentNodePointer = parentContext.getCurrentNodePointer();
90             if (currentNodePointer != null) {
91                 if (!currentNodePointer.isLeaf()) {
92                     stack.push(
93                         currentNodePointer.childIterator(
94                             ELEMENT_NODE_TEST,
95                             false,
96                             null));
97                 }
98                 if (includeSelf) {
99                     if (currentNodePointer.testNode(nodeTest)) {
100                         position++;
101                         return true;
102                     }
103                 }
104             }
105         }
106
107         while (!stack.isEmpty()) {
108             NodeIterator it = (NodeIterator) stack.peek();
109             if (it.setPosition(it.getPosition() + 1)) {
110                 currentNodePointer = it.getNodePointer();
111                 if (!isRecursive()) {
112                     if (!currentNodePointer.isLeaf()) {
113                         stack.push(
114                             currentNodePointer.childIterator(
115                                 ELEMENT_NODE_TEST,
116                                 false,
117                                 null));
118                     }
119                     if (currentNodePointer.testNode(nodeTest)) {
120                         position++;
121                         return true;
122                     }
123                 }
124             }
125             else {
126                 // We get here only if the name test failed
127
// and the iterator ended
128
stack.pop();
129             }
130         }
131         return false;
132     }
133
134     /**
135      * Checks if we are reentering a bean we have already seen and if so
136      * returns true to prevent infinite recursion.
137      */

138     private boolean isRecursive() {
139         Object JavaDoc node = currentNodePointer.getNode();
140         for (int i = stack.size() - 1; --i >= 0;) {
141             NodeIterator it = (NodeIterator) stack.get(i);
142             Pointer pointer = it.getNodePointer();
143             if (pointer != null && pointer.getNode() == node) {
144                 return true;
145             }
146         }
147         return false;
148     }
149 }
Popular Tags