1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jxpath.ri.axes;
17
18 import org.apache.commons.jxpath.ri.EvalContext;
19 import org.apache.commons.jxpath.ri.compiler.NodeTest;
20 import org.apache.commons.jxpath.ri.model.NodePointer;
21
22 /***
23 * EvalContext that walks the "ancestor::" and "ancestor-or-self::" axes.
24 *
25 * @author Dmitri Plotnikov
26 * @version $Revision: 1.15 $ $Date: 2004/03/25 03:49:50 $
27 */
28 public class AncestorContext extends EvalContext {
29 private NodeTest nodeTest;
30 private boolean setStarted = false;
31 private NodePointer currentNodePointer;
32 private boolean includeSelf;
33
34 /***
35 * @param parentContext represents the previous step on the path
36 * @param includeSelf differentiates between "ancestor::" and "ancestor-
37 * or-self::" axes
38 * @param nameTest is the name of the element(s) we are looking for
39 */
40 public AncestorContext(
41 EvalContext parentContext,
42 boolean includeSelf,
43 NodeTest nodeTest)
44 {
45 super(parentContext);
46 this.includeSelf = includeSelf;
47 this.nodeTest = nodeTest;
48 }
49
50 public NodePointer getCurrentNodePointer() {
51 return currentNodePointer;
52 }
53
54 public int getDocumentOrder() {
55 return -1;
56 }
57
58 public void reset() {
59 super.reset();
60 setStarted = false;
61 }
62
63 public boolean setPosition(int position) {
64 if (position < getCurrentPosition()) {
65 reset();
66 }
67
68 while (getCurrentPosition() < position) {
69 if (!nextNode()) {
70 return false;
71 }
72 }
73 return true;
74 }
75
76 public boolean nextNode() {
77 if (!setStarted) {
78 setStarted = true;
79 currentNodePointer = parentContext.getCurrentNodePointer();
80 if (includeSelf) {
81 if (currentNodePointer.testNode(nodeTest)) {
82 position++;
83 return true;
84 }
85 }
86 }
87
88 while (true) {
89 currentNodePointer = currentNodePointer.getImmediateParentPointer();
90
91 if (currentNodePointer == null) {
92 return false;
93 }
94
95 if (currentNodePointer.testNode(nodeTest)) {
96 position++;
97 return true;
98 }
99 }
100 }
101 }