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.Pointer;
19 import org.apache.commons.jxpath.ri.EvalContext;
20 import org.apache.commons.jxpath.ri.compiler.NodeTest;
21 import org.apache.commons.jxpath.ri.model.NodeIterator;
22 import org.apache.commons.jxpath.ri.model.NodePointer;
23
24 /***
25 * EvalContext that can walk the "child::", "following-sibling::" and
26 * "preceding-sibling::" axes.
27 *
28 * @author Dmitri Plotnikov
29 * @version $Revision: 1.16 $ $Date: 2004/03/25 03:49:50 $
30 */
31 public class ChildContext extends EvalContext {
32 private NodeTest nodeTest;
33 private boolean startFromParentLocation;
34 private boolean reverse;
35 private NodeIterator iterator;
36
37 public ChildContext(
38 EvalContext parentContext,
39 NodeTest nodeTest,
40 boolean startFromParentLocation,
41 boolean reverse)
42 {
43 super(parentContext);
44 this.nodeTest = nodeTest;
45 this.startFromParentLocation = startFromParentLocation;
46 this.reverse = reverse;
47 }
48
49 public NodePointer getCurrentNodePointer() {
50 if (position == 0) {
51 if (!setPosition(1)) {
52 return null;
53 }
54 }
55 if (iterator != null) {
56 return iterator.getNodePointer();
57 }
58 else {
59 return null;
60 }
61 }
62
63 /***
64 * This method is called on the last context on the path when only
65 * one value is needed. Note that this will return the whole property,
66 * even if it is a collection. It will not extract the first element
67 * of the collection. For example, "books" will return the collection
68 * of books rather than the first book from that collection.
69 */
70 public Pointer getSingleNodePointer() {
71 if (position == 0) {
72 while (nextSet()) {
73 prepare();
74 if (iterator == null) {
75 return null;
76 }
77
78 NodePointer pointer = iterator.getNodePointer();
79 if (pointer != null) {
80 return pointer;
81 }
82 }
83 return null;
84 }
85 return getCurrentNodePointer();
86 }
87
88 public boolean nextNode() {
89 return setPosition(getCurrentPosition() + 1);
90 }
91
92 public void reset() {
93 super.reset();
94 iterator = null;
95 }
96
97 public boolean setPosition(int position) {
98 int oldPosition = getCurrentPosition();
99 super.setPosition(position);
100 if (oldPosition == 0) {
101 prepare();
102 }
103 if (iterator == null) {
104 return false;
105 }
106 return iterator.setPosition(position);
107 }
108
109 /***
110 * Allocates a PropertyIterator.
111 */
112 private void prepare() {
113 NodePointer parent = parentContext.getCurrentNodePointer();
114 if (parent == null) {
115 return;
116 }
117 if (startFromParentLocation) {
118 NodePointer pointer = parent.getParent();
119 iterator = pointer.childIterator(nodeTest, reverse, parent);
120 }
121 else {
122 iterator = parent.childIterator(nodeTest, reverse, null);
123 }
124 }
125 }