KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jxpath > ri > model > XMLModelTestCase


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.jxpath.ri.model;
17
18 import org.apache.commons.jxpath.AbstractFactory;
19 import org.apache.commons.jxpath.IdentityManager;
20 import org.apache.commons.jxpath.JXPathContext;
21 import org.apache.commons.jxpath.JXPathException;
22 import org.apache.commons.jxpath.JXPathTestCase;
23 import org.apache.commons.jxpath.Pointer;
24 import org.apache.commons.jxpath.Variables;
25 import org.apache.commons.jxpath.xml.DocumentContainer;
26
27 /**
28  * Abstract superclass for pure XPath 1.0. Subclasses
29  * apply the same XPaths to contexts using different models:
30  * DOM, JDOM etc.
31  *
32  * @author Dmitri Plotnikov
33  * @version $Revision: 1.23 $ $Date: 2004/06/30 00:29:13 $
34  */

35
36 public abstract class XMLModelTestCase extends JXPathTestCase {
37     protected JXPathContext context;
38
39     /**
40      * Construct a new instance of this test case.
41      *
42      * @param name Name of the test case
43      */

44     public XMLModelTestCase(String JavaDoc name) {
45         super(name);
46     }
47
48     public void setUp() {
49         if (context == null) {
50             DocumentContainer docCtr = createDocumentContainer();
51             context = createContext();
52             Variables vars = context.getVariables();
53             vars.declareVariable("document", docCtr.getValue());
54             vars.declareVariable("container", docCtr);
55             vars.declareVariable(
56                 "element",
57                 context.getPointer("vendor/location/address/street").getNode());
58         }
59     }
60
61     protected abstract String JavaDoc getModel();
62
63     protected DocumentContainer createDocumentContainer() {
64         return new DocumentContainer(
65                 JXPathTestCase.class.getResource("Vendor.xml"),
66                 getModel());
67     }
68     
69     protected abstract AbstractFactory getAbstractFactory();
70         
71     protected JXPathContext createContext() {
72         JXPathContext context =
73             JXPathContext.newContext(createDocumentContainer());
74         context.setFactory(getAbstractFactory());
75         context.registerNamespace("product", "productNS");
76         return context;
77     }
78
79     /**
80      * An XML signature is used to determine if we have the right result
81      * after a modification of XML by JXPath. It is basically a piece
82      * of simplified XML.
83      */

84     protected abstract String JavaDoc getXMLSignature(
85         Object JavaDoc node,
86         boolean elements,
87         boolean attributes,
88         boolean text,
89         boolean pi);
90
91     protected void assertXMLSignature(
92         JXPathContext context,
93         String JavaDoc path,
94         String JavaDoc signature,
95         boolean elements,
96         boolean attributes,
97         boolean text,
98         boolean pi)
99     {
100         Object JavaDoc node = context.getPointer(path).getNode();
101         String JavaDoc sig = getXMLSignature(node, elements, attributes, text, pi);
102         assertEquals("XML Signature mismatch: ", signature, sig);
103     }
104
105     // ------------------------------------------------ Individual Test Methods
106

107     public void testDocumentOrder() {
108         assertDocumentOrder(
109             context,
110             "vendor/location",
111             "vendor/location/address/street",
112             -1);
113
114         assertDocumentOrder(
115             context,
116             "vendor/location[@id = '100']",
117             "vendor/location[@id = '101']",
118             -1);
119
120         assertDocumentOrder(
121             context,
122             "vendor//price:amount",
123             "vendor/location",
124             1);
125     }
126     
127
128     public void testSetValue() {
129         assertXPathSetValue(
130             context,
131             "vendor/location[@id = '100']",
132             "New Text");
133
134         assertXMLSignature(
135             context,
136             "vendor/location[@id = '100']",
137             "<E>New Text</E>",
138             false,
139             false,
140             true,
141             false);
142
143         assertXPathSetValue(
144             context,
145             "vendor/location[@id = '101']",
146             "Replacement Text");
147
148         assertXMLSignature(
149             context,
150             "vendor/location[@id = '101']",
151             "<E>Replacement Text</E>",
152             false,
153             false,
154             true,
155             false);
156     }
157
158     /**
159      * Test JXPathContext.createPath() with various arguments
160      */

161     public void testCreatePath() {
162         // Create a DOM element
163
assertXPathCreatePath(
164             context,
165             "/vendor[1]/location[3]",
166             "",
167             "/vendor[1]/location[3]");
168
169         // Create a DOM element with contents
170
assertXPathCreatePath(
171             context,
172             "/vendor[1]/location[3]/address/street",
173             "",
174             "/vendor[1]/location[3]/address[1]/street[1]");
175
176         // Create a DOM attribute
177
assertXPathCreatePath(
178             context,
179             "/vendor[1]/location[2]/@manager",
180             "",
181             "/vendor[1]/location[2]/@manager");
182
183         assertXPathCreatePath(
184             context,
185             "/vendor[1]/location[1]/@name",
186             "local",
187             "/vendor[1]/location[1]/@name");
188
189          assertXPathCreatePathAndSetValue(
190             context,
191             "/vendor[1]/location[4]/@manager",
192             "",
193             "/vendor[1]/location[4]/@manager");
194          
195          context.registerNamespace("price", "priceNS");
196          
197          // Create a DOM element
198
assertXPathCreatePath(
199              context,
200              "/vendor[1]/price:foo/price:bar",
201              "",
202              "/vendor[1]/price:foo[1]/price:bar[1]");
203     }
204
205     /**
206      * Test JXPath.createPathAndSetValue() with various arguments
207      */

208     public void testCreatePathAndSetValue() {
209         // Create a XML element
210
assertXPathCreatePathAndSetValue(
211             context,
212             "vendor/location[3]",
213             "",
214             "/vendor[1]/location[3]");
215
216         // Create a DOM element with contents
217
assertXPathCreatePathAndSetValue(
218             context,
219             "vendor/location[3]/address/street",
220             "Lemon Circle",
221             "/vendor[1]/location[3]/address[1]/street[1]");
222
223         // Create an attribute
224
assertXPathCreatePathAndSetValue(
225             context,
226             "vendor/location[2]/@manager",
227             "John Doe",
228             "/vendor[1]/location[2]/@manager");
229
230         assertXPathCreatePathAndSetValue(
231             context,
232             "vendor/location[1]/@manager",
233             "John Doe",
234             "/vendor[1]/location[1]/@manager");
235         
236         assertXPathCreatePathAndSetValue(
237             context,
238             "/vendor[1]/location[4]/@manager",
239             "James Dow",
240             "/vendor[1]/location[4]/@manager");
241         
242         assertXPathCreatePathAndSetValue(
243             context,
244             "vendor/product/product:name/attribute::price:language",
245             "English",
246             "/vendor[1]/product[1]/product:name[1]/@price:language");
247         
248         context.registerNamespace("price", "priceNS");
249         
250         // Create a DOM element
251
assertXPathCreatePathAndSetValue(
252             context,
253             "/vendor[1]/price:foo/price:bar",
254             "123.20",
255             "/vendor[1]/price:foo[1]/price:bar[1]");
256     }
257
258     /**
259      * Test JXPathContext.removePath() with various arguments
260      */

261     public void testRemovePath() {
262         // Remove XML nodes
263
context.removePath("vendor/location[@id = '101']//street/text()");
264         assertEquals(
265             "Remove DOM text",
266             "",
267             context.getValue("vendor/location[@id = '101']//street"));
268
269         context.removePath("vendor/location[@id = '101']//street");
270         assertEquals(
271             "Remove DOM element",
272             new Double JavaDoc(0),
273             context.getValue("count(vendor/location[@id = '101']//street)"));
274
275         context.removePath("vendor/location[@id = '100']/@name");
276         assertEquals(
277             "Remove DOM attribute",
278             new Double JavaDoc(0),
279             context.getValue("count(vendor/location[@id = '100']/@name)"));
280     }
281
282     public void testID() {
283         context.setIdentityManager(new IdentityManager() {
284             public Pointer getPointerByID(JXPathContext context, String JavaDoc id) {
285                 NodePointer ptr = (NodePointer) context.getPointer("/");
286                 ptr = ptr.getValuePointer(); // Unwrap the container
287
return ptr.getPointerByID(context, id);
288             }
289         });
290
291         assertXPathValueAndPointer(
292             context,
293             "id(101)//street",
294             "Tangerine Drive",
295             "id('101')/address[1]/street[1]");
296
297         assertXPathPointerLenient(
298             context,
299             "id(105)/address/street",
300             "id(105)/address/street");
301     }
302
303     public void testAxisChild() {
304         assertXPathValue(
305             context,
306             "vendor/location/address/street",
307             "Orchard Road");
308
309         // child:: - first child does not match, need to search
310
assertXPathValue(
311             context,
312             "vendor/location/address/city",
313             "Fruit Market");
314         
315         // local-name(qualified)
316
assertXPathValue(
317             context,
318             "local-name(vendor/product/price:amount)",
319             "amount");
320         
321         // local-name(non-qualified)
322
assertXPathValue(context, "local-name(vendor/location)", "location");
323
324         // name (qualified)
325
assertXPathValue(
326             context,
327             "name(vendor/product/price:amount)",
328             "value:amount");
329
330         // name (non-qualified)
331
assertXPathValue(
332             context,
333             "name(vendor/location)",
334             "location");
335
336         // namespace-uri (qualified)
337
assertXPathValue(
338             context,
339             "namespace-uri(vendor/product/price:amount)",
340             "priceNS");
341
342         // default namespace does not affect search
343
assertXPathValue(context, "vendor/product/prix", "934.99");
344         
345         assertXPathValue(context, "/vendor/contact[@name='jim']", "Jim");
346         
347         boolean nsv = false;
348         try {
349             context.setLenient(false);
350             context.getValue("/vendor/contact[@name='jane']");
351         }
352         catch (JXPathException ex) {
353             nsv = true;
354         }
355         assertTrue("No such value: /vendor/contact[@name='jim']", nsv);
356                 
357         nsv = false;
358         try {
359             context.setLenient(false);
360             context.getValue("/vendor/contact[@name='jane']/*");
361         }
362         catch (JXPathException ex) {
363             nsv = true;
364         }
365         assertTrue("No such value: /vendor/contact[@name='jane']/*", nsv);
366         
367         // child:: with a wildcard
368
assertXPathValue(
369             context,
370             "count(vendor/product/price:*)",
371             new Double JavaDoc(2));
372
373         // child:: with the default namespace
374
assertXPathValue(context, "count(vendor/product/*)", new Double JavaDoc(4));
375
376         // child:: with a qualified name
377
assertXPathValue(context, "vendor/product/price:amount", "45.95");
378     }
379
380     public void testAxisChildIndexPredicate() {
381         assertXPathValue(
382             context,
383             "vendor/location[2]/address/street",
384             "Tangerine Drive");
385     }
386
387     public void testAxisDescendant() {
388         // descendant::
389
assertXPathValue(context, "//street", "Orchard Road");
390
391         // descendent:: with a namespace and wildcard
392
assertXPathValue(context, "count(//price:*)", new Double JavaDoc(2));
393
394         assertXPathValueIterator(context, "vendor//saleEnds", list("never"));
395
396         assertXPathValueIterator(context, "vendor//promotion", list(""));
397
398         assertXPathValueIterator(
399             context,
400             "vendor//saleEnds[../@stores = 'all']",
401             list("never"));
402
403         assertXPathValueIterator(
404             context,
405             "vendor//promotion[../@stores = 'all']",
406             list(""));
407     }
408     
409 // public void testAxisDescendantDocumentOrder() {
410
// Iterator iter = context.iteratePointers("//*");
411
// while (iter.hasNext()) {
412
// System.err.println(iter.next());
413
// }
414
// }
415

416     public void testAxisParent() {
417         // parent::
418
assertXPathPointer(
419             context,
420             "//street/..",
421             "/vendor[1]/location[1]/address[1]");
422
423         // parent:: (note reverse document order)
424
assertXPathPointerIterator(
425             context,
426             "//street/..",
427             list(
428                 "/vendor[1]/location[2]/address[1]",
429                 "/vendor[1]/location[1]/address[1]"));
430
431         // parent:: with a namespace and wildcard
432
assertXPathValue(
433             context,
434             "vendor/product/price:sale/saleEnds/parent::price:*" + "/saleEnds",
435             "never");
436     }
437
438     public void testAxisFollowingSibling() {
439         // following-sibling::
440
assertXPathValue(
441             context,
442             "vendor/location[.//employeeCount = 10]/"
443                 + "following-sibling::location//street",
444             "Tangerine Drive");
445
446         // following-sibling:: produces the correct pointer
447
assertXPathPointer(
448             context,
449             "vendor/location[.//employeeCount = 10]/"
450                 + "following-sibling::location//street",
451             "/vendor[1]/location[2]/address[1]/street[1]");
452     }
453
454     public void testAxisPrecedingSibling() {
455         // preceding-sibling:: produces the correct pointer
456
assertXPathPointer(
457             context,
458             "//location[2]/preceding-sibling::location//street",
459             "/vendor[1]/location[1]/address[1]/street[1]");
460     }
461
462     public void testAxisAttribute() {
463         // attribute::
464
assertXPathValue(context, "vendor/location/@id", "100");
465
466         // attribute:: produces the correct pointer
467
assertXPathPointer(
468             context,
469             "vendor/location/@id",
470             "/vendor[1]/location[1]/@id");
471
472         // iterate over attributes
473
assertXPathValueIterator(
474             context,
475             "vendor/location/@id",
476             list("100", "101"));
477
478         // Using different prefixes for the same namespace
479
assertXPathValue(
480             context,
481             "vendor/product/price:amount/@price:discount",
482             "10%");
483         
484         // namespace uri for an attribute
485
assertXPathValue(
486             context,
487             "namespace-uri(vendor/product/price:amount/@price:discount)",
488             "priceNS");
489
490         // local name of an attribute
491
assertXPathValue(
492             context,
493             "local-name(vendor/product/price:amount/@price:discount)",
494             "discount");
495
496         // name for an attribute
497
assertXPathValue(
498             context,
499             "name(vendor/product/price:amount/@price:discount)",
500             "price:discount");
501
502         // attribute:: with the default namespace
503
assertXPathValue(
504             context,
505             "vendor/product/price:amount/@discount",
506             "20%");
507
508         // namespace uri of an attribute with the default namespace
509
assertXPathValue(
510             context,
511             "namespace-uri(vendor/product/price:amount/@discount)",
512             "");
513
514         // local name of an attribute with the default namespace
515
assertXPathValue(
516             context,
517             "local-name(vendor/product/price:amount/@discount)",
518             "discount");
519
520         // name of an attribute with the default namespace
521
assertXPathValue(
522             context,
523             "name(vendor/product/price:amount/@discount)",
524             "discount");
525
526         // attribute:: with a namespace and wildcard
527
assertXPathValueIterator(
528             context,
529             "vendor/product/price:amount/@price:*",
530             list("10%"));
531
532         // attribute:: with a wildcard
533
assertXPathValueIterator(
534             context,
535             "vendor/location[1]/@*",
536             set("100", "", "local"));
537
538         // attribute:: with default namespace and wildcard
539
assertXPathValueIterator(
540             context,
541             "vendor/product/price:amount/@*",
542             list("20%"));
543
544         // Empty attribute
545
assertXPathValue(context, "vendor/location/@manager", "");
546
547         // Missing attribute
548
assertXPathValueLenient(context, "vendor/location/@missing", null);
549
550         // Missing attribute with namespace
551
assertXPathValueLenient(context, "vendor/location/@miss:missing", null);
552
553         // Using attribute in a predicate
554
assertXPathValue(
555             context,
556             "vendor/location[@id='101']//street",
557             "Tangerine Drive");
558         
559         assertXPathValueIterator(
560             context,
561             "/vendor/location[1]/@*[name()!= 'manager']", list("100",
562             "local"));
563     }
564
565     public void testAxisNamespace() {
566         // namespace::
567
assertXPathValueAndPointer(
568             context,
569             "vendor/product/prix/namespace::price",
570             "priceNS",
571             "/vendor[1]/product[1]/prix[1]/namespace::price");
572
573         // namespace::*
574
assertXPathValue(
575             context,
576             "count(vendor/product/namespace::*)",
577             new Double JavaDoc(3));
578
579         // name of namespace
580
assertXPathValue(
581             context,
582             "name(vendor/product/prix/namespace::price)",
583             "price");
584
585         // local name of namespace
586
assertXPathValue(
587             context,
588             "local-name(vendor/product/prix/namespace::price)",
589             "price");
590     }
591
592     public void testAxisAncestor() {
593         // ancestor::
594
assertXPathValue(
595             context,
596             "vendor/product/price:sale/saleEnds/"
597                 + "ancestor::price:sale/saleEnds",
598             "never");
599
600         // ancestor:: with a wildcard
601
assertXPathValue(
602             context,
603             "vendor/product/price:sale/saleEnds/ancestor::price:*"
604                 + "/saleEnds",
605             "never");
606     }
607
608     public void testAxisAncestorOrSelf() {
609         // ancestor-or-self::
610
assertXPathValue(
611             context,
612             "vendor/product/price:sale/"
613                 + "ancestor-or-self::price:sale/saleEnds",
614             "never");
615     }
616
617     public void testAxisFollowing() {
618         assertXPathValueIterator(
619             context,
620             "vendor/contact/following::location//street",
621             list("Orchard Road", "Tangerine Drive"));
622
623         // following:: with a namespace
624
assertXPathValue(
625             context,
626             "//location/following::price:sale/saleEnds",
627             "never");
628     }
629
630     public void testAxisSelf() {
631         // self:: with a namespace
632
assertXPathValue(
633             context,
634             "//price:sale/self::price:sale/saleEnds",
635             "never");
636
637         // self:: with an unmatching name
638
assertXPathValueLenient(context, "//price:sale/self::x/saleEnds", null);
639     }
640
641     public void testNodeTypeComment() {
642         // comment()
643
assertXPathValue(
644             context,
645             "//product/comment()",
646             "We are not buying this product, ever");
647     }
648
649     public void testNodeTypeText() {
650         // text()
651
assertXPathValue(
652             context,
653             "//product/text()[. != '']",
654             "We love this product.");
655
656         // text() pointer
657
assertXPathPointer(
658             context,
659             "//product/text()",
660             "/vendor[1]/product[1]/text()[1]");
661
662     }
663
664     public void testNodeTypeProcessingInstruction() {
665         // processing-instruction() without an argument
666
assertXPathValue(
667             context,
668             "//product/processing-instruction()",
669             "do not show anybody");
670
671         // processing-instruction() with an argument
672
assertXPathValue(
673             context,
674             "//product/processing-instruction('report')",
675             "average only");
676
677         // processing-instruction() pointer without an argument
678
assertXPathPointer(
679             context,
680             "//product/processing-instruction('report')",
681             "/vendor[1]/product[1]/processing-instruction('report')[1]");
682
683         // processing-instruction name
684
assertXPathValue(
685             context,
686             "name(//product/processing-instruction()[1])",
687             "security");
688     }
689
690     public void testLang() {
691         // xml:lang built-in attribute
692
assertXPathValue(context, "//product/prix/@xml:lang", "fr");
693
694         // lang() used the built-in xml:lang attribute
695
assertXPathValue(context, "//product/prix[lang('fr')]", "934.99");
696
697         // Default language
698
assertXPathValue(
699             context,
700             "//product/price:sale[lang('en')]/saleEnds",
701             "never");
702     }
703
704     public void testDocument() {
705         assertXPathValue(
706             context,
707             "$document/vendor/location[1]//street",
708             "Orchard Road");
709
710         assertXPathPointer(
711             context,
712             "$document/vendor/location[1]//street",
713             "$document/vendor[1]/location[1]/address[1]/street[1]");
714
715         assertXPathValue(context, "$document/vendor//street", "Orchard Road");
716     }
717
718     public void testContainer() {
719         assertXPathValue(context, "$container/vendor//street", "Orchard Road");
720
721         assertXPathValue(context, "$container//street", "Orchard Road");
722
723         assertXPathPointer(
724             context,
725             "$container//street",
726             "$container/vendor[1]/location[1]/address[1]/street[1]");
727
728         // Conversion to number
729
assertXPathValue(
730             context,
731             "number(vendor/location/employeeCount)",
732             new Double JavaDoc(10));
733     }
734
735     public void testElementInVariable() {
736         assertXPathValue(context, "$element", "Orchard Road");
737     }
738
739     public void testTypeConversions() {
740         // Implicit conversion to number
741
assertXPathValue(
742             context,
743             "vendor/location/employeeCount + 1",
744             new Double JavaDoc(11));
745
746         // Implicit conversion to boolean
747
assertXPathValue(
748             context,
749             "vendor/location/employeeCount and true()",
750             Boolean.TRUE);
751     }
752
753     public void testBooleanFunction() {
754         assertXPathValue(
755             context,
756             "boolean(vendor//saleEnds[../@stores = 'all'])",
757             Boolean.TRUE);
758
759         assertXPathValue(
760             context,
761             "boolean(vendor//promotion[../@stores = 'all'])",
762             Boolean.TRUE);
763
764         assertXPathValue(
765             context,
766             "boolean(vendor//promotion[../@stores = 'some'])",
767             Boolean.FALSE);
768     }
769     
770     public void testFunctionsLastAndPosition() {
771         assertXPathPointer(
772                 context,
773                 "vendor//location[last()]",
774                 "/vendor[1]/location[2]");
775     }
776
777     public void testNamespaceMapping() {
778         context.registerNamespace("rate", "priceNS");
779         context.registerNamespace("goods", "productNS");
780
781         assertEquals("Context node namespace resolution",
782                 "priceNS",
783                 context.getNamespaceURI("price"));
784         
785         assertEquals("Registered namespace resolution",
786                 "priceNS",
787                 context.getNamespaceURI("rate"));
788
789         // child:: with a namespace and wildcard
790
assertXPathValue(context,
791                 "count(vendor/product/rate:*)",
792                 new Double JavaDoc(2));
793
794         // Preference for externally registered namespace prefix
795
assertXPathValueAndPointer(context,
796                 "//product:name",
797                 "Box of oranges",
798                 "/vendor[1]/product[1]/goods:name[1]");
799     }
800 }
Popular Tags