Home | History | Annotate | Download | only in dom2dtm
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 /*
     19  * $Id: DOM2DTMdefaultNamespaceDeclarationNode.java 468653 2006-10-28 07:07:05Z minchau $
     20  */
     21 
     22 package org.apache.xml.dtm.ref.dom2dtm;
     23 
     24 import org.apache.xml.dtm.DTMException;
     25 
     26 import org.w3c.dom.Attr;
     27 import org.w3c.dom.Document;
     28 import org.w3c.dom.Element;
     29 import org.w3c.dom.NamedNodeMap;
     30 import org.w3c.dom.Node;
     31 import org.w3c.dom.NodeList;
     32 import org.w3c.dom.TypeInfo;
     33 import org.w3c.dom.UserDataHandler;
     34 import org.w3c.dom.DOMException;
     35 
     36 /** This is a kluge to let us shove a declaration for xml: into the
     37  * DOM2DTM model.  Basically, it creates a proxy node in DOM space to
     38  * carry the additional information. This is _NOT_ a full DOM
     39  * implementation, and shouldn't be one since it sits alongside the
     40  * DOM rather than becoming part of the DOM model.
     41  *
     42  * (This used to be an internal class within DOM2DTM. Moved out because
     43  * I need to perform an instanceof operation on it to support a temporary
     44  * workaround in DTMManagerDefault.)
     45  *
     46  * %REVIEW% What if the DOM2DTM was built around a DocumentFragment and
     47  * there isn't a single root element? I think this fails that case...
     48  *
     49  * %REVIEW% An alternative solution would be to create the node _only_
     50  * in DTM space, but given how DOM2DTM is currently written I think
     51  * this is simplest.
     52  * */
     53 public class DOM2DTMdefaultNamespaceDeclarationNode implements Attr,TypeInfo
     54 {
     55   final String NOT_SUPPORTED_ERR="Unsupported operation on pseudonode";
     56 
     57   Element pseudoparent;
     58   String prefix,uri,nodename;
     59   int handle;
     60   DOM2DTMdefaultNamespaceDeclarationNode(Element pseudoparent,String prefix,String uri,int handle)
     61   {
     62     this.pseudoparent=pseudoparent;
     63     this.prefix=prefix;
     64     this.uri=uri;
     65     this.handle=handle;
     66     this.nodename="xmlns:"+prefix;
     67   }
     68   public String getNodeName() {return nodename;}
     69   public String getName() {return nodename;}
     70   public String getNamespaceURI() {return "http://www.w3.org/2000/xmlns/";}
     71   public String getPrefix() {return prefix;}
     72   public String getLocalName() {return prefix;}
     73   public String getNodeValue() {return uri;}
     74   public String getValue() {return uri;}
     75   public Element getOwnerElement() {return pseudoparent;}
     76 
     77   public boolean isSupported(String feature, String version) {return false;}
     78   public boolean hasChildNodes() {return false;}
     79   public boolean hasAttributes() {return false;}
     80   public Node getParentNode() {return null;}
     81   public Node getFirstChild() {return null;}
     82   public Node getLastChild() {return null;}
     83   public Node getPreviousSibling() {return null;}
     84   public Node getNextSibling() {return null;}
     85   public boolean getSpecified() {return false;}
     86   public void normalize() {return;}
     87   public NodeList getChildNodes() {return null;}
     88   public NamedNodeMap getAttributes() {return null;}
     89   public short getNodeType() {return Node.ATTRIBUTE_NODE;}
     90   public void setNodeValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);}
     91   public void setValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);}
     92   public void setPrefix(String value) {throw new DTMException(NOT_SUPPORTED_ERR);}
     93   public Node insertBefore(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);}
     94   public Node replaceChild(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);}
     95   public Node appendChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);}
     96   public Node removeChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);}
     97   public Document getOwnerDocument() {return pseudoparent.getOwnerDocument();}
     98   public Node cloneNode(boolean deep) {throw new DTMException(NOT_SUPPORTED_ERR);}
     99 
    100     /** Non-DOM method, part of the temporary kluge
    101      * %REVIEW% This would be a pruning problem, but since it will always be
    102      * added to the root element and we prune on elements, we shouldn't have
    103      * to worry.
    104      */
    105     public int getHandleOfNode()
    106     {
    107         return handle;
    108     }
    109 
    110     //RAMESH: PENDING=> Add proper implementation for the below DOM L3 additions
    111 
    112     /**
    113      * @see org.w3c.dom.TypeInfo#getTypeName()
    114      */
    115     public String getTypeName() {return null; }
    116 
    117     /**
    118      * @see org.w3c.dom.TypeInfo#getTypeNamespace()
    119      */
    120     public String getTypeNamespace() { return null;}
    121 
    122     /**
    123      * @see or.gw3c.dom.TypeInfo#isDerivedFrom(String,String,int)
    124      */
    125     public boolean isDerivedFrom( String ns, String localName, int derivationMethod ) {
    126         return false;
    127     }
    128 
    129     public TypeInfo getSchemaTypeInfo() { return this; }
    130 
    131     public boolean isId( ) { return false; }
    132 
    133     /**
    134      * Associate an object to a key on this node. The object can later be
    135      * retrieved from this node by calling <code>getUserData</code> with the
    136      * same key.
    137      * @param key The key to associate the object to.
    138      * @param data The object to associate to the given key, or
    139      *   <code>null</code> to remove any existing association to that key.
    140      * @param handler The handler to associate to that key, or
    141      *   <code>null</code>.
    142      * @return Returns the <code>DOMObject</code> previously associated to
    143      *   the given key on this node, or <code>null</code> if there was none.
    144      * @since DOM Level 3
    145      */
    146     public Object setUserData(String key,
    147                               Object data,
    148                               UserDataHandler handler) {
    149         return getOwnerDocument().setUserData( key, data, handler);
    150     }
    151 
    152     /**
    153      * Retrieves the object associated to a key on a this node. The object
    154      * must first have been set to this node by calling
    155      * <code>setUserData</code> with the same key.
    156      * @param key The key the object is associated to.
    157      * @return Returns the <code>DOMObject</code> associated to the given key
    158      *   on this node, or <code>null</code> if there was none.
    159      * @since DOM Level 3
    160      */
    161     public Object getUserData(String key) {
    162         return getOwnerDocument().getUserData( key);
    163     }
    164 
    165     /**
    166      *  This method returns a specialized object which implements the
    167      * specialized APIs of the specified feature and version. The
    168      * specialized object may also be obtained by using binding-specific
    169      * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations.
    170      * @param feature The name of the feature requested (case-insensitive).
    171      * @param version  This is the version number of the feature to test. If
    172      *   the version is <code>null</code> or the empty string, supporting
    173      *   any version of the feature will cause the method to return an
    174      *   object that supports at least one version of the feature.
    175      * @return  Returns an object which implements the specialized APIs of
    176      *   the specified feature and version, if any, or <code>null</code> if
    177      *   there is no object which implements interfaces associated with that
    178      *   feature. If the <code>DOMObject</code> returned by this method
    179      *   implements the <code>Node</code> interface, it must delegate to the
    180      *   primary core <code>Node</code> and not return results inconsistent
    181      *   with the primary core <code>Node</code> such as attributes,
    182      *   childNodes, etc.
    183      * @since DOM Level 3
    184      */
    185     public Object getFeature(String feature, String version) {
    186         // we don't have any alternate node, either this node does the job
    187         // or we don't have anything that does
    188         return isSupported(feature, version) ? this : null;
    189     }
    190 
    191     /**
    192      * Tests whether two nodes are equal.
    193      * <br>This method tests for equality of nodes, not sameness (i.e.,
    194      * whether the two nodes are references to the same object) which can be
    195      * tested with <code>Node.isSameNode</code>. All nodes that are the same
    196      * will also be equal, though the reverse may not be true.
    197      * <br>Two nodes are equal if and only if the following conditions are
    198      * satisfied: The two nodes are of the same type.The following string
    199      * attributes are equal: <code>nodeName</code>, <code>localName</code>,
    200      * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
    201      * , <code>baseURI</code>. This is: they are both <code>null</code>, or
    202      * they have the same length and are character for character identical.
    203      * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
    204      * This is: they are both <code>null</code>, or they have the same
    205      * length and for each node that exists in one map there is a node that
    206      * exists in the other map and is equal, although not necessarily at the
    207      * same index.The <code>childNodes</code> <code>NodeLists</code> are
    208      * equal. This is: they are both <code>null</code>, or they have the
    209      * same length and contain equal nodes at the same index. This is true
    210      * for <code>Attr</code> nodes as for any other type of node. Note that
    211      * normalization can affect equality; to avoid this, nodes should be
    212      * normalized before being compared.
    213      * <br>For two <code>DocumentType</code> nodes to be equal, the following
    214      * conditions must also be satisfied: The following string attributes
    215      * are equal: <code>publicId</code>, <code>systemId</code>,
    216      * <code>internalSubset</code>.The <code>entities</code>
    217      * <code>NamedNodeMaps</code> are equal.The <code>notations</code>
    218      * <code>NamedNodeMaps</code> are equal.
    219      * <br>On the other hand, the following do not affect equality: the
    220      * <code>ownerDocument</code> attribute, the <code>specified</code>
    221      * attribute for <code>Attr</code> nodes, the
    222      * <code>isWhitespaceInElementContent</code> attribute for
    223      * <code>Text</code> nodes, as well as any user data or event listeners
    224      * registered on the nodes.
    225      * @param arg The node to compare equality with.
    226      * @param deep If <code>true</code>, recursively compare the subtrees; if
    227      *   <code>false</code>, compare only the nodes themselves (and its
    228      *   attributes, if it is an <code>Element</code>).
    229      * @return If the nodes, and possibly subtrees are equal,
    230      *   <code>true</code> otherwise <code>false</code>.
    231      * @since DOM Level 3
    232      */
    233     public boolean isEqualNode(Node arg) {
    234         if (arg == this) {
    235             return true;
    236         }
    237         if (arg.getNodeType() != getNodeType()) {
    238             return false;
    239         }
    240         // in theory nodeName can't be null but better be careful
    241         // who knows what other implementations may be doing?...
    242         if (getNodeName() == null) {
    243             if (arg.getNodeName() != null) {
    244                 return false;
    245             }
    246         }
    247         else if (!getNodeName().equals(arg.getNodeName())) {
    248             return false;
    249         }
    250 
    251         if (getLocalName() == null) {
    252             if (arg.getLocalName() != null) {
    253                 return false;
    254             }
    255         }
    256         else if (!getLocalName().equals(arg.getLocalName())) {
    257             return false;
    258         }
    259 
    260         if (getNamespaceURI() == null) {
    261             if (arg.getNamespaceURI() != null) {
    262                 return false;
    263             }
    264         }
    265         else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
    266             return false;
    267         }
    268 
    269         if (getPrefix() == null) {
    270             if (arg.getPrefix() != null) {
    271                 return false;
    272             }
    273         }
    274         else if (!getPrefix().equals(arg.getPrefix())) {
    275             return false;
    276         }
    277 
    278         if (getNodeValue() == null) {
    279             if (arg.getNodeValue() != null) {
    280                 return false;
    281             }
    282         }
    283         else if (!getNodeValue().equals(arg.getNodeValue())) {
    284             return false;
    285         }
    286     /*
    287         if (getBaseURI() == null) {
    288             if (((NodeImpl) arg).getBaseURI() != null) {
    289                 return false;
    290             }
    291         }
    292         else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) {
    293             return false;
    294         }
    295 */
    296 
    297              return true;
    298     }
    299 
    300     /**
    301      * DOM Level 3 - Experimental:
    302      * Look up the namespace URI associated to the given prefix, starting from this node.
    303      * Use lookupNamespaceURI(null) to lookup the default namespace
    304      *
    305      * @param namespaceURI
    306      * @return th URI for the namespace
    307      * @since DOM Level 3
    308      */
    309     public String lookupNamespaceURI(String specifiedPrefix) {
    310         short type = this.getNodeType();
    311         switch (type) {
    312         case Node.ELEMENT_NODE : {
    313 
    314                 String namespace = this.getNamespaceURI();
    315                 String prefix = this.getPrefix();
    316                 if (namespace !=null) {
    317                     // REVISIT: is it possible that prefix is empty string?
    318                     if (specifiedPrefix== null && prefix==specifiedPrefix) {
    319                         // looking for default namespace
    320                         return namespace;
    321                     } else if (prefix != null && prefix.equals(specifiedPrefix)) {
    322                         // non default namespace
    323                         return namespace;
    324                     }
    325                 }
    326                 if (this.hasAttributes()) {
    327                     NamedNodeMap map = this.getAttributes();
    328                     int length = map.getLength();
    329                     for (int i=0;i<length;i++) {
    330                         Node attr = map.item(i);
    331                         String attrPrefix = attr.getPrefix();
    332                         String value = attr.getNodeValue();
    333                         namespace = attr.getNamespaceURI();
    334                         if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
    335                             // at this point we are dealing with DOM Level 2 nodes only
    336                             if (specifiedPrefix == null &&
    337                                 attr.getNodeName().equals("xmlns")) {
    338                                 // default namespace
    339                                 return value;
    340                             } else if (attrPrefix !=null &&
    341                                        attrPrefix.equals("xmlns") &&
    342                                        attr.getLocalName().equals(specifiedPrefix)) {
    343                  // non default namespace
    344                                 return value;
    345                             }
    346                         }
    347                     }
    348                 }
    349 		/*
    350                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
    351                 if (ancestor != null) {
    352                     return ancestor.lookupNamespaceURI(specifiedPrefix);
    353                 }
    354 		*/
    355 
    356                 return null;
    357 
    358 
    359             }
    360 /*
    361         case Node.DOCUMENT_NODE : {
    362                 return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ;
    363             }
    364 */
    365         case Node.ENTITY_NODE :
    366         case Node.NOTATION_NODE:
    367         case Node.DOCUMENT_FRAGMENT_NODE:
    368         case Node.DOCUMENT_TYPE_NODE:
    369             // type is unknown
    370             return null;
    371         case Node.ATTRIBUTE_NODE:{
    372                 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
    373                     return getOwnerElement().lookupNamespaceURI(specifiedPrefix);
    374 
    375                 }
    376                 return null;
    377             }
    378         default:{
    379 	   /*
    380                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
    381                 if (ancestor != null) {
    382                     return ancestor.lookupNamespaceURI(specifiedPrefix);
    383                 }
    384              */
    385                 return null;
    386             }
    387 
    388         }
    389     }
    390 
    391     /**
    392      *  DOM Level 3: Experimental
    393      *  This method checks if the specified <code>namespaceURI</code> is the
    394      *  default namespace or not.
    395      *  @param namespaceURI The namespace URI to look for.
    396      *  @return  <code>true</code> if the specified <code>namespaceURI</code>
    397      *   is the default namespace, <code>false</code> otherwise.
    398      * @since DOM Level 3
    399      */
    400     public boolean isDefaultNamespace(String namespaceURI){
    401        /*
    402         // REVISIT: remove casts when DOM L3 becomes REC.
    403         short type = this.getNodeType();
    404         switch (type) {
    405         case Node.ELEMENT_NODE: {
    406             String namespace = this.getNamespaceURI();
    407             String prefix = this.getPrefix();
    408 
    409             // REVISIT: is it possible that prefix is empty string?
    410             if (prefix == null || prefix.length() == 0) {
    411                 if (namespaceURI == null) {
    412                     return (namespace == namespaceURI);
    413                 }
    414                 return namespaceURI.equals(namespace);
    415             }
    416             if (this.hasAttributes()) {
    417                 ElementImpl elem = (ElementImpl)this;
    418                 NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns");
    419                 if (attr != null) {
    420                     String value = attr.getNodeValue();
    421                     if (namespaceURI == null) {
    422                         return (namespace == value);
    423                     }
    424                     return namespaceURI.equals(value);
    425                 }
    426             }
    427 
    428             NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
    429             if (ancestor != null) {
    430                 return ancestor.isDefaultNamespace(namespaceURI);
    431             }
    432             return false;
    433         }
    434         case Node.DOCUMENT_NODE:{
    435                 return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
    436             }
    437 
    438         case Node.ENTITY_NODE :
    439           case Node.NOTATION_NODE:
    440         case Node.DOCUMENT_FRAGMENT_NODE:
    441         case Node.DOCUMENT_TYPE_NODE:
    442             // type is unknown
    443             return false;
    444         case Node.ATTRIBUTE_NODE:{
    445                 if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) {
    446                     return ownerNode.isDefaultNamespace(namespaceURI);
    447 
    448                 }
    449                 return false;
    450             }
    451         default:{
    452                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
    453                 if (ancestor != null) {
    454                     return ancestor.isDefaultNamespace(namespaceURI);
    455                 }
    456                 return false;
    457             }
    458 
    459         }
    460 */
    461         return false;
    462 
    463 
    464     }
    465 
    466     /**
    467      *
    468      * DOM Level 3 - Experimental:
    469      * Look up the prefix associated to the given namespace URI, starting from this node.
    470      *
    471      * @param namespaceURI
    472      * @return the prefix for the namespace
    473      */
    474     public String lookupPrefix(String namespaceURI){
    475 
    476         // REVISIT: When Namespaces 1.1 comes out this may not be true
    477         // Prefix can't be bound to null namespace
    478         if (namespaceURI == null) {
    479             return null;
    480         }
    481 
    482         short type = this.getNodeType();
    483 
    484         switch (type) {
    485 /*
    486         case Node.ELEMENT_NODE: {
    487 
    488                 String namespace = this.getNamespaceURI(); // to flip out children
    489                 return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
    490             }
    491 
    492         case Node.DOCUMENT_NODE:{
    493                 return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
    494             }
    495 */
    496         case Node.ENTITY_NODE :
    497         case Node.NOTATION_NODE:
    498         case Node.DOCUMENT_FRAGMENT_NODE:
    499         case Node.DOCUMENT_TYPE_NODE:
    500             // type is unknown
    501             return null;
    502         case Node.ATTRIBUTE_NODE:{
    503                 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
    504                     return getOwnerElement().lookupPrefix(namespaceURI);
    505 
    506                 }
    507                 return null;
    508             }
    509         default:{
    510 /*
    511                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
    512                 if (ancestor != null) {
    513                     return ancestor.lookupPrefix(namespaceURI);
    514                 }
    515 */
    516                 return null;
    517             }
    518          }
    519     }
    520 
    521     /**
    522      * Returns whether this node is the same node as the given one.
    523      * <br>This method provides a way to determine whether two
    524      * <code>Node</code> references returned by the implementation reference
    525      * the same object. When two <code>Node</code> references are references
    526      * to the same object, even if through a proxy, the references may be
    527      * used completely interchangably, such that all attributes have the
    528      * same values and calling the same DOM method on either reference
    529      * always has exactly the same effect.
    530      * @param other The node to test against.
    531      * @return Returns <code>true</code> if the nodes are the same,
    532      *   <code>false</code> otherwise.
    533      * @since DOM Level 3
    534      */
    535     public boolean isSameNode(Node other) {
    536         // we do not use any wrapper so the answer is obvious
    537         return this == other;
    538     }
    539 
    540     /**
    541      * This attribute returns the text content of this node and its
    542      * descendants. When it is defined to be null, setting it has no effect.
    543      * When set, any possible children this node may have are removed and
    544      * replaced by a single <code>Text</code> node containing the string
    545      * this attribute is set to. On getting, no serialization is performed,
    546      * the returned string does not contain any markup. No whitespace
    547      * normalization is performed, the returned string does not contain the
    548      * element content whitespaces . Similarly, on setting, no parsing is
    549      * performed either, the input string is taken as pure textual content.
    550      * <br>The string returned is made of the text content of this node
    551      * depending on its type, as defined below:
    552      * <table border='1'>
    553      * <tr>
    554      * <th>Node type</th>
    555      * <th>Content</th>
    556      * </tr>
    557      * <tr>
    558      * <td valign='top' rowspan='1' colspan='1'>
    559      * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
    560      * DOCUMENT_FRAGMENT_NODE</td>
    561      * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
    562      * attribute value of every child node, excluding COMMENT_NODE and
    563      * PROCESSING_INSTRUCTION_NODE nodes</td>
    564      * </tr>
    565      * <tr>
    566      * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
    567      * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
    568      * <td valign='top' rowspan='1' colspan='1'>
    569      * <code>nodeValue</code></td>
    570      * </tr>
    571      * <tr>
    572      * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
    573      * <td valign='top' rowspan='1' colspan='1'>
    574      * null</td>
    575      * </tr>
    576      * </table>
    577      * @exception DOMException
    578      *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
    579      * @exception DOMException
    580      *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
    581      *   fit in a <code>DOMString</code> variable on the implementation
    582      *   platform.
    583      * @since DOM Level 3
    584      */
    585     public void setTextContent(String textContent)
    586         throws DOMException {
    587         setNodeValue(textContent);
    588     }
    589 
    590     /**
    591      * This attribute returns the text content of this node and its
    592      * descendants. When it is defined to be null, setting it has no effect.
    593      * When set, any possible children this node may have are removed and
    594      * replaced by a single <code>Text</code> node containing the string
    595      * this attribute is set to. On getting, no serialization is performed,
    596      * the returned string does not contain any markup. No whitespace
    597      * normalization is performed, the returned string does not contain the
    598      * element content whitespaces . Similarly, on setting, no parsing is
    599      * performed either, the input string is taken as pure textual content.
    600      * <br>The string returned is made of the text content of this node
    601      * depending on its type, as defined below:
    602      * <table border='1'>
    603      * <tr>
    604      * <th>Node type</th>
    605      * <th>Content</th>
    606      * </tr>
    607      * <tr>
    608      * <td valign='top' rowspan='1' colspan='1'>
    609      * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
    610      * DOCUMENT_FRAGMENT_NODE</td>
    611      * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
    612      * attribute value of every child node, excluding COMMENT_NODE and
    613      * PROCESSING_INSTRUCTION_NODE nodes</td>
    614      * </tr>
    615      * <tr>
    616      * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
    617      * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
    618      * <td valign='top' rowspan='1' colspan='1'>
    619      * <code>nodeValue</code></td>
    620      * </tr>
    621      * <tr>
    622      * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
    623      * <td valign='top' rowspan='1' colspan='1'>
    624      * null</td>
    625      * </tr>
    626      * </table>
    627      * @exception DOMException
    628      *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
    629      * @exception DOMException
    630      *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
    631      *   fit in a <code>DOMString</code> variable on the implementation
    632      *   platform.
    633      * @since DOM Level 3
    634      */
    635     public String getTextContent() throws DOMException {
    636         return getNodeValue();  // overriden in some subclasses
    637     }
    638 
    639     /**
    640      * Compares a node with this node with regard to their position in the
    641      * document.
    642      * @param other The node to compare against this node.
    643      * @return Returns how the given node is positioned relatively to this
    644      *   node.
    645      * @since DOM Level 3
    646      */
    647     public short compareDocumentPosition(Node other) throws DOMException {
    648         return 0;
    649     }
    650 
    651     /**
    652      * The absolute base URI of this node or <code>null</code> if undefined.
    653      * This value is computed according to . However, when the
    654      * <code>Document</code> supports the feature "HTML" , the base URI is
    655      * computed using first the value of the href attribute of the HTML BASE
    656      * element if any, and the value of the <code>documentURI</code>
    657      * attribute from the <code>Document</code> interface otherwise.
    658      * <br> When the node is an <code>Element</code>, a <code>Document</code>
    659      * or a a <code>ProcessingInstruction</code>, this attribute represents
    660      * the properties [base URI] defined in . When the node is a
    661      * <code>Notation</code>, an <code>Entity</code>, or an
    662      * <code>EntityReference</code>, this attribute represents the
    663      * properties [declaration base URI] in the . How will this be affected
    664      * by resolution of relative namespace URIs issue?It's not.Should this
    665      * only be on Document, Element, ProcessingInstruction, Entity, and
    666      * Notation nodes, according to the infoset? If not, what is it equal to
    667      * on other nodes? Null? An empty string? I think it should be the
    668      * parent's.No.Should this be read-only and computed or and actual
    669      * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and
    670      * teleconference 30 May 2001).If the base HTML element is not yet
    671      * attached to a document, does the insert change the Document.baseURI?
    672      * Yes. (F2F 26 Sep 2001)
    673      * @since DOM Level 3
    674      */
    675     public String getBaseURI() {
    676         return null;
    677     }
    678 }
    679 
    680