1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jxpath.ri.axes;
18
19 import java.util.Iterator;
20
21 import org.apache.commons.jxpath.ri.EvalContext;
22 import org.apache.commons.jxpath.ri.InfoSetUtil;
23 import org.apache.commons.jxpath.ri.compiler.Expression;
24 import org.apache.commons.jxpath.ri.compiler.NameAttributeTest;
25 import org.apache.commons.jxpath.ri.model.NodePointer;
26 import org.apache.commons.jxpath.ri.model.beans.PropertyOwnerPointer;
27 import org.apache.commons.jxpath.ri.model.beans.PropertyPointer;
28
29
30
31
32
33
34
35 public class PredicateContext extends EvalContext {
36 private Expression expression;
37 private boolean done = false;
38 private Expression nameTestExpression;
39 private PropertyPointer dynamicPropertyPointer;
40
41
42
43
44
45
46 public PredicateContext(EvalContext parentContext, Expression expression) {
47 super(parentContext);
48 this.expression = expression;
49 if (expression instanceof NameAttributeTest) {
50 nameTestExpression =
51 ((NameAttributeTest) expression).getNameTestExpression();
52 }
53 }
54
55 public boolean nextNode() {
56 if (done) {
57 return false;
58 }
59 while (parentContext.nextNode()) {
60 if (setupDynamicPropertyPointer()) {
61 Object pred = nameTestExpression.computeValue(parentContext);
62 String propertyName = InfoSetUtil.stringValue(pred);
63
64
65
66
67
68
69
70
71
72 boolean ok = false;
73 String[] names = dynamicPropertyPointer.getPropertyNames();
74 for (int i = 0; i < names.length; i++) {
75 if (names[i].equals(propertyName)) {
76 ok = true;
77 break;
78 }
79 }
80 if (ok) {
81 dynamicPropertyPointer.setPropertyName(propertyName);
82 position++;
83 return true;
84 }
85 }
86 else {
87 Object pred = expression.computeValue(parentContext);
88 if (pred instanceof Iterator) {
89 if (!((Iterator) pred).hasNext()) {
90 return false;
91 }
92 pred = ((Iterator) pred).next();
93 }
94
95 if (pred instanceof NodePointer) {
96 pred = ((NodePointer) pred).getNode();
97 }
98
99 if (pred instanceof Number) {
100 int pos = (int) InfoSetUtil.doubleValue(pred);
101 position++;
102 done = true;
103 return parentContext.setPosition(pos);
104 }
105 if (InfoSetUtil.booleanValue(pred)) {
106 position++;
107 return true;
108 }
109 }
110 }
111 return false;
112 }
113
114
115
116
117
118
119 private boolean setupDynamicPropertyPointer() {
120 if (nameTestExpression == null) {
121 return false;
122 }
123
124 NodePointer parent = parentContext.getCurrentNodePointer();
125 if (parent == null) {
126 return false;
127 }
128 parent = parent.getValuePointer();
129 if (!(parent instanceof PropertyOwnerPointer)) {
130 return false;
131 }
132 dynamicPropertyPointer =
133 (PropertyPointer) ((PropertyOwnerPointer) parent)
134 .getPropertyPointer()
135 .clone();
136 return true;
137 }
138
139 public boolean setPosition(int position) {
140 if (nameTestExpression == null) {
141 return setPositionStandard(position);
142 }
143 else {
144 if (dynamicPropertyPointer == null && !setupDynamicPropertyPointer()) {
145 return setPositionStandard(position);
146 }
147 if (position < 1
148 || position > dynamicPropertyPointer.getLength()) {
149 return false;
150 }
151 dynamicPropertyPointer.setIndex(position - 1);
152 return true;
153 }
154 }
155
156 public NodePointer getCurrentNodePointer() {
157 if (position == 0 && !setPosition(1)) {
158 return null;
159 }
160 if (dynamicPropertyPointer != null) {
161 return dynamicPropertyPointer.getValuePointer();
162 }
163 return parentContext.getCurrentNodePointer();
164 }
165
166 public void reset() {
167 super.reset();
168 parentContext.reset();
169 done = false;
170 }
171
172 public boolean nextSet() {
173 reset();
174 return parentContext.nextSet();
175 }
176
177
178
179
180
181
182 private boolean setPositionStandard(int position) {
183 if (this.position > position) {
184 reset();
185 }
186
187 while (this.position < position) {
188 if (!nextNode()) {
189 return false;
190 }
191 }
192 return true;
193 }
194 }