001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jxpath.ri.model;
017:
018: import java.util.ArrayList;
019: import java.util.Collections;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Locale;
024: import java.util.Map;
025: import java.util.Vector;
026:
027: import junit.framework.Test;
028: import junit.framework.TestSuite;
029: import junit.textui.TestRunner;
030:
031: import org.apache.commons.jxpath.JXPathContext;
032: import org.apache.commons.jxpath.JXPathTestCase;
033: import org.apache.commons.jxpath.Pointer;
034: import org.apache.commons.jxpath.TestBean;
035: import org.apache.commons.jxpath.TestMixedModelBean;
036: import org.apache.commons.jxpath.TestNull;
037: import org.apache.commons.jxpath.Variables;
038:
039: /**
040: * Tests JXPath with mixed model: beans, maps, DOM etc.
041: *
042: * @author Dmitri Plotnikov
043: * @version $Revision: 1.9 $ $Date: 2004/04/04 22:06:36 $
044: */
045:
046: public class MixedModelTest extends JXPathTestCase {
047: private JXPathContext context;
048:
049: /**
050: * Construct a new instance of this test case.
051: *
052: * @param name Name of the test case
053: */
054: public MixedModelTest(String name) {
055: super (name);
056: }
057:
058: public static void main(String[] args) {
059: TestRunner
060: .run(new MixedModelTest("testContainerWithCollection"));
061: }
062:
063: /**
064: * Return the tests included in this test suite.
065: */
066: public static Test suite() {
067: return (new TestSuite(MixedModelTest.class));
068: }
069:
070: public void setUp() {
071: TestMixedModelBean bean = new TestMixedModelBean();
072: context = JXPathContext.newContext(bean);
073: context.setFactory(new TestMixedModelFactory());
074: context.setLocale(Locale.US);
075: Variables vars = context.getVariables();
076: vars.declareVariable("string", bean.getString());
077: vars.declareVariable("bean", bean.getBean());
078: vars.declareVariable("map", bean.getMap());
079: vars.declareVariable("list", bean.getList());
080: vars.declareVariable("document", bean.getDocument());
081: vars.declareVariable("element", bean.getElement());
082: vars.declareVariable("container", bean.getContainer());
083: vars.declareVariable("testnull", new TestNull());
084:
085: int[][] matrix = new int[1][];
086: matrix[0] = new int[1];
087: matrix[0][0] = 3;
088: vars.declareVariable("matrix", matrix);
089: }
090:
091: public void testVar() {
092: context.getVariables().declareVariable("foo:bar", "baz");
093:
094: assertXPathValueAndPointer(context, "$foo:bar", "baz",
095: "$foo:bar");
096:
097: }
098:
099: public void testVarPrimitive() {
100: assertXPathValueAndPointer(context, "$string", "string",
101: "$string");
102: }
103:
104: public void testVarBean() {
105: assertXPathValueAndPointer(context, "$bean/int",
106: new Integer(1), "$bean/int");
107: }
108:
109: public void testVarMap() {
110: assertXPathValueAndPointer(context, "$map/string", "string",
111: "$map[@name='string']");
112: }
113:
114: public void testVarList() {
115: assertXPathValueAndPointer(context, "$list[1]", "string",
116: "$list[1]");
117: }
118:
119: public void testVarDocument() {
120: assertXPathValueAndPointer(context,
121: "$document/vendor/location/address/city",
122: "Fruit Market",
123: "$document/vendor[1]/location[2]/address[1]/city[1]");
124: }
125:
126: public void testVarElement() {
127: assertXPathValueAndPointer(context,
128: "$element/location/address/city", "Fruit Market",
129: "$element/location[2]/address[1]/city[1]");
130: }
131:
132: public void testVarContainer() {
133: assertXPathValueAndPointer(context,
134: "$container/vendor/location/address/city",
135: "Fruit Market",
136: "$container/vendor[1]/location[2]/address[1]/city[1]");
137: }
138:
139: // ----------------------------------------------------------------------
140:
141: public void testBeanPrimitive() {
142: assertXPathValueAndPointer(context, "string", "string",
143: "/string");
144: }
145:
146: public void testBeanBean() {
147: assertXPathValueAndPointer(context, "bean/int", new Integer(1),
148: "/bean/int");
149: }
150:
151: public void testBeanMap() {
152: assertXPathValueAndPointer(context, "map/string", "string",
153: "/map[@name='string']");
154: }
155:
156: public void testBeanList() {
157: assertXPathValueAndPointer(context, "list[1]", "string",
158: "/list[1]");
159: }
160:
161: public void testBeanDocument() {
162: assertXPathValueAndPointer(context,
163: "document/vendor/location/address/city",
164: "Fruit Market",
165: "/document/vendor[1]/location[2]/address[1]/city[1]");
166: }
167:
168: public void testBeanElement() {
169: assertXPathValueAndPointer(context,
170: "element/location/address/city", "Fruit Market",
171: "/element/location[2]/address[1]/city[1]");
172: }
173:
174: public void testBeanContainer() {
175: assertXPathValueAndPointer(context,
176: "container/vendor/location/address/city",
177: "Fruit Market",
178: "/container/vendor[1]/location[2]/address[1]/city[1]");
179: }
180:
181: // ----------------------------------------------------------------------
182:
183: public void testMapPrimitive() {
184: assertXPathValueAndPointer(context, "map/string", "string",
185: "/map[@name='string']");
186: }
187:
188: public void testMapBean() {
189: assertXPathValueAndPointer(context, "map/bean/int",
190: new Integer(1), "/map[@name='bean']/int");
191: }
192:
193: public void testMapMap() {
194: assertXPathValueAndPointer(context, "map/map/string", "string",
195: "/map[@name='map'][@name='string']");
196: }
197:
198: public void testMapList() {
199: assertXPathValueAndPointer(context, "map/list[1]", "string",
200: "/map[@name='list'][1]");
201: }
202:
203: public void testMapDocument() {
204: assertXPathValueAndPointer(context,
205: "map/document/vendor/location/address/city",
206: "Fruit Market", "/map[@name='document']"
207: + "/vendor[1]/location[2]/address[1]/city[1]");
208: }
209:
210: public void testMapElement() {
211: assertXPathValueAndPointer(context,
212: "map/element/location/address/city", "Fruit Market",
213: "/map[@name='element']/location[2]/address[1]/city[1]");
214: }
215:
216: public void testMapContainer() {
217: assertXPathValueAndPointer(context,
218: "map/container/vendor/location/address/city",
219: "Fruit Market", "/map[@name='container']"
220: + "/vendor[1]/location[2]/address[1]/city[1]");
221: }
222:
223: // ----------------------------------------------------------------------
224:
225: public void testListPrimitive() {
226: assertXPathValueAndPointer(context, "list[1]", "string",
227: "/list[1]");
228: }
229:
230: public void testListBean() {
231: assertXPathValueAndPointer(context, "list[2]/int", new Integer(
232: 1), "/list[2]/int");
233: }
234:
235: public void testListMap() {
236: assertXPathValueAndPointer(context, "list[3]/string", "string",
237: "/list[3][@name='string']");
238: }
239:
240: public void testListList() {
241: /** @todo: what is this supposed to do? Should we stick to XPath,
242: * in which case [1] is simply ignored, or Java, in which case
243: * it is supposed to extract the first element from the list?
244: */
245: // assertXPathValueAndPointer(context,
246: // "list[4][1]",
247: // "string2",
248: // "/list[4][1]");
249: assertXPathValueAndPointer(context, "list[4]/.[1]", "string2",
250: "/list[4]/.[1]");
251: }
252:
253: public void testListDocument() {
254: assertXPathValueAndPointer(context,
255: "list[5]/vendor/location/address/city", "Fruit Market",
256: "/list[5]/vendor[1]/location[2]/address[1]/city[1]");
257: }
258:
259: public void testListElement() {
260: assertXPathValueAndPointer(context,
261: "list[6]/location/address/city", "Fruit Market",
262: "/list[6]/location[2]/address[1]/city[1]");
263: }
264:
265: public void testListContainer() {
266: assertXPathValueAndPointer(context,
267: "list[7]/vendor/location/address/city", "Fruit Market",
268: "/list[7]/vendor[1]/location[2]/address[1]/city[1]");
269: }
270:
271: public void testNull() {
272:
273: assertXPathPointerLenient(context, "$null", "$null");
274:
275: assertXPathPointerLenient(context, "$null[3]", "$null[3]");
276:
277: assertXPathPointerLenient(context, "$testnull/nothing",
278: "$testnull/nothing");
279:
280: assertXPathPointerLenient(context, "$testnull/nothing[2]",
281: "$testnull/nothing[2]");
282:
283: assertXPathPointerLenient(context, "beans[8]/int",
284: "/beans[8]/int");
285:
286: assertXPathValueIterator(context, "$testnull/nothing[1]",
287: Collections.EMPTY_LIST);
288:
289: JXPathContext ctx = JXPathContext.newContext(new TestNull());
290: assertXPathValue(ctx, "nothing", null);
291:
292: assertXPathValue(ctx, "child/nothing", null);
293:
294: assertXPathValue(ctx, "array[2]", null);
295:
296: assertXPathValueLenient(ctx, "nothing/something", null);
297:
298: assertXPathValueLenient(ctx, "array[2]/something", null);
299: }
300:
301: public void testRootAsCollection() {
302: assertXPathValue(context, ".[1]/string", "string");
303: }
304:
305: public void testCreatePath() {
306: context = JXPathContext.newContext(new TestBean());
307: context.setFactory(new TestMixedModelFactory());
308:
309: TestBean bean = (TestBean) context.getContextBean();
310: bean.setMap(null);
311:
312: assertXPathCreatePath(context,
313: "/map[@name='TestKey5']/nestedBean/int",
314: new Integer(1), "/map[@name='TestKey5']/nestedBean/int");
315:
316: bean.setMap(null);
317: assertXPathCreatePath(context,
318: "/map[@name='TestKey5']/beans[2]/int", new Integer(1),
319: "/map[@name='TestKey5']/beans[2]/int");
320: }
321:
322: /**
323: * Test JXPath.iterate() with map containing an array
324: */
325: public void testIterateArray() {
326: Map map = new HashMap();
327: map.put("foo", new String[] { "a", "b", "c" });
328:
329: JXPathContext context = JXPathContext.newContext(map);
330:
331: assertXPathValueIterator(context, "foo", list("a", "b", "c"));
332: }
333:
334: public void testIteratePointersArray() {
335: Map map = new HashMap();
336: map.put("foo", new String[] { "a", "b", "c" });
337:
338: JXPathContext context = JXPathContext.newContext(map);
339:
340: Iterator it = context.iteratePointers("foo");
341: List actual = new ArrayList();
342: while (it.hasNext()) {
343: Pointer ptr = (Pointer) it.next();
344: actual.add(context.getValue(ptr.asPath()));
345: }
346: assertEquals("Iterating pointers <" + "foo" + ">", list("a",
347: "b", "c"), actual);
348: }
349:
350: public void testIteratePointersArrayElementWithVariable() {
351: Map map = new HashMap();
352: map.put("foo", new String[] { "a", "b", "c" });
353:
354: JXPathContext context = JXPathContext.newContext(map);
355: context.getVariables().declareVariable("x", new Integer(2));
356: Iterator it = context.iteratePointers("foo[$x]");
357: List actual = new ArrayList();
358: while (it.hasNext()) {
359: Pointer ptr = (Pointer) it.next();
360: actual.add(context.getValue(ptr.asPath()));
361: }
362: assertEquals("Iterating pointers <" + "foo" + ">", list("b"),
363: actual);
364: }
365:
366: public void testIterateVector() {
367: Map map = new HashMap();
368: Vector vec = new Vector();
369: vec.add(new HashMap());
370: vec.add(new HashMap());
371:
372: map.put("vec", vec);
373: JXPathContext context = JXPathContext.newContext(map);
374: assertXPathPointerIterator(context, "/vec", list(
375: "/.[@name='vec'][1]", "/.[@name='vec'][2]"));
376: }
377:
378: public void testErrorProperty() {
379: context.getVariables().declareVariable("e",
380: new ExceptionPropertyTestBean());
381:
382: boolean ex = false;
383: try {
384: assertXPathValue(context, "$e/errorString", null);
385: } catch (Throwable t) {
386: ex = true;
387: }
388: assertTrue("Legitimate exception accessing property", ex);
389:
390: assertXPathPointer(context, "$e/errorString", "$e/errorString");
391:
392: assertXPathPointerLenient(context, "$e/errorStringArray[1]",
393: "$e/errorStringArray[1]");
394:
395: assertXPathPointerIterator(context, "$e/errorString",
396: list("$e/errorString"));
397:
398: assertXPathPointerIterator(context, "$e//error",
399: Collections.EMPTY_LIST);
400: }
401:
402: public void testMatrix() {
403: assertXPathValueAndPointer(context, "$matrix[1]/.[1]",
404: new Integer(3), "$matrix[1]/.[1]");
405:
406: context.setValue("$matrix[1]/.[1]", new Integer(2));
407:
408: assertXPathValueAndPointer(context, "matrix[1]/.[1]",
409: new Integer(3), "/matrix[1]/.[1]");
410:
411: context.setValue("matrix[1]/.[1]", "2");
412:
413: assertXPathValue(context, "matrix[1]/.[1]", new Integer(2));
414:
415: context.getVariables().declareVariable("wholebean",
416: context.getContextBean());
417:
418: assertXPathValueAndPointer(context,
419: "$wholebean/matrix[1]/.[1]", new Integer(2),
420: "$wholebean/matrix[1]/.[1]");
421:
422: boolean ex = false;
423: try {
424: context.setValue("$wholebean/matrix[1]/.[2]", "4");
425: } catch (Exception e) {
426: ex = true;
427: }
428: assertTrue("Exception setting value of non-existent element",
429: ex);
430:
431: ex = false;
432: try {
433: context.setValue("$wholebean/matrix[2]/.[1]", "4");
434: } catch (Exception e) {
435: ex = true;
436: }
437: assertTrue("Exception setting value of non-existent element",
438: ex);
439: }
440:
441: public void testCreatePathAndSetValueWithMatrix() {
442:
443: context.setValue("matrix", null);
444:
445: // Calls factory.createObject(..., TestMixedModelBean, "matrix")
446: // Calls factory.createObject(..., nestedBean, "strings", 2)
447: assertXPathCreatePathAndSetValue(context, "/matrix[1]/.[1]",
448: new Integer(4), "/matrix[1]/.[1]");
449: }
450: }
|