KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > ejb > cmp3 > xml > parser > XPathEngine


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.internal.ejb.cmp3.xml.parser;
23
24 import org.w3c.dom.Element JavaDoc;
25 import org.w3c.dom.Node JavaDoc;
26 import org.w3c.dom.NodeList JavaDoc;
27 import org.w3c.dom.Text JavaDoc;
28
29 /**
30  * INTERNAL
31  * Utility class for finding XML nodes using XPath expressions.
32  */

33 public class XPathEngine {
34     private static final String JavaDoc ATTRIBUTE = "@";
35     private static final String JavaDoc TEXT = "text()";
36     private static final String JavaDoc ALL_CHILDREN = "child::*";
37     private static final String JavaDoc NAMESPACE_URI = "http://java.sun.com/xml/ns/persistence/orm";
38     private static XPathEngine instance = null;
39
40     private XPathEngine() {
41         super();
42     }
43
44     /**
45      * Return the <code>XPathEngine</code> singleton.
46      */

47     public static XPathEngine getInstance() {
48         if (instance == null) {
49             instance = new XPathEngine();
50         }
51         return instance;
52     }
53
54     /**
55      * Execute the XPath statement relative to the context node.
56      *
57      * @param contextNode the node relative to which the XPath statement will be executed
58      * @param xmlField the field containing the XPath statement to be executed
59      * @param namespaceResolver used to resolve namespace prefixes to the corresponding namespace URI
60      * @return the first node located matching the XPath statement
61      * @throws XMLPlatformException
62      */

63     public Node JavaDoc selectSingleNode(Node JavaDoc contextNode, String JavaDoc[] xPathFragments) {
64         if (contextNode == null) {
65             return null;
66         }
67
68         return selectSingleNode(contextNode, xPathFragments, 0);
69     }
70
71     private Node JavaDoc selectSingleNode(Node JavaDoc contextNode, String JavaDoc[] xPathFragments, int index) {
72         Node JavaDoc resultNode = getSingleNode(contextNode, xPathFragments[index]);
73         if ((resultNode == null) || (xPathFragments.length == (index + 1))) {
74             return resultNode;
75         }
76
77         return selectSingleNode(resultNode, xPathFragments, index + 1);
78     }
79
80     /**
81      * Execute the XPath statement relative to the context node.
82      *
83      * @param contextNode the node relative to which the XPath statement will be executed
84      * @param xmlField the field containing the XPath statement to be executed
85      * @param namespaceResolver used to resolve namespace prefixes to the corresponding namespace URI
86      * @return a list of nodes matching the XPath statement
87      * @throws XMLPlatformException
88      */

89     public NodeList JavaDoc selectNodes(Node JavaDoc contextNode, String JavaDoc[] xPathFragments) {
90         if (contextNode == null) {
91             return null;
92         }
93
94         return selectNodes(contextNode, xPathFragments, 0);
95     }
96
97     private NodeList JavaDoc selectNodes(Node JavaDoc contextNode, String JavaDoc[] xPathFragments, int index) {
98     
99         NodeList JavaDoc resultNodes = getNodes(contextNode, xPathFragments[index]);
100
101         if (xPathFragments.length != index + 1) {
102             Node JavaDoc resultNode;
103             XMLNodeList result = new XMLNodeList();
104             int numberOfResultNodes = resultNodes.getLength();
105             for (int x = 0; x < numberOfResultNodes; x++) {
106                 resultNode = resultNodes.item(x);
107                 result.addAll(selectNodes(resultNode, xPathFragments, index + 1));
108             }
109             return result;
110         }
111
112         return resultNodes;
113     }
114
115     private Node JavaDoc getSingleNode(Node JavaDoc contextNode, String JavaDoc xPathFragment) {
116         if (xPathFragment.startsWith(ATTRIBUTE)) {
117             return selectSingleAttribute(contextNode, xPathFragment);
118         } else if (TEXT.equals(xPathFragment)) {
119             return selectSingleText(contextNode);
120         }
121         return selectSingleElement(contextNode, xPathFragment);
122     }
123
124     private NodeList JavaDoc getNodes(Node JavaDoc contextNode, String JavaDoc xPathFragment) {
125         if (xPathFragment.startsWith(ATTRIBUTE)) {
126             return selectAttributeNodes(contextNode, xPathFragment);
127         } else if (TEXT.equals(xPathFragment)) {
128             return selectTextNodes(contextNode);
129         } else if (xPathFragment.equals(ALL_CHILDREN)) {
130             return selectChildElements(contextNode);
131         }
132         return selectElementNodes(contextNode, xPathFragment);
133
134     }
135
136     private Node JavaDoc selectSingleAttribute(Node JavaDoc contextNode, String JavaDoc xPathFragment) {
137         Element JavaDoc contextElement = (Element JavaDoc)contextNode;
138         return contextElement.getAttributeNode(xPathFragment.substring(1));
139     }
140
141     private NodeList JavaDoc selectAttributeNodes(Node JavaDoc contextNode, String JavaDoc xPathFragment) {
142         XMLNodeList xmlNodeList = new XMLNodeList();
143
144         Node JavaDoc child = selectSingleAttribute(contextNode, xPathFragment);
145         if (null != child) {
146             xmlNodeList.add(child);
147         }
148         return xmlNodeList;
149     }
150
151     private Node JavaDoc selectSingleElement(Node JavaDoc contextNode, String JavaDoc xPathFragment) {
152         Node JavaDoc child = contextNode.getFirstChild();
153         while (null != child) {
154             if ((child.getNodeType() == Node.ELEMENT_NODE) && sameName(child, xPathFragment) && sameNamespaceURI(child, NAMESPACE_URI)) {
155                 return child;
156             }
157
158             child = child.getNextSibling();
159         }
160         return null;
161     }
162
163     private NodeList JavaDoc selectChildElements(Node JavaDoc contextNode) {
164         XMLNodeList xmlNodeList = new XMLNodeList();
165         Node JavaDoc child = contextNode.getFirstChild();
166
167         while (child != null) {
168             if (child.getNodeType() == Node.ELEMENT_NODE) {
169                 xmlNodeList.add(child);
170             }
171             child = child.getNextSibling();
172         }
173
174         return xmlNodeList;
175     }
176
177     private NodeList JavaDoc selectElementNodes(Node JavaDoc contextNode, String JavaDoc xPathFragment) {
178         XMLNodeList xmlNodeList = new XMLNodeList();
179         Node JavaDoc child = contextNode.getFirstChild();
180
181         while (null != child) {
182             if ((child.getNodeType() == Node.ELEMENT_NODE) && sameName(child, xPathFragment) && sameNamespaceURI(child, NAMESPACE_URI)) {
183                 xmlNodeList.add(child);
184             }
185
186             child = child.getNextSibling();
187         }
188
189         return xmlNodeList;
190     }
191
192     private Node JavaDoc selectSingleText(Node JavaDoc contextNode) {
193         NodeList JavaDoc childrenNodes = contextNode.getChildNodes();
194
195         if (childrenNodes.getLength() == 0) {
196             return null;
197         }
198
199         if (childrenNodes.getLength() == 1) {
200             Node JavaDoc child = childrenNodes.item(0);
201             if (child.getNodeType() == Node.TEXT_NODE) {
202                 return child;
203             }
204             return null;
205         }
206
207         String JavaDoc returnVal = null;
208         for (int i = 0; i < childrenNodes.getLength(); i++) {
209             Node JavaDoc next = childrenNodes.item(i);
210             if (next.getNodeType() == Node.TEXT_NODE) {
211                 String JavaDoc val = ((Text JavaDoc)next).getNodeValue();
212                 if (val != null) {
213                     if (returnVal == null) {
214                         returnVal = new String JavaDoc();
215                     }
216                     returnVal += val;
217                 }
218             }
219         }
220
221         //bug#4515249 a new text node was being created when null should have been returned
222
//case where contextNode had several children but no Text children
223
if (returnVal != null) {
224             return contextNode.getOwnerDocument().createTextNode(returnVal);
225         }
226         return null;
227     }
228
229     private NodeList JavaDoc selectTextNodes(Node JavaDoc contextNode) {
230         Node JavaDoc n = selectSingleText(contextNode);
231
232         XMLNodeList xmlNodeList = new XMLNodeList();
233         if (n != null) {
234             xmlNodeList.add(n);
235         }
236         return xmlNodeList;
237     }
238
239     private boolean sameNamespaceURI(Node JavaDoc node, String JavaDoc namespaceURI) {
240         // HANDLE THE NULL CASE
241
String JavaDoc nodeNamespaceURI = node.getNamespaceURI();
242         if (nodeNamespaceURI == namespaceURI) {
243             return true;
244         }
245
246         if ((nodeNamespaceURI == null) && namespaceURI.equals("")) {
247             return true;
248         }
249
250         if ((namespaceURI == null) && nodeNamespaceURI.equals("")) {
251             return true;
252         }
253
254         // HANDLE THE NON-NULL CASE
255
return (null != nodeNamespaceURI) && nodeNamespaceURI.equals(namespaceURI);
256     }
257
258     private boolean sameName(Node JavaDoc node, String JavaDoc name) {
259         return name.equals(node.getLocalName()) || name.equals(node.getNodeName());
260     }
261 }
262
Popular Tags