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