Coverage Report - org.jaxen.dom.NamespaceNode

Classes in this Package Line Coverage Branch Coverage Complexity
NamespaceNode
33% 
25% 
1.235

 1  
 /*
 2  
  * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom/NamespaceNode.java,v 1.11 2005/05/10 12:01:14 elharo Exp $
 3  
  * $Revision: 1.11 $
 4  
  * $Date: 2005/05/10 12:01:14 $
 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.11 2005/05/10 12:01:14 elharo Exp $
 60  
  */
 61  
 
 62  
 ////////////////////////////////////////////////////////////////////
 63  
 // Inner class for a Namespace node.
 64  
 ////////////////////////////////////////////////////////////////////
 65  
 
 66  
 package org.jaxen.dom;
 67  
 
 68  
 import org.jaxen.pattern.Pattern;
 69  
 import org.w3c.dom.DOMException;
 70  
 import org.w3c.dom.Document;
 71  
 import org.w3c.dom.NamedNodeMap;
 72  
 import org.w3c.dom.Node;
 73  
 import org.w3c.dom.NodeList;
 74  
 
 75  
 
 76  
 /**
 77  
  * Extension DOM2 node type for a namespace node.
 78  
  *
 79  
  * <p>This class implements the DOM2 {@link Node} interface to
 80  
  * allow namespace nodes to be included in the result
 81  
  * set of an XPath selectNodes operation, even though DOM2 does
 82  
  * not model namespaces in scope as separate nodes.</p>
 83  
  *
 84  
  * <p>While all of the methods are implemented with reasonable
 85  
  * defaults, there will be some unexpected surprises, so users are
 86  
  * advised to test for NamespaceNodes and filter them out from the
 87  
  * result sets as early as possible:</p>
 88  
  *
 89  
  * <ol>
 90  
  *
 91  
  * <li>The {@link #getNodeType} method returns {@link #NAMESPACE_NODE},
 92  
  * which is not one of the usual DOM2 node types.  Generic code may
 93  
  * fall unexpectedly out of switch statements, for example.</li>
 94  
  *
 95  
  * <li>The {@link #getOwnerDocument} method returns the owner document
 96  
  * of the parent node, but that owner document will know nothing about
 97  
  * the namespace node.</p>
 98  
  *
 99  
  * <li>The {@link #isSupported} method always returns false.</li>
 100  
  *
 101  
  * </ol>
 102  
  *
 103  
  * <p>All attempts to modify a <code>NamespaceNode</code> will fail with a {@link
 104  
  * DOMException} ({@link
 105  
  * DOMException#NO_MODIFICATION_ALLOWED_ERR}).</p>
 106  
  *
 107  
  * @author David Megginson
 108  
  * @see DocumentNavigator
 109  
  */
 110  
 public class NamespaceNode implements Node
 111  
 {
 112  
 
 113  
 
 114  
     ////////////////////////////////////////////////////////////////////
 115  
     // Constants.
 116  
     ////////////////////////////////////////////////////////////////////
 117  
 
 118  
     /**
 119  
      * Constant: this is a NamespaceNode.
 120  
      *
 121  
      * @see #getNodeType
 122  
      */
 123  
     public final static short NAMESPACE_NODE = Pattern.NAMESPACE_NODE;
 124  
 
 125  
 
 126  
 
 127  
     ////////////////////////////////////////////////////////////////////
 128  
     // Protected Constructors.
 129  
     ////////////////////////////////////////////////////////////////////
 130  
 
 131  
 
 132  
     /**
 133  
      * Constructor.
 134  
      *
 135  
      * @param parent the DOM node to which the namespace is attached
 136  
      * @param name the namespace prefix
 137  
      * @param value the namespace URI
 138  
      */
 139  
     public NamespaceNode (Node parent, String name, String value)
 140  55
     {
 141  55
         this.parent = parent;
 142  55
         this.name = name;
 143  55
         this.value = value;
 144  55
     }
 145  
 
 146  
 
 147  
     /**
 148  
      * Constructor.
 149  
      *
 150  
      * @param parent the DOM node to which the namespace is attached
 151  
      * @param attribute the DOM attribute object containing the
 152  
      *        namespace declaration
 153  
      */
 154  
     NamespaceNode (Node parent, Node attribute)
 155  78
     {
 156  78
         String name = attribute.getNodeName();
 157  
     
 158  78
         if (name.equals("xmlns")) {
 159  0
             this.name = "";
 160  
         }
 161  
         else {
 162  78
             this.name = name.substring(6); // the part after "xmlns:"
 163  
         }
 164  78
         this.parent = parent;
 165  78
         this.value = attribute.getNodeValue();
 166  78
     }
 167  
 
 168  
 
 169  
 
 170  
     ////////////////////////////////////////////////////////////////////
 171  
     // Implementation of org.w3c.dom.Node.
 172  
     ////////////////////////////////////////////////////////////////////
 173  
 
 174  
 
 175  
     /**
 176  
      * Get the namespace prefix.
 177  
      *
 178  
      * @return the namespace prefix, or "" for the default namespace
 179  
      */
 180  
     public String getNodeName ()
 181  
     {
 182  82
         return name;
 183  
     }
 184  
 
 185  
 
 186  
     /**
 187  
      * Get the namespace URI.
 188  
      *
 189  
      * @return the namespace URI
 190  
      */
 191  
     public String getNodeValue ()
 192  
     {
 193  8
         return value;
 194  
     }
 195  
 
 196  
 
 197  
     /**
 198  
      * Change the namespace URI (always fails).
 199  
      *
 200  
      * @param value the new URI
 201  
      * @throws DOMException always
 202  
      */
 203  
     public void setNodeValue (String value) throws DOMException
 204  
     {
 205  0
         disallowModification();
 206  0
     }
 207  
 
 208  
 
 209  
     /**
 210  
      * Get the node type.
 211  
      *
 212  
      * @return always {@link #NAMESPACE_NODE}.
 213  
      */
 214  
     public short getNodeType ()
 215  
     {
 216  1300
         return NAMESPACE_NODE;
 217  
     }
 218  
 
 219  
 
 220  
     /**
 221  
      * Get the parent node.
 222  
      *
 223  
      * <p>This method returns the element that was queried for Namespaces
 224  
      * in effect, <em>not</em> necessarily the actual element containing
 225  
      * the Namespace declaration.</p>
 226  
      *
 227  
      * @return the parent node (not null)
 228  
      */
 229  
     public Node getParentNode ()
 230  
     {
 231  347
         return parent;
 232  
     }
 233  
 
 234  
 
 235  
     /**
 236  
      * Get the list of child nodes.
 237  
      *
 238  
      * @return an empty node list
 239  
      */
 240  
     public NodeList getChildNodes ()
 241  
     {
 242  0
         return new EmptyNodeList();
 243  
     }
 244  
 
 245  
 
 246  
     /**
 247  
      * Get the first child node.
 248  
      *
 249  
      * @return null
 250  
      */
 251  
     public Node getFirstChild ()
 252  
     {
 253  0
         return null;
 254  
     }
 255  
 
 256  
 
 257  
     /**
 258  
      * Get the last child node.
 259  
      *
 260  
      * @return null
 261  
      */
 262  
     public Node getLastChild ()
 263  
     {
 264  0
         return null;
 265  
     }
 266  
 
 267  
 
 268  
     /**
 269  
      * Get the previous sibling node.
 270  
      *
 271  
      * @return null
 272  
      */
 273  
     public Node getPreviousSibling ()
 274  
     {
 275  0
         return null;
 276  
     }
 277  
 
 278  
 
 279  
     /**
 280  
      * Get the next sibling node.
 281  
      *
 282  
      * @return null
 283  
      */
 284  
     public Node getNextSibling ()
 285  
     {
 286  0
         return null;
 287  
     }
 288  
 
 289  
 
 290  
     /**
 291  
      * Get the attribute nodes.
 292  
      *
 293  
      * @return null
 294  
      */
 295  
     public NamedNodeMap getAttributes ()
 296  
     {
 297  0
         return null;
 298  
     }
 299  
 
 300  
 
 301  
     /**
 302  
      * Get the owner document.
 303  
      *
 304  
      * @return the owner document <em>of the parent node</em>
 305  
      */
 306  
     public Document getOwnerDocument ()
 307  
     {
 308  
                     // FIXME: this could cause confusion
 309  0
         return (parent == null ? null : parent.getOwnerDocument());
 310  
     }
 311  
 
 312  
 
 313  
     /**
 314  
      * Insert a new child node (always fails).
 315  
      * 
 316  
      * @param newChild the node to add
 317  
      * @param oldChild ignored
 318  
      * @return never
 319  
      * @throws DOMException always
 320  
      * @see Node#insertBefore
 321  
      */
 322  
     public Node insertBefore (Node newChild, Node refChild)
 323  
     throws DOMException
 324  
     {
 325  0
         disallowModification();
 326  0
         return null;
 327  
     }
 328  
 
 329  
 
 330  
     /**
 331  
      * Replace a child node (always fails).
 332  
      *
 333  
      * @param newChild the node to add
 334  
      * @param oldChild the child node to replace
 335  
      * @return never
 336  
      * @throws DOMException always
 337  
      * @see Node#replaceChild
 338  
      */
 339  
     public Node replaceChild (Node newChild, Node oldChild)
 340  
     throws DOMException
 341  
     {
 342  0
         disallowModification();
 343  0
         return null;
 344  
     }
 345  
 
 346  
 
 347  
     /**
 348  
      * Remove a child node (always fails).
 349  
      *
 350  
      * @param oldChild the child node to remove
 351  
      * @return never
 352  
      * @throws DOMException always
 353  
      * @see Node#removeChild
 354  
      */
 355  
     public Node removeChild (Node oldChild)
 356  
     throws DOMException
 357  
     {
 358  0
         disallowModification();
 359  0
         return null;
 360  
     }
 361  
 
 362  
 
 363  
     /**
 364  
      * Append a new child node (always fails).
 365  
      *
 366  
      * @param newChild the node to add
 367  
      * @return never
 368  
      * @throws DOMException always
 369  
      * @see Node#appendChild
 370  
      */
 371  
     public Node appendChild (Node newChild)
 372  
     throws DOMException
 373  
     {
 374  0
         disallowModification();
 375  0
         return null;
 376  
     }
 377  
 
 378  
 
 379  
     /**
 380  
      * Test for child nodes.
 381  
      *
 382  
      * @return false
 383  
      */
 384  
     public boolean hasChildNodes ()
 385  
     {
 386  0
         return false;
 387  
     }
 388  
 
 389  
 
 390  
     /**
 391  
      * Create a copy of this node.
 392  
      *
 393  
      * @param deep make a deep copy (no effect, since namespace nodes
 394  
      *        don't have children).
 395  
      * @return a new copy of this namespace node
 396  
      */
 397  
     public Node cloneNode (boolean deep)
 398  
     {
 399  0
         return new NamespaceNode(parent, name, value);
 400  
     }
 401  
 
 402  
 
 403  
     /**
 404  
      * Normalize the text descendants of this node.
 405  
      *
 406  
      * <p>This method has no effect, since Namespace nodes have no
 407  
      * descendants.</p>
 408  
      */
 409  
     public void normalize ()
 410  
     {
 411  
     // no op
 412  0
     }
 413  
 
 414  
 
 415  
     /**
 416  
      * Test if a DOM2 feature is supported.
 417  
      *
 418  
      * @param feature the feature name
 419  
      * @param version the feature version
 420  
      * @return false
 421  
      */
 422  
     public boolean isSupported (String feature, String version)
 423  
     {
 424  0
         return false;
 425  
     }
 426  
 
 427  
 
 428  
     /**
 429  
      * Get the namespace URI of this node.
 430  
      *
 431  
      * <p>Namespace declarations are not themselves
 432  
      * Namespace-qualified.</p>
 433  
      *
 434  
      * @return null
 435  
      */
 436  
     public String getNamespaceURI ()
 437  
     {
 438  0
        return null;
 439  
     }
 440  
 
 441  
 
 442  
     /**
 443  
      * Get the namespace prefix of this node.
 444  
      *
 445  
      * <p>Namespace declarations are not themselves
 446  
      * namespace-qualified.</p>
 447  
      *
 448  
      * @return null
 449  
      * @see #getLocalName
 450  
      */
 451  
     public String getPrefix ()
 452  
     {
 453  0
         return null;
 454  
     }
 455  
 
 456  
 
 457  
     /**
 458  
      * Change the namespace prefix of this node (always fails).
 459  
      *
 460  
      * @param prefix the new prefix
 461  
      * @throws DOMException always thrown
 462  
      */
 463  
     public void setPrefix (String prefix)
 464  
     throws DOMException
 465  
     {
 466  0
         disallowModification();
 467  0
     }
 468  
 
 469  
 
 470  
     /**
 471  
      * Get the XPath name of the namespace node;; i.e. the
 472  
      * namespace prefix.
 473  
      *
 474  
      * @return the namespace prefix
 475  
      */
 476  
     public String getLocalName ()
 477  
     {
 478  119
         return name;
 479  
     }
 480  
 
 481  
 
 482  
     /**
 483  
      * Test if this node has attributes.
 484  
      *
 485  
      * @return false
 486  
      */
 487  
     public boolean hasAttributes ()
 488  
     {
 489  0
         return false;
 490  
     }
 491  
 
 492  
 
 493  
     /**
 494  
      * Throw a NO_MODIFICATION_ALLOWED_ERR DOMException.
 495  
      *
 496  
      * @throws DOMException always thrown
 497  
      */
 498  
     private void disallowModification () throws DOMException
 499  
     {
 500  0
         throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
 501  
                    "Namespace node may not be modified");
 502  
     }
 503  
 
 504  
 
 505  
 
 506  
     ////////////////////////////////////////////////////////////////////
 507  
     // Override default methods from java.lang.Object.
 508  
     ////////////////////////////////////////////////////////////////////
 509  
 
 510  
 
 511  
     /**
 512  
      * Generate a hash code for a namespace node.
 513  
      *
 514  
      * @return a hash code for this node
 515  
      */
 516  
     public int hashCode ()
 517  
     {
 518  4
     return hashCode(parent) + hashCode(name) + hashCode(value);
 519  
     }
 520  
 
 521  
 
 522  
     /**
 523  
      * Test for equivalence with another object.
 524  
      *
 525  
      * <p>Two Namespace nodes are considered equivalent if their parents,
 526  
      * names, and values are equal.</p>
 527  
      *
 528  
      * @param o the object to test for equality
 529  
      * @return true if the object is equivalent to this node, false
 530  
      *         otherwise
 531  
      */
 532  
     public boolean equals (Object o)
 533  
     {
 534  0
         if (o == this) return true;
 535  0
         else if (o == null) return false;
 536  0
         else if (o instanceof NamespaceNode) {
 537  0
             NamespaceNode ns = (NamespaceNode)o;
 538  0
             return (equals(parent, ns.getParentNode()) &&
 539  
                 equals(name, ns.getNodeName()) &&
 540  
                 equals(value, ns.getNodeValue()));
 541  
         } else {
 542  0
             return false;
 543  
         }
 544  
     }
 545  
 
 546  
 
 547  
     /**
 548  
      * Helper method for generating a hash code.
 549  
      *
 550  
      * @param o the object for generating a hash code (possibly null)
 551  
      * @return the object's hash code, or 0 if the object is null
 552  
      * @see java.lang.Object#hashCode
 553  
      */
 554  
     private int hashCode (Object o)
 555  
     {
 556  12
     return (o == null ? 0 : o.hashCode());
 557  
     }
 558  
 
 559  
 
 560  
     /**
 561  
      * Helper method for comparing two objects.
 562  
      *
 563  
      * @param a the first object to compare (possibly null)
 564  
      * @param b the second object to compare (possibly null)
 565  
      * @return true if the objects are equivalent or are both null
 566  
      * @see java.lang.Object#equals
 567  
      */
 568  
     private boolean equals (Object a, Object b)
 569  
     {
 570  0
         return ((a == null && b == null) ||
 571  
           (a != null && a.equals(b)));
 572  
     }
 573  
 
 574  
 
 575  
     ////////////////////////////////////////////////////////////////////
 576  
     // Internal state.
 577  
     ////////////////////////////////////////////////////////////////////
 578  
 
 579  
     private Node parent;
 580  
     private String name;
 581  
     private String value;
 582  
 
 583  
 
 584  
 
 585  
     ////////////////////////////////////////////////////////////////////
 586  
     // Inner class: empty node list.
 587  
     ////////////////////////////////////////////////////////////////////
 588  
 
 589  
 
 590  
     /**
 591  
      * A node list with no members.
 592  
      *
 593  
      * <p>This class is necessary for the {@link Node#getChildNodes}
 594  
      * method, which must return an empty node list rather than
 595  
      * null when there are no children.</p>
 596  
      */
 597  0
     private static class EmptyNodeList implements NodeList
 598  
     {
 599  
 
 600  
     /**
 601  
      * @see NodeList#getLength
 602  
      */
 603  
     public int getLength ()
 604  
     {
 605  0
         return 0;
 606  
     }
 607  
 
 608  
 
 609  
     /**
 610  
      * @see NodeList#item
 611  
      */
 612  
     public Node item(int index)
 613  
     {
 614  0
         return null;
 615  
     }
 616  
     
 617  
     }
 618  
 }
 619  
 
 620  
 // end of Namespace.java