1   /*
2    * Copyright 2007 the original author or authors.
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  
17  package org.springframework.xml.xpath;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.util.List;
22  import javax.xml.parsers.DocumentBuilder;
23  import javax.xml.parsers.DocumentBuilderFactory;
24  import javax.xml.parsers.ParserConfigurationException;
25  import javax.xml.transform.Source;
26  import javax.xml.transform.dom.DOMSource;
27  import javax.xml.transform.stream.StreamSource;
28  
29  import junit.framework.TestCase;
30  import org.springframework.core.io.ClassPathResource;
31  import org.springframework.xml.sax.SaxUtils;
32  import org.springframework.xml.transform.ResourceSource;
33  import org.w3c.dom.DOMException;
34  import org.w3c.dom.Document;
35  import org.w3c.dom.Node;
36  import org.xml.sax.SAXException;
37  
38  public abstract class AbstractXPathTemplateTestCase extends TestCase {
39  
40      XPathOperations template;
41  
42      private Source namespaces;
43  
44      private Source nonamespaces;
45  
46      protected final void setUp() throws Exception {
47          template = createTemplate();
48          namespaces = new ResourceSource(new ClassPathResource("namespaces.xml", AbstractXPathTemplateTestCase.class));
49          nonamespaces =
50                  new ResourceSource(new ClassPathResource("nonamespaces.xml", AbstractXPathTemplateTestCase.class));
51      }
52  
53      protected abstract XPathOperations createTemplate() throws Exception;
54  
55      public void testEvaluateAsBoolean() {
56          boolean result = template.evaluateAsBoolean("/root/child/boolean", nonamespaces);
57          assertTrue("Invalid result", result);
58      }
59  
60      public void testEvaluateAsBooleanNamespaces() {
61          boolean result = template.evaluateAsBoolean("/prefix1:root/prefix2:child/prefix2:boolean", namespaces);
62          assertTrue("Invalid result", result);
63      }
64  
65      public void testEvaluateAsDouble() {
66          double result = template.evaluateAsDouble("/root/child/number", nonamespaces);
67          assertEquals("Invalid result", 42D, result, 0D);
68      }
69  
70      public void testEvaluateAsDoubleNamespaces() {
71          double result = template.evaluateAsDouble("/prefix1:root/prefix2:child/prefix2:number", namespaces);
72          assertEquals("Invalid result", 42D, result, 0D);
73      }
74  
75      public void testEvaluateAsNode() {
76          Node result = template.evaluateAsNode("/root/child", nonamespaces);
77          assertNotNull("Invalid result", result);
78          assertEquals("Invalid localname", "child", result.getLocalName());
79      }
80  
81      public void testEvaluateAsNodeNamespaces() {
82          Node result = template.evaluateAsNode("/prefix1:root/prefix2:child", namespaces);
83          assertNotNull("Invalid result", result);
84          assertEquals("Invalid localname", "child", result.getLocalName());
85      }
86  
87      public void testEvaluateAsNodes() {
88          List results = template.evaluateAsNodeList("/root/child/*", nonamespaces);
89          assertNotNull("Invalid result", results);
90          assertEquals("Invalid amount of results", 3, results.size());
91      }
92  
93      public void testEvaluateAsNodesNamespaces() {
94          List results = template.evaluateAsNodeList("/prefix1:root/prefix2:child/*", namespaces);
95          assertNotNull("Invalid result", results);
96          assertEquals("Invalid amount of results", 3, results.size());
97      }
98  
99      public void testEvaluateAsStringNamespaces() throws IOException, SAXException {
100         String result = template.evaluateAsString("/prefix1:root/prefix2:child/prefix2:text", namespaces);
101         assertEquals("Invalid result", "text", result);
102     }
103 
104     public void testEvaluateAsString() throws IOException, SAXException {
105         String result = template.evaluateAsString("/root/child/text", nonamespaces);
106         assertEquals("Invalid result", "text", result);
107     }
108 
109     public void testEvaluateDomSource() throws IOException, SAXException, ParserConfigurationException {
110         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
111         documentBuilderFactory.setNamespaceAware(true);
112         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
113         Document document = documentBuilder.parse(SaxUtils.createInputSource(
114                 new ClassPathResource("nonamespaces.xml", AbstractXPathTemplateTestCase.class)));
115 
116         String result = template.evaluateAsString("/root/child/text", new DOMSource(document));
117         assertEquals("Invalid result", "text", result);
118     }
119 
120     public void testEvaluateStreamSource() throws IOException, SAXException, ParserConfigurationException {
121         InputStream in = AbstractXPathTemplateTestCase.class.getResourceAsStream("nonamespaces.xml");
122         String result = template.evaluateAsString("/root/child/text", new StreamSource(in));
123         assertEquals("Invalid result", "text", result);
124     }
125 
126     public void testInvalidExpression() {
127         try {
128             template.evaluateAsBoolean("\\", namespaces);
129             fail("No XPathException thrown");
130         }
131         catch (XPathException ex) {
132             // Expected behaviour
133         }
134     }
135 
136     public void testEvaluateAsObject() throws Exception {
137         String result = (String) template.evaluateAsObject("/root/child", nonamespaces, new NodeMapper() {
138             public Object mapNode(Node node, int nodeNum) throws DOMException {
139                 return node.getLocalName();
140             }
141         });
142         assertNotNull("Invalid result", result);
143         assertEquals("Invalid localname", "child", result);
144     }
145 
146     public void testEvaluate() throws Exception {
147         List results = template.evaluate("/root/child/*", nonamespaces, new NodeMapper() {
148             public Object mapNode(Node node, int nodeNum) throws DOMException {
149                 return node.getLocalName();
150             }
151         });
152         assertNotNull("Invalid result", results);
153         assertEquals("Invalid amount of results", 3, results.size());
154         assertEquals("Invalid first result", "text", results.get(0));
155         assertEquals("Invalid first result", "number", results.get(1));
156         assertEquals("Invalid first result", "boolean", results.get(2));
157     }
158 }