Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
NamespaceNode |
|
| 1.934782608695652;1.935 | ||||
NamespaceNode$1 |
|
| 1.934782608695652;1.935 | ||||
NamespaceNode$EmptyNodeList |
|
| 1.934782608695652;1.935 |
1 | /* | |
2 | * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom/NamespaceNode.java,v 1.25 2006/07/03 11:14:05 elharo Exp $ | |
3 | * $Revision: 1.25 $ | |
4 | * $Date: 2006/07/03 11:14:05 $ | |
5 | * | |
6 | * ==================================================================== | |
7 | * | |
8 | * Copyright 2000-2002 bob mcwhirter & James Strachan. | |
9 | * All rights reserved. | |
10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions are | |
13 | * met: | |
14 | * | |
15 | * * Redistributions of source code must retain the above copyright | |
16 | * notice, this list of conditions and the following disclaimer. | |
17 | * | |
18 | * * Redistributions in binary form must reproduce the above copyright | |
19 | * notice, this list of conditions and the following disclaimer in the | |
20 | * documentation and/or other materials provided with the distribution. | |
21 | * | |
22 | * * Neither the name of the Jaxen Project nor the names of its | |
23 | * contributors may be used to endorse or promote products derived | |
24 | * from this software without specific prior written permission. | |
25 | * | |
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
27 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
28 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | |
29 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | |
30 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
31 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
32 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
33 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
34 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
35 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
37 | * | |
38 | * ==================================================================== | |
39 | * This software consists of voluntary contributions made by many | |
40 | * individuals on behalf of the Jaxen Project and was originally | |
41 | * created by bob mcwhirter <bob@werken.com> and | |
42 | * James Strachan <jstrachan@apache.org>. For more information on the | |
43 | * Jaxen Project, please see <http://www.jaxen.org/>. | |
44 | * | |
45 | * $Id: NamespaceNode.java,v 1.25 2006/07/03 11:14:05 elharo Exp $ | |
46 | */ | |
47 | ||
48 | //////////////////////////////////////////////////////////////////// | |
49 | // Inner class for a Namespace node. | |
50 | //////////////////////////////////////////////////////////////////// | |
51 | ||
52 | package org.jaxen.dom; | |
53 | ||
54 | import java.lang.reflect.InvocationTargetException; | |
55 | import java.lang.reflect.Method; | |
56 | import java.util.HashMap; | |
57 | ||
58 | import org.jaxen.pattern.Pattern; | |
59 | import org.w3c.dom.DOMException; | |
60 | import org.w3c.dom.Document; | |
61 | import org.w3c.dom.NamedNodeMap; | |
62 | import org.w3c.dom.Node; | |
63 | import org.w3c.dom.NodeList; | |
64 | import org.w3c.dom.UserDataHandler; | |
65 | ||
66 | ||
67 | /** | |
68 | * Extension DOM2/DOM3 node type for a namespace node. | |
69 | * | |
70 | * <p>This class implements the DOM2 and DOM3 {@link Node} interface | |
71 | * to allow namespace nodes to be included in the result | |
72 | * set of an XPath selectNodes operation, even though DOM does | |
73 | * not model namespaces in scope as separate nodes.</p> | |
74 | * | |
75 | * <p> | |
76 | * While all of the DOM2 methods are implemented with reasonable | |
77 | * defaults, there will be some unexpected surprises, so users are | |
78 | * advised to test for NamespaceNodes and filter them out from the | |
79 | * result sets as early as possible. | |
80 | * </p> | |
81 | * | |
82 | * <ol> | |
83 | * | |
84 | * <li>The {@link #getNodeType} method returns {@link #NAMESPACE_NODE}, | |
85 | * which is not one of the usual DOM2 node types. Generic code may | |
86 | * fall unexpectedly out of switch statements, for example.</li> | |
87 | * | |
88 | * <li>The {@link #getOwnerDocument} method returns the owner document | |
89 | * of the parent node, but that owner document will know nothing about | |
90 | * the namespace node.</p> | |
91 | * | |
92 | * <li>The {@link #isSupported} method always returns false.</li> | |
93 | * | |
94 | * <li> The DOM3 methods sometimes throw UnsupportedOperationException. | |
95 | * They're here only to allow this class to be compiled with Java 1.5. | |
96 | * Do not call or rely on them.</li> | |
97 | * </ol> | |
98 | * | |
99 | * <p>All attempts to modify a <code>NamespaceNode</code> will fail with a {@link | |
100 | * DOMException} ({@link | |
101 | * DOMException#NO_MODIFICATION_ALLOWED_ERR}).</p> | |
102 | * | |
103 | * @author David Megginson | |
104 | * @author Elliotte Rusty Harold | |
105 | * @see DocumentNavigator | |
106 | */ | |
107 | public class NamespaceNode implements Node | |
108 | { | |
109 | ||
110 | /** | |
111 | * Constant: this is a NamespaceNode. | |
112 | * | |
113 | * @see #getNodeType | |
114 | */ | |
115 | public final static short NAMESPACE_NODE = Pattern.NAMESPACE_NODE; | |
116 | ||
117 | // FIXME "Note: Numeric codes up to 200 are reserved to W3C for possible future use." | |
118 | // We should be using higher codes. Here we're using 13, the same as DOM 3's type for XPathNamespace. | |
119 | // However, that's only a note not a recommendation. | |
120 | ||
121 | /** | |
122 | * Create a new NamespaceNode. | |
123 | * | |
124 | * @param parent the DOM node to which the namespace is attached | |
125 | * @param name the namespace prefix | |
126 | * @param value the namespace URI | |
127 | */ | |
128 | public NamespaceNode (Node parent, String name, String value) | |
129 | 284 | { |
130 | 284 | this.parent = parent; |
131 | 284 | this.name = name; |
132 | 284 | this.value = value; |
133 | 284 | } |
134 | ||
135 | ||
136 | /** | |
137 | * Constructor. | |
138 | * | |
139 | * @param parent the DOM node to which the namespace is attached | |
140 | * @param attribute the DOM attribute object containing the | |
141 | * namespace declaration | |
142 | */ | |
143 | NamespaceNode (Node parent, Node attribute) | |
144 | 202 | { |
145 | 202 | String attributeName = attribute.getNodeName(); |
146 | ||
147 | 202 | if (attributeName.equals("xmlns")) { |
148 | 0 | this.name = ""; |
149 | 0 | } |
150 | 202 | else if (attributeName.startsWith("xmlns:")) { |
151 | 202 | this.name = attributeName.substring(6); // the part after "xmlns:" |
152 | 202 | } |
153 | else { // workaround for Crimson bug; Crimson incorrectly reports the prefix as the node name | |
154 | 0 | this.name = attributeName; |
155 | } | |
156 | 202 | this.parent = parent; |
157 | 202 | this.value = attribute.getNodeValue(); |
158 | 202 | } |
159 | ||
160 | ||
161 | ||
162 | //////////////////////////////////////////////////////////////////// | |
163 | // Implementation of org.w3c.dom.Node. | |
164 | //////////////////////////////////////////////////////////////////// | |
165 | ||
166 | ||
167 | /** | |
168 | * Get the namespace prefix. | |
169 | * | |
170 | * @return the namespace prefix, or "" for the default namespace | |
171 | */ | |
172 | public String getNodeName () | |
173 | { | |
174 | 210 | return name; |
175 | } | |
176 | ||
177 | ||
178 | /** | |
179 | * Get the namespace URI. | |
180 | * | |
181 | * @return the namespace URI | |
182 | */ | |
183 | public String getNodeValue () | |
184 | { | |
185 | 28 | return value; |
186 | } | |
187 | ||
188 | ||
189 | /** | |
190 | * Change the namespace URI (always fails). | |
191 | * | |
192 | * @param value the new URI | |
193 | * @throws DOMException always | |
194 | */ | |
195 | public void setNodeValue (String value) throws DOMException | |
196 | { | |
197 | 0 | disallowModification(); |
198 | 0 | } |
199 | ||
200 | ||
201 | /** | |
202 | * Get the node type. | |
203 | * | |
204 | * @return always {@link #NAMESPACE_NODE}. | |
205 | */ | |
206 | public short getNodeType () | |
207 | { | |
208 | 3222 | return NAMESPACE_NODE; |
209 | } | |
210 | ||
211 | ||
212 | /** | |
213 | * Get the parent node. | |
214 | * | |
215 | * <p>This method returns the element that was queried for Namespaces | |
216 | * in effect, <em>not</em> necessarily the actual element containing | |
217 | * the Namespace declaration.</p> | |
218 | * | |
219 | * @return the parent node (not null) | |
220 | */ | |
221 | public Node getParentNode () | |
222 | { | |
223 | 786 | return parent; |
224 | } | |
225 | ||
226 | ||
227 | /** | |
228 | * Get the list of child nodes. | |
229 | * | |
230 | * @return an empty node list | |
231 | */ | |
232 | public NodeList getChildNodes () | |
233 | { | |
234 | 0 | return new EmptyNodeList(); |
235 | } | |
236 | ||
237 | ||
238 | /** | |
239 | * Get the first child node. | |
240 | * | |
241 | * @return null | |
242 | */ | |
243 | public Node getFirstChild () | |
244 | { | |
245 | 0 | return null; |
246 | } | |
247 | ||
248 | ||
249 | /** | |
250 | * Get the last child node. | |
251 | * | |
252 | * @return null | |
253 | */ | |
254 | public Node getLastChild () | |
255 | { | |
256 | 0 | return null; |
257 | } | |
258 | ||
259 | ||
260 | /** | |
261 | * Get the previous sibling node. | |
262 | * | |
263 | * @return null | |
264 | */ | |
265 | public Node getPreviousSibling () | |
266 | { | |
267 | 0 | return null; |
268 | } | |
269 | ||
270 | ||
271 | /** | |
272 | * Get the next sibling node. | |
273 | * | |
274 | * @return null | |
275 | */ | |
276 | public Node getNextSibling () | |
277 | { | |
278 | 0 | return null; |
279 | } | |
280 | ||
281 | ||
282 | /** | |
283 | * Get the attribute nodes. | |
284 | * | |
285 | * @return null | |
286 | */ | |
287 | public NamedNodeMap getAttributes () | |
288 | { | |
289 | 0 | return null; |
290 | } | |
291 | ||
292 | ||
293 | /** | |
294 | * Get the owner document. | |
295 | * | |
296 | * @return the owner document <em>of the parent node</em> | |
297 | */ | |
298 | public Document getOwnerDocument () | |
299 | { | |
300 | 0 | if (parent == null) return null; |
301 | 0 | return parent.getOwnerDocument(); |
302 | } | |
303 | ||
304 | ||
305 | /** | |
306 | * Insert a new child node (always fails). | |
307 | * | |
308 | * @param newChild the node to add | |
309 | * @param refChild ignored | |
310 | * @return never | |
311 | * @throws DOMException always | |
312 | * @see Node#insertBefore | |
313 | */ | |
314 | public Node insertBefore (Node newChild, Node refChild) | |
315 | throws DOMException | |
316 | { | |
317 | 0 | disallowModification(); |
318 | 0 | return null; |
319 | } | |
320 | ||
321 | ||
322 | /** | |
323 | * Replace a child node (always fails). | |
324 | * | |
325 | * @param newChild the node to add | |
326 | * @param oldChild the child node to replace | |
327 | * @return never | |
328 | * @throws DOMException always | |
329 | * @see Node#replaceChild | |
330 | */ | |
331 | public Node replaceChild (Node newChild, Node oldChild) throws DOMException | |
332 | { | |
333 | 0 | disallowModification(); |
334 | 0 | return null; |
335 | } | |
336 | ||
337 | ||
338 | /** | |
339 | * Remove a child node (always fails). | |
340 | * | |
341 | * @param oldChild the child node to remove | |
342 | * @return never | |
343 | * @throws DOMException always | |
344 | * @see Node#removeChild | |
345 | */ | |
346 | public Node removeChild(Node oldChild) throws DOMException | |
347 | { | |
348 | 0 | disallowModification(); |
349 | 0 | return null; |
350 | } | |
351 | ||
352 | ||
353 | /** | |
354 | * Append a new child node (always fails). | |
355 | * | |
356 | * @param newChild the node to add | |
357 | * @return never | |
358 | * @throws DOMException always | |
359 | * @see Node#appendChild | |
360 | */ | |
361 | public Node appendChild(Node newChild) throws DOMException | |
362 | { | |
363 | 0 | disallowModification(); |
364 | 0 | return null; |
365 | } | |
366 | ||
367 | ||
368 | /** | |
369 | * Test for child nodes. | |
370 | * | |
371 | * @return false | |
372 | */ | |
373 | public boolean hasChildNodes() | |
374 | { | |
375 | 0 | return false; |
376 | } | |
377 | ||
378 | ||
379 | /** | |
380 | * Create a copy of this node. | |
381 | * | |
382 | * @param deep make a deep copy (no effect, since namespace nodes | |
383 | * don't have children). | |
384 | * @return a new copy of this namespace node | |
385 | */ | |
386 | public Node cloneNode (boolean deep) | |
387 | { | |
388 | 0 | return new NamespaceNode(parent, name, value); |
389 | } | |
390 | ||
391 | ||
392 | /** | |
393 | * Normalize the text descendants of this node. | |
394 | * | |
395 | * <p>This method has no effect, since namespace nodes have no | |
396 | * descendants.</p> | |
397 | */ | |
398 | public void normalize () | |
399 | { | |
400 | // no op | |
401 | 0 | } |
402 | ||
403 | ||
404 | /** | |
405 | * Test if a DOM2 feature is supported. (None are.) | |
406 | * | |
407 | * @param feature the feature name | |
408 | * @param version the feature version | |
409 | * @return false | |
410 | */ | |
411 | public boolean isSupported(String feature, String version) | |
412 | { | |
413 | 0 | return false; |
414 | } | |
415 | ||
416 | ||
417 | /** | |
418 | * Get the namespace URI of this node. | |
419 | * | |
420 | * <p>Namespace declarations are not themselves | |
421 | * Namespace-qualified.</p> | |
422 | * | |
423 | * @return null | |
424 | */ | |
425 | public String getNamespaceURI() | |
426 | { | |
427 | 0 | return null; |
428 | } | |
429 | ||
430 | ||
431 | /** | |
432 | * Get the namespace prefix of this node. | |
433 | * | |
434 | * <p>Namespace declarations are not themselves | |
435 | * namespace-qualified.</p> | |
436 | * | |
437 | * @return null | |
438 | * @see #getLocalName | |
439 | */ | |
440 | public String getPrefix() | |
441 | { | |
442 | 0 | return null; |
443 | } | |
444 | ||
445 | ||
446 | /** | |
447 | * Change the namespace prefix of this node (always fails). | |
448 | * | |
449 | * @param prefix the new prefix | |
450 | * @throws DOMException always thrown | |
451 | */ | |
452 | public void setPrefix(String prefix) | |
453 | throws DOMException | |
454 | { | |
455 | 0 | disallowModification(); |
456 | 0 | } |
457 | ||
458 | ||
459 | /** | |
460 | * Get the XPath name of the namespace node;; i.e. the | |
461 | * namespace prefix. | |
462 | * | |
463 | * @return the namespace prefix | |
464 | */ | |
465 | public String getLocalName () | |
466 | { | |
467 | 328 | return name; |
468 | } | |
469 | ||
470 | ||
471 | /** | |
472 | * Test if this node has attributes. | |
473 | * | |
474 | * @return false | |
475 | */ | |
476 | public boolean hasAttributes () | |
477 | { | |
478 | 0 | return false; |
479 | } | |
480 | ||
481 | ||
482 | /** | |
483 | * Throw a NO_MODIFICATION_ALLOWED_ERR DOMException. | |
484 | * | |
485 | * @throws DOMException always thrown | |
486 | */ | |
487 | private void disallowModification () throws DOMException | |
488 | { | |
489 | 2 | throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, |
490 | "Namespace node may not be modified"); | |
491 | } | |
492 | ||
493 | ||
494 | ||
495 | //////////////////////////////////////////////////////////////////// | |
496 | // Override default methods from java.lang.Object. | |
497 | //////////////////////////////////////////////////////////////////// | |
498 | ||
499 | ||
500 | /** | |
501 | * Generate a hash code for a namespace node. | |
502 | * | |
503 | * @return a hash code for this node | |
504 | */ | |
505 | public int hashCode () | |
506 | { | |
507 | 16 | return hashCode(parent) + hashCode(name) + hashCode(value); |
508 | } | |
509 | ||
510 | ||
511 | /** | |
512 | * Test for equivalence with another object. | |
513 | * | |
514 | * <p>Two Namespace nodes are considered equivalent if their parents, | |
515 | * names, and values are equal.</p> | |
516 | * | |
517 | * @param o the object to test for equality | |
518 | * @return true if the object is equivalent to this node, false | |
519 | * otherwise | |
520 | */ | |
521 | public boolean equals (Object o) | |
522 | { | |
523 | 0 | if (o == this) return true; |
524 | 0 | else if (o == null) return false; |
525 | 0 | else if (o instanceof NamespaceNode) { |
526 | 0 | NamespaceNode ns = (NamespaceNode)o; |
527 | 0 | return (equals(parent, ns.getParentNode()) && |
528 | equals(name, ns.getNodeName()) && | |
529 | equals(value, ns.getNodeValue())); | |
530 | } else { | |
531 | 0 | return false; |
532 | } | |
533 | } | |
534 | ||
535 | ||
536 | /** | |
537 | * Helper method for generating a hash code. | |
538 | * | |
539 | * @param o the object for generating a hash code (possibly null) | |
540 | * @return the object's hash code, or 0 if the object is null | |
541 | * @see java.lang.Object#hashCode | |
542 | */ | |
543 | private int hashCode (Object o) | |
544 | { | |
545 | 48 | return (o == null ? 0 : o.hashCode()); |
546 | } | |
547 | ||
548 | ||
549 | /** | |
550 | * Helper method for comparing two objects. | |
551 | * | |
552 | * @param a the first object to compare (possibly null) | |
553 | * @param b the second object to compare (possibly null) | |
554 | * @return true if the objects are equivalent or are both null | |
555 | * @see java.lang.Object#equals | |
556 | */ | |
557 | private boolean equals (Object a, Object b) | |
558 | { | |
559 | 0 | return ((a == null && b == null) || |
560 | (a != null && a.equals(b))); | |
561 | } | |
562 | ||
563 | ||
564 | //////////////////////////////////////////////////////////////////// | |
565 | // Internal state. | |
566 | //////////////////////////////////////////////////////////////////// | |
567 | ||
568 | private Node parent; | |
569 | private String name; | |
570 | private String value; | |
571 | ||
572 | ||
573 | ||
574 | //////////////////////////////////////////////////////////////////// | |
575 | // Inner class: empty node list. | |
576 | //////////////////////////////////////////////////////////////////// | |
577 | ||
578 | ||
579 | /** | |
580 | * A node list with no members. | |
581 | * | |
582 | * <p>This class is necessary for the {@link Node#getChildNodes} | |
583 | * method, which must return an empty node list rather than | |
584 | * null when there are no children.</p> | |
585 | */ | |
586 | 0 | private static class EmptyNodeList implements NodeList |
587 | { | |
588 | ||
589 | /** | |
590 | * @see NodeList#getLength | |
591 | */ | |
592 | public int getLength () | |
593 | { | |
594 | 0 | return 0; |
595 | } | |
596 | ||
597 | ||
598 | /** | |
599 | * @see NodeList#item | |
600 | */ | |
601 | public Node item(int index) | |
602 | { | |
603 | 0 | return null; |
604 | } | |
605 | ||
606 | } | |
607 | ||
608 | //////////////////////////////////////////////////////////////////// | |
609 | // DOM Level 3 methods | |
610 | //////////////////////////////////////////////////////////////////// | |
611 | ||
612 | /** | |
613 | * Return the base URI of the document containing this node. | |
614 | * This only works in DOM 3. | |
615 | * | |
616 | * @return null | |
617 | */ | |
618 | public String getBaseURI() { | |
619 | 2 | Class clazz = Node.class; |
620 | try { | |
621 | 0 | Class[] args = new Class[0]; |
622 | 0 | Method getBaseURI = clazz.getMethod("getBaseURI", args); |
623 | 0 | String base = (String) getBaseURI.invoke(this.getParentNode(), args); |
624 | 0 | return base; |
625 | } | |
626 | 0 | catch (Exception ex) { |
627 | 0 | return null; |
628 | } | |
629 | } | |
630 | ||
631 | ||
632 | /** | |
633 | * Compare relative position of this node to another nbode. (Always fails). | |
634 | * This method is included solely for compatibility with the superclass. | |
635 | * | |
636 | * @param other the node to compare to | |
637 | * | |
638 | * @return never | |
639 | * @throws DOMException NOT_SUPPORTED_ERR | |
640 | */ | |
641 | public short compareDocumentPosition(Node other) throws DOMException { | |
642 | 0 | DOMException ex = new DOMException( |
643 | DOMException.NOT_SUPPORTED_ERR, | |
644 | "DOM level 3 interfaces are not fully implemented in Jaxen's NamespaceNode class" | |
645 | ); | |
646 | 0 | throw ex; |
647 | } | |
648 | ||
649 | ||
650 | /** | |
651 | * Return the namespace URI. | |
652 | * | |
653 | * @return the namespace URI | |
654 | * @see #getNodeValue | |
655 | */ | |
656 | public String getTextContent() { | |
657 | 2 | return value; |
658 | } | |
659 | ||
660 | ||
661 | /** | |
662 | * Change the value of this node (always fails). | |
663 | * This method is included solely for compatibility with the superclass. | |
664 | * | |
665 | * @param textContent the new content | |
666 | * @throws DOMException always | |
667 | */ | |
668 | public void setTextContent(String textContent) throws DOMException { | |
669 | 2 | disallowModification(); |
670 | 0 | } |
671 | ||
672 | ||
673 | /** | |
674 | * Returns true if and only if this object represents the same XPath namespace node | |
675 | * as the argument; that is, they have the same parent, the same prefix, and the | |
676 | * same URI. | |
677 | * | |
678 | * @param other the node to compare to | |
679 | * @return true if this object represents the same XPath namespace node | |
680 | * as other; false otherwise | |
681 | */ | |
682 | public boolean isSameNode(Node other) { | |
683 | 4 | boolean a = this.isEqualNode(other); |
684 | // a bit flaky (should really be | |
685 | // this.getParentNode().isEqual(other.getParentNode()) | |
686 | // but we want this to compile in Java 1.4 without problems | |
687 | // Note that this will mess up code coverage since you can't cover both | |
688 | // branches in the same VM | |
689 | boolean b; | |
690 | 4 | Node thisParent = this.getParentNode(); |
691 | 4 | Node thatParent = other.getParentNode(); |
692 | try { | |
693 | 4 | Class clazz = Node.class; |
694 | 4 | Class[] args = {clazz}; |
695 | 4 | Method isEqual = clazz.getMethod("isEqual", args); |
696 | 0 | Object[] args2 = new Object[1]; |
697 | 0 | args2[0] = thatParent; |
698 | 0 | Boolean result = (Boolean) isEqual.invoke(thisParent, args2); |
699 | 0 | b = result.booleanValue(); |
700 | } | |
701 | 4 | catch (NoSuchMethodException ex) { |
702 | 4 | b = thisParent.equals(thatParent); |
703 | } | |
704 | 0 | catch (InvocationTargetException ex) { |
705 | 0 | b = thisParent.equals(thatParent); |
706 | } | |
707 | 0 | catch (IllegalAccessException ex) { |
708 | 0 | b = thisParent.equals(thatParent); |
709 | 4 | } |
710 | ||
711 | 4 | return a && b; |
712 | ||
713 | } | |
714 | ||
715 | ||
716 | /** | |
717 | * Return the prefix bound to this namespace URI within the scope | |
718 | * of this node. | |
719 | * | |
720 | * @param namespaceURI the URI to find a prefix binding for | |
721 | * | |
722 | * @return a prefix matching this namespace URI | |
723 | * @throws UnsupportedOperationException in DOM 2 | |
724 | */ | |
725 | public String lookupPrefix(String namespaceURI) { | |
726 | // This could be fully implemented even in Java 1.4. See | |
727 | // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo | |
728 | // It hardly seems worth the effort though. | |
729 | ||
730 | try { | |
731 | 0 | Class clazz = Node.class; |
732 | 0 | Class[] argTypes = {String.class}; |
733 | 0 | Method lookupPrefix = clazz.getMethod("lookupPrefix", argTypes); |
734 | 0 | String[] args = {namespaceURI}; |
735 | 0 | String result = (String) lookupPrefix.invoke(parent, args); |
736 | 0 | return result; |
737 | } | |
738 | 0 | catch (NoSuchMethodException ex) { |
739 | 0 | throw new UnsupportedOperationException("Cannot lookup prefixes in DOM 2"); |
740 | } | |
741 | 0 | catch (InvocationTargetException ex) { |
742 | 0 | throw new UnsupportedOperationException("Cannot lookup prefixes in DOM 2"); |
743 | } | |
744 | 0 | catch (IllegalAccessException ex) { |
745 | 0 | throw new UnsupportedOperationException("Cannot lookup prefixes in DOM 2"); |
746 | } | |
747 | ||
748 | } | |
749 | ||
750 | ||
751 | /** | |
752 | * Return true if the specified URI is the default namespace in | |
753 | * scope (always fails). This method is included solely for | |
754 | * compatibility with the superclass. | |
755 | * | |
756 | * @param namespaceURI the URI to check | |
757 | * | |
758 | * @return never | |
759 | * @throws UnsupportedOperationException always | |
760 | */ | |
761 | public boolean isDefaultNamespace(String namespaceURI) { | |
762 | 0 | return namespaceURI.equals(this.lookupNamespaceURI(null)); |
763 | } | |
764 | ||
765 | ||
766 | /** | |
767 | * Return the namespace URI mapped to the specified | |
768 | * prefix within the scope of this namespace node. | |
769 | * | |
770 | * @param prefix the prefix to search for | |
771 | * | |
772 | * @return the namespace URI mapped to this prefix | |
773 | * @throws UnsupportedOperationException in DOM 2 | |
774 | */ | |
775 | public String lookupNamespaceURI(String prefix) { | |
776 | // This could be fully implemented even in Java 1.4. See | |
777 | // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo | |
778 | // It hardly seems worth the effort though. | |
779 | ||
780 | try { | |
781 | 0 | Class clazz = Node.class; |
782 | 0 | Class[] argTypes = {String.class}; |
783 | 0 | Method lookupNamespaceURI = clazz.getMethod("lookupNamespaceURI", argTypes); |
784 | 0 | String[] args = {prefix}; |
785 | 0 | String result = (String) lookupNamespaceURI.invoke(parent, args); |
786 | 0 | return result; |
787 | } | |
788 | 0 | catch (NoSuchMethodException ex) { |
789 | 0 | throw new UnsupportedOperationException("Cannot lookup namespace URIs in DOM 2"); |
790 | } | |
791 | 0 | catch (InvocationTargetException ex) { |
792 | 0 | throw new UnsupportedOperationException("Cannot lookup namespace URIs in DOM 2"); |
793 | } | |
794 | 0 | catch (IllegalAccessException ex) { |
795 | 0 | throw new UnsupportedOperationException("Cannot lookup namespace URIs in DOM 2"); |
796 | } | |
797 | } | |
798 | ||
799 | ||
800 | /** | |
801 | * Returns true if this object binds the same prefix to the same URI. | |
802 | * That is, this object has the same prefix and URI as the argument. | |
803 | * | |
804 | * @param arg the node to compare to | |
805 | * @return true if this object has the same prefix and URI as the argument; false otherwise | |
806 | */ | |
807 | public boolean isEqualNode(Node arg) { | |
808 | 8 | if (arg.getNodeType() == this.getNodeType()) { |
809 | 8 | NamespaceNode other = (NamespaceNode) arg; |
810 | 8 | if (other.name == null && this.name != null) return false; |
811 | 8 | else if (other.name != null && this.name == null) return false; |
812 | 4 | else if (other.value == null && this.value != null) return false; |
813 | 4 | else if (other.value != null && this.value == null) return false; |
814 | 4 | else if (other.name == null && this.name == null) { |
815 | 4 | return other.value.equals(this.value); |
816 | } | |
817 | ||
818 | 0 | return other.name.equals(this.name) && other.value.equals(this.value); |
819 | } | |
820 | 0 | return false; |
821 | } | |
822 | ||
823 | ||
824 | /** | |
825 | * Returns the value of the requested feature. Always returns null. | |
826 | * | |
827 | * @return null | |
828 | */ | |
829 | public Object getFeature(String feature, String version) { | |
830 | 2 | return null; |
831 | } | |
832 | ||
833 | ||
834 | // XXX userdata needs testing | |
835 | 486 | private HashMap userData = new HashMap(); |
836 | ||
837 | /** | |
838 | * Associates an object with a key. | |
839 | * | |
840 | * @param key the key by which the data will be retrieved | |
841 | * @param data the object to store with the key | |
842 | * @param handler ignored since namespace nodes cannot be imported, cloned, or renamed | |
843 | * | |
844 | * @return the value previously associated with this key; or null | |
845 | * if there isn't any such previous value | |
846 | */ | |
847 | public Object setUserData(String key, Object data, UserDataHandler handler) { | |
848 | 0 | Object oldValue = getUserData(key); |
849 | 0 | userData.put(key, data); |
850 | 0 | return oldValue; |
851 | } | |
852 | ||
853 | ||
854 | /** | |
855 | * Returns the user data associated with the given key. | |
856 | * | |
857 | * @param key the lookup key | |
858 | * | |
859 | * @return the object associated with the key; or null if no such object is available | |
860 | */ | |
861 | public Object getUserData(String key) { | |
862 | 0 | return userData.get(key); |
863 | } | |
864 | ||
865 | } | |
866 | ||
867 | // end of NamespaceNode.java |