1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jxpath.ri.model;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Locale;
24 import java.util.Map;
25 import java.util.Vector;
26
27 import junit.framework.Test;
28 import junit.framework.TestSuite;
29 import junit.textui.TestRunner;
30
31 import org.apache.commons.jxpath.JXPathContext;
32 import org.apache.commons.jxpath.JXPathTestCase;
33 import org.apache.commons.jxpath.Pointer;
34 import org.apache.commons.jxpath.TestBean;
35 import org.apache.commons.jxpath.TestMixedModelBean;
36 import org.apache.commons.jxpath.TestNull;
37 import org.apache.commons.jxpath.Variables;
38
39 /***
40 * Tests JXPath with mixed model: beans, maps, DOM etc.
41 *
42 * @author Dmitri Plotnikov
43 * @version $Revision: 1.9 $ $Date: 2004/04/04 22:06:36 $
44 */
45
46 public class MixedModelTest extends JXPathTestCase {
47 private JXPathContext context;
48
49 /***
50 * Construct a new instance of this test case.
51 *
52 * @param name Name of the test case
53 */
54 public MixedModelTest(String name) {
55 super(name);
56 }
57
58 public static void main(String[] args) {
59 TestRunner.run(new MixedModelTest("testContainerWithCollection"));
60 }
61
62 /***
63 * Return the tests included in this test suite.
64 */
65 public static Test suite() {
66 return (new TestSuite(MixedModelTest.class));
67 }
68
69 public void setUp() {
70 TestMixedModelBean bean = new TestMixedModelBean();
71 context = JXPathContext.newContext(bean);
72 context.setFactory(new TestMixedModelFactory());
73 context.setLocale(Locale.US);
74 Variables vars = context.getVariables();
75 vars.declareVariable("string", bean.getString());
76 vars.declareVariable("bean", bean.getBean());
77 vars.declareVariable("map", bean.getMap());
78 vars.declareVariable("list", bean.getList());
79 vars.declareVariable("document", bean.getDocument());
80 vars.declareVariable("element", bean.getElement());
81 vars.declareVariable("container", bean.getContainer());
82 vars.declareVariable("testnull", new TestNull());
83
84 int[][] matrix = new int[1][];
85 matrix[0] = new int[1];
86 matrix[0][0] = 3;
87 vars.declareVariable("matrix", matrix);
88 }
89
90 public void testVar() {
91 context.getVariables().declareVariable("foo:bar", "baz");
92
93 assertXPathValueAndPointer(context,
94 "$foo:bar",
95 "baz",
96 "$foo:bar");
97
98 }
99
100 public void testVarPrimitive() {
101 assertXPathValueAndPointer(context, "$string", "string", "$string");
102 }
103
104 public void testVarBean() {
105 assertXPathValueAndPointer(
106 context,
107 "$bean/int",
108 new Integer(1),
109 "$bean/int");
110 }
111
112 public void testVarMap() {
113 assertXPathValueAndPointer(
114 context,
115 "$map/string",
116 "string",
117 "$map[@name='string']");
118 }
119
120 public void testVarList() {
121 assertXPathValueAndPointer(context, "$list[1]", "string", "$list[1]");
122 }
123
124 public void testVarDocument() {
125 assertXPathValueAndPointer(
126 context,
127 "$document/vendor/location/address/city",
128 "Fruit Market",
129 "$document/vendor[1]/location[2]/address[1]/city[1]");
130 }
131
132 public void testVarElement() {
133 assertXPathValueAndPointer(
134 context,
135 "$element/location/address/city",
136 "Fruit Market",
137 "$element/location[2]/address[1]/city[1]");
138 }
139
140 public void testVarContainer() {
141 assertXPathValueAndPointer(
142 context,
143 "$container/vendor/location/address/city",
144 "Fruit Market",
145 "$container/vendor[1]/location[2]/address[1]/city[1]");
146 }
147
148
149
150 public void testBeanPrimitive() {
151 assertXPathValueAndPointer(context, "string", "string", "/string");
152 }
153
154 public void testBeanBean() {
155 assertXPathValueAndPointer(
156 context,
157 "bean/int",
158 new Integer(1),
159 "/bean/int");
160 }
161
162 public void testBeanMap() {
163 assertXPathValueAndPointer(
164 context,
165 "map/string",
166 "string",
167 "/map[@name='string']");
168 }
169
170 public void testBeanList() {
171 assertXPathValueAndPointer(context, "list[1]", "string", "/list[1]");
172 }
173
174 public void testBeanDocument() {
175 assertXPathValueAndPointer(
176 context,
177 "document/vendor/location/address/city",
178 "Fruit Market",
179 "/document/vendor[1]/location[2]/address[1]/city[1]");
180 }
181
182 public void testBeanElement() {
183 assertXPathValueAndPointer(
184 context,
185 "element/location/address/city",
186 "Fruit Market",
187 "/element/location[2]/address[1]/city[1]");
188 }
189
190 public void testBeanContainer() {
191 assertXPathValueAndPointer(
192 context,
193 "container/vendor/location/address/city",
194 "Fruit Market",
195 "/container/vendor[1]/location[2]/address[1]/city[1]");
196 }
197
198
199
200 public void testMapPrimitive() {
201 assertXPathValueAndPointer(
202 context,
203 "map/string",
204 "string",
205 "/map[@name='string']");
206 }
207
208 public void testMapBean() {
209 assertXPathValueAndPointer(
210 context,
211 "map/bean/int",
212 new Integer(1),
213 "/map[@name='bean']/int");
214 }
215
216 public void testMapMap() {
217 assertXPathValueAndPointer(
218 context,
219 "map/map/string",
220 "string",
221 "/map[@name='map'][@name='string']");
222 }
223
224 public void testMapList() {
225 assertXPathValueAndPointer(
226 context,
227 "map/list[1]",
228 "string",
229 "/map[@name='list'][1]");
230 }
231
232 public void testMapDocument() {
233 assertXPathValueAndPointer(
234 context,
235 "map/document/vendor/location/address/city",
236 "Fruit Market",
237 "/map[@name='document']"
238 + "/vendor[1]/location[2]/address[1]/city[1]");
239 }
240
241 public void testMapElement() {
242 assertXPathValueAndPointer(
243 context,
244 "map/element/location/address/city",
245 "Fruit Market",
246 "/map[@name='element']/location[2]/address[1]/city[1]");
247 }
248
249 public void testMapContainer() {
250 assertXPathValueAndPointer(
251 context,
252 "map/container/vendor/location/address/city",
253 "Fruit Market",
254 "/map[@name='container']"
255 + "/vendor[1]/location[2]/address[1]/city[1]");
256 }
257
258
259
260 public void testListPrimitive() {
261 assertXPathValueAndPointer(context, "list[1]", "string", "/list[1]");
262 }
263
264 public void testListBean() {
265 assertXPathValueAndPointer(
266 context,
267 "list[2]/int",
268 new Integer(1),
269 "/list[2]/int");
270 }
271
272 public void testListMap() {
273 assertXPathValueAndPointer(
274 context,
275 "list[3]/string",
276 "string",
277 "/list[3][@name='string']");
278 }
279
280 public void testListList() {
281 /*** @todo: what is this supposed to do? Should we stick to XPath,
282 * in which case [1] is simply ignored, or Java, in which case
283 * it is supposed to extract the first element from the list?
284 */
285
286
287
288
289
290 assertXPathValueAndPointer(
291 context,
292 "list[4]/.[1]",
293 "string2",
294 "/list[4]/.[1]");
295 }
296
297 public void testListDocument() {
298 assertXPathValueAndPointer(
299 context,
300 "list[5]/vendor/location/address/city",
301 "Fruit Market",
302 "/list[5]/vendor[1]/location[2]/address[1]/city[1]");
303 }
304
305 public void testListElement() {
306 assertXPathValueAndPointer(
307 context,
308 "list[6]/location/address/city",
309 "Fruit Market",
310 "/list[6]/location[2]/address[1]/city[1]");
311 }
312
313 public void testListContainer() {
314 assertXPathValueAndPointer(
315 context,
316 "list[7]/vendor/location/address/city",
317 "Fruit Market",
318 "/list[7]/vendor[1]/location[2]/address[1]/city[1]");
319 }
320
321 public void testNull() {
322
323 assertXPathPointerLenient(context, "$null", "$null");
324
325 assertXPathPointerLenient(context, "$null[3]", "$null[3]");
326
327 assertXPathPointerLenient(
328 context,
329 "$testnull/nothing",
330 "$testnull/nothing");
331
332 assertXPathPointerLenient(
333 context,
334 "$testnull/nothing[2]",
335 "$testnull/nothing[2]");
336
337 assertXPathPointerLenient(context, "beans[8]/int", "/beans[8]/int");
338
339 assertXPathValueIterator(
340 context,
341 "$testnull/nothing[1]",
342 Collections.EMPTY_LIST);
343
344 JXPathContext ctx = JXPathContext.newContext(new TestNull());
345 assertXPathValue(ctx, "nothing", null);
346
347 assertXPathValue(ctx, "child/nothing", null);
348
349 assertXPathValue(ctx, "array[2]", null);
350
351 assertXPathValueLenient(ctx, "nothing/something", null);
352
353 assertXPathValueLenient(ctx, "array[2]/something", null);
354 }
355
356 public void testRootAsCollection() {
357 assertXPathValue(context, ".[1]/string", "string");
358 }
359
360 public void testCreatePath() {
361 context = JXPathContext.newContext(new TestBean());
362 context.setFactory(new TestMixedModelFactory());
363
364 TestBean bean = (TestBean) context.getContextBean();
365 bean.setMap(null);
366
367 assertXPathCreatePath(
368 context,
369 "/map[@name='TestKey5']/nestedBean/int",
370 new Integer(1),
371 "/map[@name='TestKey5']/nestedBean/int");
372
373 bean.setMap(null);
374 assertXPathCreatePath(
375 context,
376 "/map[@name='TestKey5']/beans[2]/int",
377 new Integer(1),
378 "/map[@name='TestKey5']/beans[2]/int");
379 }
380
381 /***
382 * Test JXPath.iterate() with map containing an array
383 */
384 public void testIterateArray() {
385 Map map = new HashMap();
386 map.put("foo", new String[] { "a", "b", "c" });
387
388 JXPathContext context = JXPathContext.newContext(map);
389
390 assertXPathValueIterator(context, "foo", list("a", "b", "c"));
391 }
392
393 public void testIteratePointersArray() {
394 Map map = new HashMap();
395 map.put("foo", new String[] { "a", "b", "c" });
396
397 JXPathContext context = JXPathContext.newContext(map);
398
399 Iterator it = context.iteratePointers("foo");
400 List actual = new ArrayList();
401 while (it.hasNext()) {
402 Pointer ptr = (Pointer) it.next();
403 actual.add(context.getValue(ptr.asPath()));
404 }
405 assertEquals(
406 "Iterating pointers <" + "foo" + ">",
407 list("a", "b", "c"),
408 actual);
409 }
410
411 public void testIteratePointersArrayElementWithVariable() {
412 Map map = new HashMap();
413 map.put("foo", new String[] { "a", "b", "c" });
414
415 JXPathContext context = JXPathContext.newContext(map);
416 context.getVariables().declareVariable("x", new Integer(2));
417 Iterator it = context.iteratePointers("foo[$x]");
418 List actual = new ArrayList();
419 while (it.hasNext()) {
420 Pointer ptr = (Pointer) it.next();
421 actual.add(context.getValue(ptr.asPath()));
422 }
423 assertEquals("Iterating pointers <" + "foo" + ">", list("b"), actual);
424 }
425
426 public void testIterateVector() {
427 Map map = new HashMap();
428 Vector vec = new Vector();
429 vec.add(new HashMap());
430 vec.add(new HashMap());
431
432 map.put("vec", vec);
433 JXPathContext context = JXPathContext.newContext(map);
434 assertXPathPointerIterator(
435 context,
436 "/vec",
437 list("/.[@name='vec'][1]", "/.[@name='vec'][2]"));
438 }
439
440 public void testErrorProperty() {
441 context.getVariables().declareVariable(
442 "e",
443 new ExceptionPropertyTestBean());
444
445 boolean ex = false;
446 try {
447 assertXPathValue(context, "$e/errorString", null);
448 }
449 catch (Throwable t) {
450 ex = true;
451 }
452 assertTrue("Legitimate exception accessing property", ex);
453
454 assertXPathPointer(context, "$e/errorString", "$e/errorString");
455
456 assertXPathPointerLenient(
457 context,
458 "$e/errorStringArray[1]",
459 "$e/errorStringArray[1]");
460
461 assertXPathPointerIterator(
462 context,
463 "$e/errorString",
464 list("$e/errorString"));
465
466 assertXPathPointerIterator(
467 context,
468 "$e//error",
469 Collections.EMPTY_LIST);
470 }
471
472 public void testMatrix() {
473 assertXPathValueAndPointer(
474 context,
475 "$matrix[1]/.[1]",
476 new Integer(3),
477 "$matrix[1]/.[1]");
478
479 context.setValue("$matrix[1]/.[1]", new Integer(2));
480
481 assertXPathValueAndPointer(
482 context,
483 "matrix[1]/.[1]",
484 new Integer(3),
485 "/matrix[1]/.[1]");
486
487 context.setValue("matrix[1]/.[1]", "2");
488
489 assertXPathValue(context, "matrix[1]/.[1]", new Integer(2));
490
491 context.getVariables().declareVariable(
492 "wholebean",
493 context.getContextBean());
494
495 assertXPathValueAndPointer(
496 context,
497 "$wholebean/matrix[1]/.[1]",
498 new Integer(2),
499 "$wholebean/matrix[1]/.[1]");
500
501 boolean ex = false;
502 try {
503 context.setValue("$wholebean/matrix[1]/.[2]", "4");
504 }
505 catch (Exception e) {
506 ex = true;
507 }
508 assertTrue("Exception setting value of non-existent element", ex);
509
510 ex = false;
511 try {
512 context.setValue("$wholebean/matrix[2]/.[1]", "4");
513 }
514 catch (Exception e) {
515 ex = true;
516 }
517 assertTrue("Exception setting value of non-existent element", ex);
518 }
519
520 public void testCreatePathAndSetValueWithMatrix() {
521
522 context.setValue("matrix", null);
523
524
525
526 assertXPathCreatePathAndSetValue(
527 context,
528 "/matrix[1]/.[1]",
529 new Integer(4),
530 "/matrix[1]/.[1]");
531 }
532 }