1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jxpath.ri.axes;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23
24 import java.util.HashMap;
25
26 import org.apache.commons.jxpath.JXPathContext;
27 import org.apache.commons.jxpath.NestedTestBean;
28 import org.apache.commons.jxpath.Pointer;
29 import org.apache.commons.jxpath.TestNull;
30 import org.apache.commons.jxpath.ri.model.NodePointer;
31 import org.apache.commons.jxpath.ri.model.VariablePointer;
32 import org.apache.commons.jxpath.ri.model.beans.BeanPointer;
33 import org.apache.commons.jxpath.ri.model.beans.BeanPropertyPointer;
34 import org.apache.commons.jxpath.ri.model.beans.CollectionPointer;
35 import org.apache.commons.jxpath.ri.model.beans.NullElementPointer;
36 import org.apache.commons.jxpath.ri.model.beans.NullPointer;
37 import org.apache.commons.jxpath.ri.model.beans.NullPropertyPointer;
38 import org.apache.commons.jxpath.ri.model.beans.TestBeanFactory;
39 import org.apache.commons.jxpath.ri.model.dom.DOMNodePointer;
40 import org.apache.commons.jxpath.ri.model.dynamic.DynamicPointer;
41 import org.apache.commons.jxpath.ri.model.dynamic.DynamicPropertyPointer;
42 import org.junit.jupiter.api.BeforeEach;
43 import org.junit.jupiter.api.Test;
44
45 public class SimplePathInterpreterTest {
46
47 private TestBeanWithNode bean;
48 private JXPathContext context;
49
50 private void assertNullPointer(final String path, final String expectedPath, final String expectedSignature) {
51 final Pointer pointer = context.getPointer(path);
52 assertNotNull(pointer, "Null path exists: " + path);
53 assertEquals(expectedPath, pointer.asPath(), "Null path as path: " + path);
54 assertEquals(expectedSignature, pointerSignature(pointer), "Checking Signature: " + path);
55 final Pointer vPointer = ((NodePointer) pointer).getValuePointer();
56 assertFalse(((NodePointer) vPointer).isActual(), "Null path is null: " + path);
57 assertEquals(expectedSignature + "N", pointerSignature(vPointer), "Checking value pointer signature: " + path);
58 }
59
60 private void assertValueAndPointer(final String path, final Object expectedValue, final String expectedPath, final String expectedSignature) {
61 assertValueAndPointer(path, expectedValue, expectedPath, expectedSignature, expectedSignature);
62 }
63
64 private void assertValueAndPointer(final String path, final Object expectedValue, final String expectedPath, final String expectedSignature,
65 final String expectedValueSignature) {
66 final Object value = context.getValue(path);
67 assertEquals(expectedValue, value, "Checking value: " + path);
68 final Pointer pointer = context.getPointer(path);
69 assertEquals(expectedPath, pointer.toString(), "Checking pointer: " + path);
70 assertEquals(expectedSignature, pointerSignature(pointer), "Checking signature: " + path);
71 final Pointer vPointer = ((NodePointer) pointer).getValuePointer();
72 assertEquals(expectedValueSignature, pointerSignature(vPointer), "Checking value pointer signature: " + path);
73 }
74
75
76
77
78
79 private String pointerSignature(final Pointer pointer) {
80 if (pointer == null) {
81 return "";
82 }
83 char type = '?';
84 if (pointer instanceof NullPointer) {
85 type = 'N';
86 } else if (pointer instanceof NullPropertyPointer) {
87 type = 'n';
88 } else if (pointer instanceof NullElementPointer) {
89 type = 'E';
90 } else if (pointer instanceof VariablePointer) {
91 type = 'V';
92 } else if (pointer instanceof CollectionPointer) {
93 type = 'C';
94 } else if (pointer instanceof BeanPointer) {
95 type = 'B';
96 } else if (pointer instanceof BeanPropertyPointer) {
97 type = 'b';
98 } else if (pointer instanceof DynamicPointer) {
99 type = 'D';
100 } else if (pointer instanceof DynamicPropertyPointer) {
101 type = 'd';
102 } else if (pointer instanceof DOMNodePointer) {
103 type = 'M';
104 } else {
105 System.err.println("UNKNOWN TYPE: " + pointer.getClass());
106 }
107 final NodePointer parent = ((NodePointer) pointer).getImmediateParentPointer();
108 return pointerSignature(parent) + type;
109 }
110
111 @BeforeEach
112 protected void setUp() throws Exception {
113 bean = TestBeanWithNode.createTestBeanWithDOM();
114 final HashMap submap = new HashMap();
115 submap.put("key", new NestedTestBean("Name 9"));
116 submap.put("strings", bean.getNestedBean().getStrings());
117 bean.getList().add(new int[] { 1, 2 });
118 bean.getList().add(bean.getVendor());
119 bean.getMap().put("Key3", new Object[] { new NestedTestBean("some"), Integer.valueOf(2), bean.getVendor(), submap });
120 bean.getMap().put("Key4", bean.getVendor());
121 bean.getMap().put("Key5", submap);
122 bean.getMap().put("Key6", new Object[0]);
123 context = JXPathContext.newContext(null, bean);
124 context.setLenient(true);
125 context.setFactory(new TestBeanFactory());
126 }
127
128 @Test
129 public void testDoPredicateIndex() {
130
131 assertValueAndPointer("/map[@name='Key2'][@name='strings'][2]", "String 2", "/map[@name='Key2']/strings[2]", "BbDdBb", "BbDdBbB");
132
133 assertValueAndPointer("/nestedBean[@name='strings'][2]", bean.getNestedBean().getStrings()[1], "/nestedBean/strings[2]", "BbBb", "BbBbB");
134
135 assertNullPointer("/nestedBean[@name='foo'][3]", "/nestedBean[@name='foo'][3]", "BbBn");
136
137 assertNullPointer("/nestedBean[@name='strings'][5]", "/nestedBean/strings[5]", "BbBbE");
138
139 assertValueAndPointer("/map[@name='Key3'][2]", Integer.valueOf(2), "/map[@name='Key3'][2]", "BbDd", "BbDdB");
140
141 assertNullPointer("/map[@name='Key3'][5]", "/map[@name='Key3'][5]", "BbDdE");
142
143 assertNullPointer("/map[@name='Key3'][5]/foo", "/map[@name='Key3'][5]/foo", "BbDdENn");
144
145 assertValueAndPointer("/map[@name='Key5'][@name='strings'][2]", "String 2", "/map[@name='Key5'][@name='strings'][2]", "BbDdDd", "BbDdDdB");
146
147 assertNullPointer("/map[@name='Key5'][@name='strings'][5]", "/map[@name='Key5'][@name='strings'][5]", "BbDdDdE");
148
149 assertValueAndPointer("/map[@name='Key3'][2]", Integer.valueOf(2), "/map[@name='Key3'][2]", "BbDd", "BbDdB");
150
151 assertValueAndPointer("/map[@name='Key3'][1]/name", "some", "/map[@name='Key3'][1]/name", "BbDdBb", "BbDdBbB");
152
153 assertNullPointer("/map[@name='foo'][3]", "/map[@name='foo'][3]", "BbDdE");
154
155 assertValueAndPointer("/integers[2]", Integer.valueOf(2), "/integers[2]", "Bb", "BbB");
156
157 assertValueAndPointer("/nestedBean/strings[2]", bean.getNestedBean().getStrings()[1], "/nestedBean/strings[2]", "BbBb", "BbBbB");
158
159 assertValueAndPointer("/list[3]/int", Integer.valueOf(1), "/list[3]/int", "BbBb", "BbBbB");
160
161 assertNullPointer("/list[6]", "/list[6]", "BbE");
162
163 assertNullPointer("/nestedBean/foo[3]", "/nestedBean/foo[3]", "BbBn");
164
165 assertNullPointer("/map/foo[3]", "/map[@name='foo'][3]", "BbDdE");
166
167 assertNullPointer("/nestedBean/strings[5]", "/nestedBean/strings[5]", "BbBbE");
168
169 assertNullPointer("/map/Key3[5]/foo", "/map[@name='Key3'][5]/foo", "BbDdENn");
170
171 assertValueAndPointer("/map[@name='Key5']/strings[2]", "String 2", "/map[@name='Key5'][@name='strings'][2]", "BbDdDd", "BbDdDdB");
172
173 assertNullPointer("/map[@name='Key5']/strings[5]", "/map[@name='Key5'][@name='strings'][5]", "BbDdDdE");
174
175 assertValueAndPointer("/int[1]", Integer.valueOf(1), "/int", "Bb", "BbB");
176
177 assertValueAndPointer(".[1]/int", Integer.valueOf(1), "/int", "Bb", "BbB");
178 }
179
180 @Test
181 public void testDoPredicateName() {
182
183 assertValueAndPointer("/nestedBean[@name='int']", Integer.valueOf(1), "/nestedBean/int", "BbBb", "BbBbB");
184
185 assertValueAndPointer("/.[@name='int']", Integer.valueOf(1), "/int", "Bb", "BbB");
186
187 assertValueAndPointer("/map[@name='Key1']", "Value 1", "/map[@name='Key1']", "BbDd", "BbDdB");
188
189 assertValueAndPointer("/nestedBean[@name='strings']", bean.getNestedBean().getStrings(), "/nestedBean/strings", "BbBb", "BbBbC");
190
191 assertNullPointer("/nestedBean[@name='foo']", "/nestedBean[@name='foo']", "BbBn");
192
193 assertValueAndPointer("/map[@name='Key3']", bean.getMap().get("Key3"), "/map[@name='Key3']", "BbDd", "BbDdC");
194
195 assertNullPointer("/map[@name='foo']", "/map[@name='foo']", "BbDd");
196
197 assertValueAndPointer("/list[@name='fruitco']", context.getValue("/vendor"), "/list[5]", "BbCM");
198
199 assertValueAndPointer("/map/Key3[@name='key']/name", "Name 9", "/map[@name='Key3'][4][@name='key']/name", "BbDdCDdBb", "BbDdCDdBbB");
200
201 assertValueAndPointer("map/Key3[@name='fruitco']", context.getValue("/vendor"), "/map[@name='Key3'][3]", "BbDdCM");
202
203 assertValueAndPointer("/vendor[@name='fruitco']", context.getValue("/vendor"), "/vendor", "BbM");
204
205 assertNullPointer("/vendor[@name='foo']", "/vendor[@name='foo']", "BbMn");
206 assertNullPointer("/vendor[@name='foo'][3]", "/vendor[@name='foo'][3]", "BbMn");
207
208 assertNullPointer("/nestedBean[@name='foo']/bar", "/nestedBean[@name='foo']/bar", "BbBnNn");
209
210 assertNullPointer("/map[@name='foo']/bar", "/map[@name='foo']/bar", "BbDdNn");
211
212 assertNullPointer("/vendor[@name='foo']/bar", "/vendor[@name='foo']/bar", "BbMnNn");
213
214 assertNullPointer("/vendor[@name='foo'][3]/bar", "/vendor[@name='foo'][3]/bar", "BbMnNn");
215
216 assertValueAndPointer("/map[@name='Key2'][@name='name']", "Name 6", "/map[@name='Key2']/name", "BbDdBb", "BbDdBbB");
217
218 assertValueAndPointer("/map[@name='Key2'][@name='strings'][2]", "String 2", "/map[@name='Key2']/strings[2]", "BbDdBb", "BbDdBbB");
219
220 assertValueAndPointer("map[@name='Key5'][@name='key']/name", "Name 9", "/map[@name='Key5'][@name='key']/name", "BbDdDdBb", "BbDdDdBbB");
221 assertNullPointer("map[@name='Key2'][@name='foo']", "/map[@name='Key2'][@name='foo']", "BbDdBn");
222 assertNullPointer("map[@name='Key2'][@name='foo'][@name='bar']", "/map[@name='Key2'][@name='foo'][@name='bar']", "BbDdBnNn");
223
224 assertValueAndPointer("map[@name='Key4'][@name='fruitco']", context.getValue("/vendor"), "/map[@name='Key4']", "BbDdM");
225 }
226
227 @Test
228 public void testDoPredicatesStandard() {
229
230 assertValueAndPointer("map[@name='Key3'][@name='fruitco']", context.getValue("/vendor"), "/map[@name='Key3'][3]", "BbDdCM");
231
232 assertNullPointer("map[@name='Key3'][@name='foo']", "/map[@name='Key3'][4][@name='foo']", "BbDdCDd");
233
234 assertValueAndPointer("map[@name='Key4'][@name='fruitco']", context.getValue("/vendor"), "/map[@name='Key4']", "BbDdM");
235
236 assertNullPointer("map[@name='Key6'][@name='fruitco']", "/map[@name='Key6'][@name='fruitco']", "BbDdCn");
237
238 assertValueAndPointer("/vendor/contact[@name='jack'][2]", "Jack Black", "/vendor/contact[4]", "BbMM");
239
240 assertNullPointer("/vendor/contact[@name='jack'][5]", "/vendor/contact[@name='jack'][5]", "BbMnNn");
241
242 assertValueAndPointer("/vendor/contact/.[@name='jack']", "Jack", "/vendor/contact[2]", "BbMM");
243 }
244
245 @Test
246 public void testDoStepNoPredicatesPropertyOwner() {
247
248 assertValueAndPointer("/int", Integer.valueOf(1), "/int", "Bb", "BbB");
249
250 assertValueAndPointer("/./int", Integer.valueOf(1), "/int", "Bb", "BbB");
251
252 assertNullPointer("/foo", "/foo", "Bn");
253
254 assertValueAndPointer("/nestedBean/int", Integer.valueOf(1), "/nestedBean/int", "BbBb", "BbBbB");
255
256 assertValueAndPointer("/nestedBean/strings", bean.getNestedBean().getStrings(), "/nestedBean/strings", "BbBb", "BbBbC");
257
258 assertNullPointer("/nestedBean/foo", "/nestedBean/foo", "BbBn");
259
260 assertNullPointer("/map/foo", "/map[@name='foo']", "BbDd");
261
262 assertValueAndPointer("/list/int", Integer.valueOf(1), "/list[3]/int", "BbBb", "BbBbB");
263
264 assertNullPointer("/list/foo", "/list[1]/foo", "BbBn");
265
266 assertNullPointer("/nestedBean/foo/bar", "/nestedBean/foo/bar", "BbBnNn");
267
268 assertNullPointer("/list/int/bar", "/list[3]/int/bar", "BbBbBn");
269
270 assertNullPointer("/list/foo/bar", "/list[1]/foo/bar", "BbBnNn");
271
272 assertNullPointer("/map/foo/bar", "/map[@name='foo']/bar", "BbDdNn");
273
274 assertValueAndPointer("/map/Key1", "Value 1", "/map[@name='Key1']", "BbDd", "BbDdB");
275
276 assertValueAndPointer("/integers", bean.getIntegers(), "/integers", "Bb", "BbC");
277 }
278
279 @Test
280 public void testDoStepNoPredicatesStandard() {
281
282 assertValueAndPointer("/vendor/location/address/city", "Fruit Market", "/vendor/location[2]/address[1]/city[1]", "BbMMMM");
283
284 assertNullPointer("/vendor/location/address/pity", "/vendor/location[1]/address[1]/pity", "BbMMMn");
285
286 assertNullPointer("/vendor/location/address/itty/bitty", "/vendor/location[1]/address[1]/itty/bitty", "BbMMMnNn");
287
288 assertNullPointer("/vendor/location/address/city/pretty", "/vendor/location[2]/address[1]/city[1]/pretty", "BbMMMMn");
289 }
290
291 @Test
292 public void testDoStepPredicatesPropertyOwner() {
293
294 assertNullPointer("/foo[@name='foo']", "/foo[@name='foo']", "BnNn");
295
296 assertNullPointer("/foo[3]", "/foo[3]", "Bn");
297 }
298
299 @Test
300 public void testDoStepPredicatesStandard() {
301
302
303 assertValueAndPointer("/vendor/contact[@name='jack']", "Jack", "/vendor/contact[2]", "BbMM");
304
305 assertValueAndPointer("/vendor/contact[2]", "Jack", "/vendor/contact[2]", "BbMM");
306
307 assertNullPointer("/vendor/contact[5]", "/vendor/contact[5]", "BbMn");
308
309 assertValueAndPointer("/vendor/contact[@name='jack'][2]", "Jack Black", "/vendor/contact[4]", "BbMM");
310
311 assertValueAndPointer("/vendor/contact[@name='jack'][2]", "Jack Black", "/vendor/contact[4]", "BbMM");
312 }
313
314 @Test
315 public void testInterpretExpressionPath() {
316 context.getVariables().declareVariable("array", new String[] { "Value1" });
317 context.getVariables().declareVariable("testnull", new TestNull());
318 assertNullPointer("$testnull/nothing[2]", "$testnull/nothing[2]", "VBbE");
319 }
320 }