Mercurial > repos > pfrommolt > ngsrich
comparison NGSrich_0.5.5/src/org/jdom/xpath/XPath.java @ 0:89ad0a9cca52 default tip
Uploaded
author | pfrommolt |
---|---|
date | Mon, 21 Nov 2011 08:12:19 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:89ad0a9cca52 |
---|---|
1 /*-- | |
2 | |
3 $Id: XPath.java,v 1.17 2007/11/10 05:29:02 jhunter Exp $ | |
4 | |
5 Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. | |
6 All rights reserved. | |
7 | |
8 Redistribution and use in source and binary forms, with or without | |
9 modification, are permitted provided that the following conditions | |
10 are met: | |
11 | |
12 1. Redistributions of source code must retain the above copyright | |
13 notice, this list of conditions, and the following disclaimer. | |
14 | |
15 2. Redistributions in binary form must reproduce the above copyright | |
16 notice, this list of conditions, and the disclaimer that follows | |
17 these conditions in the documentation and/or other materials | |
18 provided with the distribution. | |
19 | |
20 3. The name "JDOM" must not be used to endorse or promote products | |
21 derived from this software without prior written permission. For | |
22 written permission, please contact <request_AT_jdom_DOT_org>. | |
23 | |
24 4. Products derived from this software may not be called "JDOM", nor | |
25 may "JDOM" appear in their name, without prior written permission | |
26 from the JDOM Project Management <request_AT_jdom_DOT_org>. | |
27 | |
28 In addition, we request (but do not require) that you include in the | |
29 end-user documentation provided with the redistribution and/or in the | |
30 software itself an acknowledgement equivalent to the following: | |
31 "This product includes software developed by the | |
32 JDOM Project (http://www.jdom.org/)." | |
33 Alternatively, the acknowledgment may be graphical using the logos | |
34 available at http://www.jdom.org/images/logos. | |
35 | |
36 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |
37 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
38 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
39 DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT | |
40 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
41 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
42 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
43 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
44 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
45 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
46 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
47 SUCH DAMAGE. | |
48 | |
49 This software consists of voluntary contributions made by many | |
50 individuals on behalf of the JDOM Project and was originally | |
51 created by Jason Hunter <jhunter_AT_jdom_DOT_org> and | |
52 Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information | |
53 on the JDOM Project, please see <http://www.jdom.org/>. | |
54 | |
55 */ | |
56 | |
57 package org.jdom.xpath; | |
58 | |
59 | |
60 import java.io.*; | |
61 import java.lang.reflect.*; | |
62 import java.util.*; | |
63 | |
64 import org.jdom.*; | |
65 | |
66 | |
67 /** | |
68 * A utility class for performing XPath calls on JDOM nodes, with a factory | |
69 * interface for obtaining a first XPath instance. Users operate against this | |
70 * class while XPath vendors can plug-in implementations underneath. Users | |
71 * can choose an implementation using either {@link #setXPathClass} or | |
72 * the system property "org.jdom.xpath.class". | |
73 * | |
74 * @version $Revision: 1.17 $, $Date: 2007/11/10 05:29:02 $ | |
75 * @author Laurent Bihanic | |
76 */ | |
77 public abstract class XPath implements Serializable { | |
78 | |
79 private static final String CVS_ID = | |
80 "@(#) $RCSfile: XPath.java,v $ $Revision: 1.17 $ $Date: 2007/11/10 05:29:02 $ $Name: jdom_1_1_1 $"; | |
81 | |
82 /** | |
83 * The name of the system property from which to retrieve the | |
84 * name of the implementation class to use. | |
85 * <p> | |
86 * The property name is: | |
87 * "<code>org.jdom.xpath.class</code>".</p> | |
88 */ | |
89 private final static String XPATH_CLASS_PROPERTY = "org.jdom.xpath.class"; | |
90 | |
91 /** | |
92 * The default implementation class to use if none was configured. | |
93 */ | |
94 private final static String DEFAULT_XPATH_CLASS = | |
95 "org.jdom.xpath.JaxenXPath"; | |
96 | |
97 /** | |
98 * The string passable to the JAXP 1.3 XPathFactory isObjectModelSupported() | |
99 * method to query an XPath engine regarding its support for JDOM. Defined | |
100 * to be the well-known URI "http://jdom.org/jaxp/xpath/jdom". | |
101 */ | |
102 public final static String JDOM_OBJECT_MODEL_URI = | |
103 "http://jdom.org/jaxp/xpath/jdom"; | |
104 | |
105 /** | |
106 * The constructor to instanciate a new XPath concrete | |
107 * implementation. | |
108 * | |
109 * @see #newInstance | |
110 */ | |
111 private static Constructor constructor = null; | |
112 | |
113 /** | |
114 * Creates a new XPath wrapper object, compiling the specified | |
115 * XPath expression. | |
116 * | |
117 * @param path the XPath expression to wrap. | |
118 * | |
119 * @throws JDOMException if the XPath expression is invalid. | |
120 */ | |
121 public static XPath newInstance(String path) throws JDOMException { | |
122 try { | |
123 if (constructor == null) { | |
124 // First call => Determine implementation. | |
125 String className; | |
126 try { | |
127 className = System.getProperty(XPATH_CLASS_PROPERTY, | |
128 DEFAULT_XPATH_CLASS); | |
129 } | |
130 catch (SecurityException ex1) { | |
131 // Access to system property denied. => Use default impl. | |
132 className = DEFAULT_XPATH_CLASS; | |
133 } | |
134 setXPathClass(Class.forName(className)); | |
135 } | |
136 // Allocate and return new implementation instance. | |
137 return (XPath)constructor.newInstance(new Object[] { path }); | |
138 } | |
139 catch (JDOMException ex1) { | |
140 throw ex1; | |
141 } | |
142 catch (InvocationTargetException ex2) { | |
143 // Constructor threw an error on invocation. | |
144 Throwable t = ex2.getTargetException(); | |
145 | |
146 throw (t instanceof JDOMException)? (JDOMException)t: | |
147 new JDOMException(t.toString(), t); | |
148 } | |
149 catch (Exception ex3) { | |
150 // Any reflection error (probably due to a configuration mistake). | |
151 throw new JDOMException(ex3.toString(), ex3); | |
152 } | |
153 } | |
154 | |
155 /** | |
156 * Sets the concrete XPath subclass to use when allocating XPath | |
157 * instances. | |
158 * | |
159 * @param aClass the concrete subclass of XPath. | |
160 * | |
161 * @throws IllegalArgumentException if <code>aClass</code> is | |
162 * <code>null</code>. | |
163 * @throws JDOMException if <code>aClass</code> is | |
164 * not a concrete subclass | |
165 * of XPath. | |
166 */ | |
167 public static void setXPathClass(Class aClass) throws JDOMException { | |
168 if (aClass == null) { | |
169 throw new IllegalArgumentException("aClass"); | |
170 } | |
171 | |
172 try { | |
173 if ((XPath.class.isAssignableFrom(aClass)) && | |
174 (Modifier.isAbstract(aClass.getModifiers()) == false)) { | |
175 // Concrete subclass of XPath => Get constructor | |
176 constructor = aClass.getConstructor(new Class[] { String.class }); | |
177 } | |
178 else { | |
179 throw new JDOMException(aClass.getName() + | |
180 " is not a concrete JDOM XPath implementation"); | |
181 } | |
182 } | |
183 catch (JDOMException ex1) { | |
184 throw ex1; | |
185 } | |
186 catch (Exception ex2) { | |
187 // Any reflection error (probably due to a configuration mistake). | |
188 throw new JDOMException(ex2.toString(), ex2); | |
189 } | |
190 } | |
191 | |
192 /** | |
193 * Evaluates the wrapped XPath expression and returns the list | |
194 * of selected items. | |
195 * | |
196 * @param context the node to use as context for evaluating | |
197 * the XPath expression. | |
198 * | |
199 * @return the list of selected items, which may be of types: {@link Element}, | |
200 * {@link Attribute}, {@link Text}, {@link CDATA}, | |
201 * {@link Comment}, {@link ProcessingInstruction}, Boolean, | |
202 * Double, or String. | |
203 * | |
204 * @throws JDOMException if the evaluation of the XPath | |
205 * expression on the specified context | |
206 * failed. | |
207 */ | |
208 abstract public List selectNodes(Object context) throws JDOMException; | |
209 | |
210 /** | |
211 * Evaluates the wrapped XPath expression and returns the first | |
212 * entry in the list of selected nodes (or atomics). | |
213 * | |
214 * @param context the node to use as context for evaluating | |
215 * the XPath expression. | |
216 * | |
217 * @return the first selected item, which may be of types: {@link Element}, | |
218 * {@link Attribute}, {@link Text}, {@link CDATA}, | |
219 * {@link Comment}, {@link ProcessingInstruction}, Boolean, | |
220 * Double, String, or <code>null</code> if no item was selected. | |
221 * | |
222 * @throws JDOMException if the evaluation of the XPath | |
223 * expression on the specified context | |
224 * failed. | |
225 */ | |
226 abstract public Object selectSingleNode(Object context) throws JDOMException; | |
227 | |
228 /** | |
229 * Returns the string value of the first node selected by applying | |
230 * the wrapped XPath expression to the given context. | |
231 * | |
232 * @param context the element to use as context for evaluating | |
233 * the XPath expression. | |
234 * | |
235 * @return the string value of the first node selected by applying | |
236 * the wrapped XPath expression to the given context. | |
237 * | |
238 * @throws JDOMException if the XPath expression is invalid or | |
239 * its evaluation on the specified context | |
240 * failed. | |
241 */ | |
242 abstract public String valueOf(Object context) throws JDOMException; | |
243 | |
244 /** | |
245 * Returns the number value of the first node selected by applying | |
246 * the wrapped XPath expression to the given context. | |
247 * | |
248 * @param context the element to use as context for evaluating | |
249 * the XPath expression. | |
250 * | |
251 * @return the number value of the first node selected by applying | |
252 * the wrapped XPath expression to the given context, | |
253 * <code>null</code> if no node was selected or the | |
254 * special value {@link java.lang.Double#NaN} | |
255 * (Not-a-Number) if the selected value can not be | |
256 * converted into a number value. | |
257 * | |
258 * @throws JDOMException if the XPath expression is invalid or | |
259 * its evaluation on the specified context | |
260 * failed. | |
261 */ | |
262 abstract public Number numberValueOf(Object context) throws JDOMException; | |
263 | |
264 /** | |
265 * Defines an XPath variable and sets its value. | |
266 * | |
267 * @param name the variable name. | |
268 * @param value the variable value. | |
269 * | |
270 * @throws IllegalArgumentException if <code>name</code> is not | |
271 * a valid XPath variable name | |
272 * or if the value type is not | |
273 * supported by the underlying | |
274 * implementation | |
275 */ | |
276 abstract public void setVariable(String name, Object value); | |
277 | |
278 /** | |
279 * Adds a namespace definition to the list of namespaces known of | |
280 * this XPath expression. | |
281 * <p> | |
282 * <strong>Note</strong>: In XPath, there is no such thing as a | |
283 * 'default namespace'. The empty prefix <b>always</b> resolves | |
284 * to the empty namespace URI.</p> | |
285 * | |
286 * @param namespace the namespace. | |
287 */ | |
288 abstract public void addNamespace(Namespace namespace); | |
289 | |
290 /** | |
291 * Adds a namespace definition (prefix and URI) to the list of | |
292 * namespaces known of this XPath expression. | |
293 * <p> | |
294 * <strong>Note</strong>: In XPath, there is no such thing as a | |
295 * 'default namespace'. The empty prefix <b>always</b> resolves | |
296 * to the empty namespace URI.</p> | |
297 * | |
298 * @param prefix the namespace prefix. | |
299 * @param uri the namespace URI. | |
300 * | |
301 * @throws IllegalNameException if the prefix or uri are null or | |
302 * empty strings or if they contain | |
303 * illegal characters. | |
304 */ | |
305 public void addNamespace(String prefix, String uri) { | |
306 addNamespace(Namespace.getNamespace(prefix, uri)); | |
307 } | |
308 | |
309 /** | |
310 * Returns the wrapped XPath expression as a string. | |
311 * | |
312 * @return the wrapped XPath expression as a string. | |
313 */ | |
314 abstract public String getXPath(); | |
315 | |
316 | |
317 /** | |
318 * Evaluates an XPath expression and returns the list of selected | |
319 * items. | |
320 * <p> | |
321 * <strong>Note</strong>: This method should not be used when the | |
322 * same XPath expression needs to be applied several times (on the | |
323 * same or different contexts) as it requires the expression to be | |
324 * compiled before being evaluated. In such cases, | |
325 * {@link #newInstance allocating} an XPath wrapper instance and | |
326 * {@link #selectNodes(java.lang.Object) evaluating} it several | |
327 * times is way more efficient. | |
328 * </p> | |
329 * | |
330 * @param context the node to use as context for evaluating | |
331 * the XPath expression. | |
332 * @param path the XPath expression to evaluate. | |
333 * | |
334 * @return the list of selected items, which may be of types: {@link Element}, | |
335 * {@link Attribute}, {@link Text}, {@link CDATA}, | |
336 * {@link Comment}, {@link ProcessingInstruction}, Boolean, | |
337 * Double, or String. | |
338 * | |
339 * @throws JDOMException if the XPath expression is invalid or | |
340 * its evaluation on the specified context | |
341 * failed. | |
342 */ | |
343 public static List selectNodes(Object context, String path) | |
344 throws JDOMException { | |
345 return newInstance(path).selectNodes(context); | |
346 } | |
347 | |
348 /** | |
349 * Evaluates the wrapped XPath expression and returns the first | |
350 * entry in the list of selected nodes (or atomics). | |
351 * <p> | |
352 * <strong>Note</strong>: This method should not be used when the | |
353 * same XPath expression needs to be applied several times (on the | |
354 * same or different contexts) as it requires the expression to be | |
355 * compiled before being evaluated. In such cases, | |
356 * {@link #newInstance allocating} an XPath wrapper instance and | |
357 * {@link #selectSingleNode(java.lang.Object) evaluating} it | |
358 * several times is way more efficient. | |
359 * </p> | |
360 * | |
361 * @param context the element to use as context for evaluating | |
362 * the XPath expression. | |
363 * @param path the XPath expression to evaluate. | |
364 * | |
365 * @return the first selected item, which may be of types: {@link Element}, | |
366 * {@link Attribute}, {@link Text}, {@link CDATA}, | |
367 * {@link Comment}, {@link ProcessingInstruction}, Boolean, | |
368 * Double, String, or <code>null</code> if no item was selected. | |
369 * | |
370 * @throws JDOMException if the XPath expression is invalid or | |
371 * its evaluation on the specified context | |
372 * failed. | |
373 */ | |
374 public static Object selectSingleNode(Object context, String path) | |
375 throws JDOMException { | |
376 return newInstance(path).selectSingleNode(context); | |
377 } | |
378 | |
379 | |
380 //------------------------------------------------------------------------- | |
381 // Serialization support | |
382 //------------------------------------------------------------------------- | |
383 | |
384 /** | |
385 * <i>[Serialization support]</i> Returns the alternative object | |
386 * to write to the stream when serializing this object. This | |
387 * method returns an instance of a dedicated nested class to | |
388 * serialize XPath expressions independently of the concrete | |
389 * implementation being used. | |
390 * <p> | |
391 * <strong>Note</strong>: Subclasses are not allowed to override | |
392 * this method to ensure valid serialization of all | |
393 * implementations.</p> | |
394 * | |
395 * @return an XPathString instance configured with the wrapped | |
396 * XPath expression. | |
397 * | |
398 * @throws ObjectStreamException never. | |
399 */ | |
400 protected final Object writeReplace() throws ObjectStreamException { | |
401 return new XPathString(this.getXPath()); | |
402 } | |
403 | |
404 /** | |
405 * The XPathString is dedicated to serialize instances of | |
406 * XPath subclasses in a implementation-independent manner. | |
407 * <p> | |
408 * XPathString ensures that only string data are serialized. Upon | |
409 * deserialization, XPathString relies on XPath factory method to | |
410 * to create instances of the concrete XPath wrapper currently | |
411 * configured.</p> | |
412 */ | |
413 private final static class XPathString implements Serializable { | |
414 /** | |
415 * The XPath expression as a string. | |
416 */ | |
417 private String xPath = null; | |
418 | |
419 /** | |
420 * Creates a new XPathString instance from the specified | |
421 * XPath expression. | |
422 * | |
423 * @param xpath the XPath expression. | |
424 */ | |
425 public XPathString(String xpath) { | |
426 super(); | |
427 | |
428 this.xPath = xpath; | |
429 } | |
430 | |
431 /** | |
432 * <i>[Serialization support]</i> Resolves the read XPathString | |
433 * objects into XPath implementations. | |
434 * | |
435 * @return an instance of a concrete implementation of | |
436 * XPath. | |
437 * | |
438 * @throws ObjectStreamException if no XPath could be built | |
439 * from the read object. | |
440 */ | |
441 private Object readResolve() throws ObjectStreamException { | |
442 try { | |
443 return XPath.newInstance(this.xPath); | |
444 } | |
445 catch (JDOMException ex1) { | |
446 throw new InvalidObjectException( | |
447 "Can't create XPath object for expression \"" + | |
448 this.xPath + "\": " + ex1.toString()); | |
449 } | |
450 } | |
451 } | |
452 } | |
453 |