KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > utils > XPathFuncHereAPI


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

18 package com.sun.org.apache.xml.internal.security.utils;
19
20
21
22 import javax.xml.transform.TransformerException JavaDoc;
23
24 import com.sun.org.apache.xml.internal.security.transforms.implementations.FuncHereContext;
25 import com.sun.org.apache.xml.internal.utils.PrefixResolver;
26 import com.sun.org.apache.xml.internal.utils.PrefixResolverDefault;
27 import com.sun.org.apache.xpath.internal.XPath;
28 import com.sun.org.apache.xpath.internal.objects.XObject;
29 import org.w3c.dom.Attr JavaDoc;
30 import org.w3c.dom.Document JavaDoc;
31 import org.w3c.dom.Node JavaDoc;
32 import org.w3c.dom.NodeList JavaDoc;
33 import org.w3c.dom.ProcessingInstruction JavaDoc;
34 import org.w3c.dom.Text JavaDoc;
35 import org.w3c.dom.traversal.NodeIterator;
36
37
38
39
40 /**
41  * This class does the same as {@link com.sun.org.apache.xpath.internal.XPathAPI} except that the XPath strings
42  * are not supplied as Strings but as {@link Text}, {@link Attr}ibute or
43  * {ProcessingInstruction} nodes which contain the XPath string. This enables
44  * us to use the <CODE>here()</CODE> function.
45  * <BR>
46  * The methods in this class are convenience methods into the low-level XPath API.
47  * These functions tend to be a little slow, since a number of objects must be
48  * created for each evaluation. A faster way is to precompile the
49  * XPaths using the low-level API, and then just use the XPaths
50  * over and over.
51  *
52  * @author $Author: raul $
53  * @see <a HREF="http://www.w3.org/TR/xpath">XPath Specification</a>
54  */

55 public class XPathFuncHereAPI {
56
57    /**
58     * Use an XPath string to select a single node. XPath namespace
59     * prefixes are resolved from the context node, which may not
60     * be what you want (see the next method).
61     *
62     * @param contextNode The node to start searching from.
63     * @param xpathnode A Node containing a valid XPath string.
64     * @return The first node found that matches the XPath, or null.
65     *
66     * @throws TransformerException
67     */

68    public static Node JavaDoc selectSingleNode(Node JavaDoc contextNode, Node JavaDoc xpathnode)
69            throws TransformerException JavaDoc {
70       return selectSingleNode(contextNode, xpathnode, contextNode);
71    }
72
73    /**
74     * Use an XPath string to select a single node.
75     * XPath namespace prefixes are resolved from the namespaceNode.
76     *
77     * @param contextNode The node to start searching from.
78     * @param xpathnode
79     * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
80     * @return The first node found that matches the XPath, or null.
81     *
82     * @throws TransformerException
83     */

84    public static Node JavaDoc selectSingleNode(
85            Node JavaDoc contextNode, Node JavaDoc xpathnode, Node JavaDoc namespaceNode)
86               throws TransformerException JavaDoc {
87
88       // Have the XObject return its result as a NodeSetDTM.
89
NodeIterator nl = selectNodeIterator(contextNode, xpathnode,
90                                            namespaceNode);
91
92       // Return the first node, or null
93
return nl.nextNode();
94    }
95
96    /**
97     * Use an XPath string to select a nodelist.
98     * XPath namespace prefixes are resolved from the contextNode.
99     *
100     * @param contextNode The node to start searching from.
101     * @param xpathnode
102     * @return A NodeIterator, should never be null.
103     *
104     * @throws TransformerException
105     */

106    public static NodeIterator selectNodeIterator(
107            Node JavaDoc contextNode, Node JavaDoc xpathnode) throws TransformerException JavaDoc {
108       return selectNodeIterator(contextNode, xpathnode, contextNode);
109    }
110
111    /**
112     * Use an XPath string to select a nodelist.
113     * XPath namespace prefixes are resolved from the namespaceNode.
114     *
115     * @param contextNode The node to start searching from.
116     * @param xpathnode
117     * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
118     * @return A NodeIterator, should never be null.
119     *
120     * @throws TransformerException
121     */

122    public static NodeIterator selectNodeIterator(
123            Node JavaDoc contextNode, Node JavaDoc xpathnode, Node JavaDoc namespaceNode)
124               throws TransformerException JavaDoc {
125
126       // Execute the XPath, and have it return the result
127
XObject list = eval(contextNode, xpathnode, namespaceNode);
128
129       // Have the XObject return its result as a NodeSetDTM.
130
return list.nodeset();
131    }
132
133    /**
134     * Use an XPath string to select a nodelist.
135     * XPath namespace prefixes are resolved from the contextNode.
136     *
137     * @param contextNode The node to start searching from.
138     * @param xpathnode
139     * @return A NodeIterator, should never be null.
140     *
141     * @throws TransformerException
142     */

143    public static NodeList JavaDoc selectNodeList(Node JavaDoc contextNode, Node JavaDoc xpathnode)
144            throws TransformerException JavaDoc {
145       return selectNodeList(contextNode, xpathnode, contextNode);
146    }
147
148    /**
149     * Use an XPath string to select a nodelist.
150     * XPath namespace prefixes are resolved from the namespaceNode.
151     *
152     * @param contextNode The node to start searching from.
153     * @param xpathnode
154     * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
155     * @return A NodeIterator, should never be null.
156     *
157     * @throws TransformerException
158     */

159    public static NodeList JavaDoc selectNodeList(
160            Node JavaDoc contextNode, Node JavaDoc xpathnode, Node JavaDoc namespaceNode)
161               throws TransformerException JavaDoc {
162
163       // Execute the XPath, and have it return the result
164
XObject list = eval(contextNode, xpathnode, namespaceNode);
165
166       // Return a NodeList.
167
return list.nodelist();
168    }
169
170    /**
171     * Evaluate XPath string to an XObject. Using this method,
172     * XPath namespace prefixes will be resolved from the namespaceNode.
173     * @param contextNode The node to start searching from.
174     * @param xpathnode
175     * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
176     * @see com.sun.org.apache.xpath.internal.objects.XObject
177     * @see com.sun.org.apache.xpath.internal.objects.XNull
178     * @see com.sun.org.apache.xpath.internal.objects.XBoolean
179     * @see com.sun.org.apache.xpath.internal.objects.XNumber
180     * @see com.sun.org.apache.xpath.internal.objects.XString
181     * @see com.sun.org.apache.xpath.internal.objects.XRTreeFrag
182     *
183     * @throws TransformerException
184     */

185    public static XObject eval(Node JavaDoc contextNode, Node JavaDoc xpathnode)
186            throws TransformerException JavaDoc {
187       return eval(contextNode, xpathnode, contextNode);
188    }
189
190    /**
191     * Evaluate XPath string to an XObject.
192     * XPath namespace prefixes are resolved from the namespaceNode.
193     * The implementation of this is a little slow, since it creates
194     * a number of objects each time it is called. This could be optimized
195     * to keep the same objects around, but then thread-safety issues would arise.
196     *
197     * @param contextNode The node to start searching from.
198     * @param xpathnode
199     * @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
200     * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
201     * @see com.sun.org.apache.xpath.internal.objects.XObject
202     * @see com.sun.org.apache.xpath.internal.objects.XNull
203     * @see com.sun.org.apache.xpath.internal.objects.XBoolean
204     * @see com.sun.org.apache.xpath.internal.objects.XNumber
205     * @see com.sun.org.apache.xpath.internal.objects.XString
206     * @see com.sun.org.apache.xpath.internal.objects.XRTreeFrag
207     *
208     * @throws TransformerException
209     */

210    public static XObject eval(
211            Node JavaDoc contextNode, Node JavaDoc xpathnode, Node JavaDoc namespaceNode)
212               throws TransformerException JavaDoc {
213
214       // Since we don't have a XML Parser involved here, install some default support
215
// for things like namespaces, etc.
216
// (Changed from: XPathContext xpathSupport = new XPathContext();
217
// because XPathContext is weak in a number of areas... perhaps
218
// XPathContext should be done away with.)
219
FuncHereContext xpathSupport = new FuncHereContext(xpathnode);
220
221       // Create an object to resolve namespace prefixes.
222
// XPath namespaces are resolved from the input context node's document element
223
// if it is a root node, or else the current context node (for lack of a better
224
// resolution space, given the simplicity of this sample code).
225
PrefixResolverDefault prefixResolver =
226          new PrefixResolverDefault((namespaceNode.getNodeType()
227                                     == Node.DOCUMENT_NODE)
228                                    ? ((Document JavaDoc) namespaceNode)
229                                       .getDocumentElement()
230                                    : namespaceNode);
231       String JavaDoc str = getStrFromNode(xpathnode);
232
233       // Create the XPath object.
234
XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null);
235
236       // Execute the XPath, and have it return the result
237
// return xpath.execute(xpathSupport, contextNode, prefixResolver);
238
int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);
239
240       return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
241    }
242
243    /**
244     * Evaluate XPath string to an XObject.
245     * XPath namespace prefixes are resolved from the namespaceNode.
246     * The implementation of this is a little slow, since it creates
247     * a number of objects each time it is called. This could be optimized
248     * to keep the same objects around, but then thread-safety issues would arise.
249     *
250     * @param contextNode The node to start searching from.
251     * @param xpathnode
252     * @param prefixResolver Will be called if the parser encounters namespace
253     * prefixes, to resolve the prefixes to URLs.
254     * @return An XObject, which can be used to obtain a string, number, nodelist, etc, should never be null.
255     * @see com.sun.org.apache.xpath.internal.objects.XObject
256     * @see com.sun.org.apache.xpath.internal.objects.XNull
257     * @see com.sun.org.apache.xpath.internal.objects.XBoolean
258     * @see com.sun.org.apache.xpath.internal.objects.XNumber
259     * @see com.sun.org.apache.xpath.internal.objects.XString
260     * @see com.sun.org.apache.xpath.internal.objects.XRTreeFrag
261     *
262     * @throws TransformerException
263     */

264    public static XObject eval(
265            Node JavaDoc contextNode, Node JavaDoc xpathnode, PrefixResolver prefixResolver)
266               throws TransformerException JavaDoc {
267
268       String JavaDoc str = getStrFromNode(xpathnode);
269
270       // Since we don't have a XML Parser involved here, install some default support
271
// for things like namespaces, etc.
272
// (Changed from: XPathContext xpathSupport = new XPathContext();
273
// because XPathContext is weak in a number of areas... perhaps
274
// XPathContext should be done away with.)
275
// Create the XPath object.
276
XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null);
277
278       // Execute the XPath, and have it return the result
279
FuncHereContext xpathSupport = new FuncHereContext(xpathnode);
280       int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);
281
282       return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
283    }
284
285    /**
286     * Method getStrFromNode
287     *
288     * @param xpathnode
289     * @return the string from the node
290     */

291    private static String JavaDoc getStrFromNode(Node JavaDoc xpathnode) {
292
293       if (xpathnode.getNodeType() == Node.TEXT_NODE) {
294          return ((Text JavaDoc) xpathnode).getData();
295       } else if (xpathnode.getNodeType() == Node.ATTRIBUTE_NODE) {
296          return ((Attr JavaDoc) xpathnode).getNodeValue();
297       } else if (xpathnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
298          return ((ProcessingInstruction JavaDoc) xpathnode).getNodeValue();
299       }
300
301       return "";
302    }
303 }
304
Popular Tags