KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > scriptella > driver > xpath > XPathQueryExecutor


1 /*
2  * Copyright 2006-2007 The Scriptella Project Team.
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 scriptella.driver.xpath;
17
18 import org.w3c.dom.Document JavaDoc;
19 import org.w3c.dom.Element JavaDoc;
20 import org.w3c.dom.Node JavaDoc;
21 import org.w3c.dom.NodeList JavaDoc;
22 import scriptella.expression.PropertiesSubstitutor;
23 import scriptella.spi.AbstractConnection;
24 import scriptella.spi.ParametersCallback;
25 import scriptella.spi.QueryCallback;
26 import scriptella.spi.Resource;
27 import scriptella.util.IOUtils;
28 import scriptella.util.StringUtils;
29
30 import javax.xml.xpath.XPathConstants JavaDoc;
31 import javax.xml.xpath.XPathExpression JavaDoc;
32 import javax.xml.xpath.XPathExpressionException JavaDoc;
33 import java.io.IOException JavaDoc;
34
35 /**
36  * Executor for XPath queries.
37  *
38  * @author Fyodor Kupolov
39  * @version 1.0
40  */

41 public class XPathQueryExecutor implements ParametersCallback {
42     private Node JavaDoc node;
43     private PropertiesSubstitutor substitutor = new PropertiesSubstitutor();
44     private Document JavaDoc document;
45     private String JavaDoc expressionStr;
46     private XPathExpressionCompiler compiler;
47     private AbstractConnection.StatementCounter counter;
48
49     /**
50      * Crates executor to query document using a specified xpath expression.
51      *
52      * @param document document to query.
53      * @param xpathResource resource with xpath expression.
54      * @param counter statement counter.
55      */

56     public XPathQueryExecutor(Document JavaDoc document, Resource xpathResource, XPathExpressionCompiler compiler, AbstractConnection.StatementCounter counter) {
57         this.document = document;
58         this.compiler = compiler;
59         this.counter = counter;
60         try {
61             expressionStr = IOUtils.toString(xpathResource.open());
62         } catch (IOException JavaDoc e) {
63             throw new XPathProviderException("Unable to read XPath query content");
64         }
65     }
66
67     /**
68      * Executes a query and notifies queryCallback for each found node.
69      *
70      * @param queryCallback callback to notify for each found node.
71      * @param parentParameters parent parameters to inherit.
72      */

73     public void execute(final QueryCallback queryCallback, final ParametersCallback parentParameters) {
74         try {
75             substitutor.setParameters(parentParameters);
76             XPathExpression JavaDoc xpathExpression = compiler.compile(substitutor.substitute(expressionStr));
77             NodeList JavaDoc nList = (NodeList JavaDoc) xpathExpression.evaluate(document, XPathConstants.NODESET);
78             counter.statements++;
79             int n = nList.getLength();
80             for (int i = 0; i < n; i++) {
81                 node = nList.item(i);
82                 queryCallback.processRow(this);
83             }
84         } catch (XPathExpressionException JavaDoc e) {
85             throw new XPathProviderException("Failed to evaluate XPath query", e);
86         } finally {
87             substitutor.setParameters(null);
88         }
89     }
90
91     public Object JavaDoc getParameter(final String JavaDoc name) {
92         Object JavaDoc result = null;
93         //If name is a number and node has attributes - try to get an attribute by index
94

95         if (node instanceof Element JavaDoc) { //if element
96
//Now we use a trick to determine if node contains "name" attribute
97
//element.getAttribute returns "" for declared and declared attributes
98
Node JavaDoc item = node.getAttributes().getNamedItem(name);
99             result = item == null ? null : StringUtils.nullsafeTrim(item.getNodeValue()); //Get attribute value for name
100
}
101         //If previos check was unsucessful and the selected node has specified name
102
if (result == null && name.equals(node.getNodeName())) {
103             result = StringUtils.nullsafeTrim(node.getTextContent()); //returns its text content
104
}
105         //If previos check was unsucessful and the selected node is an element
106
if (result == null && node instanceof Element JavaDoc) {
107             Element JavaDoc element = (Element JavaDoc) node;
108             NodeList JavaDoc list = element.getElementsByTagName(name);
109             int n = list.getLength();
110             //If element contains children with specified name
111
//Convert these elements to text and return a string instance or array
112
if (n > 0) {
113                 String JavaDoc[] r = new String JavaDoc[n];
114                 for (int i = 0; i < n; i++) {
115                     r[i] = StringUtils.nullsafeTrim(list.item(i).getTextContent());
116                 }
117                 result = r.length > 1 ? r : r[0];
118             }
119         }
120         //if result=null fallback to parent parameters
121
return result == null ? substitutor.getParameters().getParameter(name) : result;
122     }
123 }
124
Popular Tags