Home | History | Annotate | Download | only in ref
      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: DTMNodeProxy.java 889881 2009-12-12 03:47:15Z zongaro $
     20  */
     21 package org.apache.xml.dtm.ref;
     22 
     23 import java.util.Vector;
     24 
     25 import org.apache.xml.dtm.DTM;
     26 import org.apache.xml.dtm.DTMDOMException;
     27 import org.apache.xpath.NodeSet;
     28 
     29 import org.w3c.dom.Attr;
     30 import org.w3c.dom.CDATASection;
     31 import org.w3c.dom.Comment;
     32 import org.w3c.dom.DOMException;
     33 import org.w3c.dom.DOMImplementation;
     34 import org.w3c.dom.Document;
     35 import org.w3c.dom.DocumentFragment;
     36 import org.w3c.dom.DocumentType;
     37 import org.w3c.dom.Element;
     38 import org.w3c.dom.EntityReference;
     39 import org.w3c.dom.NamedNodeMap;
     40 import org.w3c.dom.Node;
     41 import org.w3c.dom.NodeList;
     42 import org.w3c.dom.ProcessingInstruction;
     43 import org.w3c.dom.Text;
     44 
     45 import org.w3c.dom.UserDataHandler;
     46 import org.w3c.dom.DOMConfiguration;
     47 import org.w3c.dom.TypeInfo;
     48 
     49 /**
     50  * <code>DTMNodeProxy</code> presents a DOM Node API front-end to the DTM model.
     51  * <p>
     52  * It does _not_ attempt to address the "node identity" question; no effort
     53  * is made to prevent the creation of multiple proxies referring to a single
     54  * DTM node. Users can create a mechanism for managing this, or relinquish the
     55  * use of "==" and use the .sameNodeAs() mechanism, which is under
     56  * consideration for future versions of the DOM.
     57  * <p>
     58  * DTMNodeProxy may be subclassed further to present specific DOM node types.
     59  *
     60  * @see org.w3c.dom
     61  * @xsl.usage internal
     62  */
     63 public class DTMNodeProxy
     64   implements Node, Document, Text, Element, Attr,
     65                    ProcessingInstruction, Comment, DocumentFragment
     66 {
     67 
     68   /** The DTM for this node. */
     69   public DTM dtm;
     70 
     71   /** The DTM node handle. */
     72   int node;
     73 
     74   /** The return value as Empty String. */
     75   private static final String EMPTYSTRING = "";
     76 
     77   /** The DOMImplementation object */
     78   static final DOMImplementation implementation=new DTMNodeProxyImplementation();
     79 
     80   /**
     81    * Create a DTMNodeProxy Node representing a specific Node in a DTM
     82    *
     83    * @param dtm The DTM Reference, must be non-null.
     84    * @param node The DTM node handle.
     85    */
     86   public DTMNodeProxy(DTM dtm, int node)
     87   {
     88     this.dtm = dtm;
     89     this.node = node;
     90   }
     91 
     92   /**
     93    * NON-DOM: Return the DTM model
     94    *
     95    * @return The DTM that this proxy is a representative for.
     96    */
     97   public final DTM getDTM()
     98   {
     99     return dtm;
    100   }
    101 
    102   /**
    103    * NON-DOM: Return the DTM node number
    104    *
    105    * @return The DTM node handle.
    106    */
    107   public final int getDTMNodeNumber()
    108   {
    109     return node;
    110   }
    111 
    112   /**
    113    * Test for equality based on node number.
    114    *
    115    * @param node A DTM node proxy reference.
    116    *
    117    * @return true if the given node has the same handle as this node.
    118    */
    119   public final boolean equals(Node node)
    120   {
    121 
    122     try
    123     {
    124       DTMNodeProxy dtmp = (DTMNodeProxy) node;
    125 
    126       // return (dtmp.node == this.node);
    127       // Patch attributed to Gary L Peskin <garyp (at) firstech.com>
    128       return (dtmp.node == this.node) && (dtmp.dtm == this.dtm);
    129     }
    130     catch (ClassCastException cce)
    131     {
    132       return false;
    133     }
    134   }
    135 
    136   /**
    137    * Test for equality based on node number.
    138    *
    139    * @param node A DTM node proxy reference.
    140    *
    141    * @return true if the given node has the same handle as this node.
    142    */
    143   public final boolean equals(Object node)
    144   {
    145 
    146     try
    147     {
    148 
    149       // DTMNodeProxy dtmp = (DTMNodeProxy)node;
    150       // return (dtmp.node == this.node);
    151       // Patch attributed to Gary L Peskin <garyp (at) firstech.com>
    152       return equals((Node) node);
    153     }
    154     catch (ClassCastException cce)
    155     {
    156       return false;
    157     }
    158   }
    159 
    160   /**
    161    * FUTURE DOM: Test node identity, in lieu of Node==Node
    162    *
    163    * @param other
    164    *
    165    * @return true if the given node has the same handle as this node.
    166    */
    167   public final boolean sameNodeAs(Node other)
    168   {
    169 
    170     if (!(other instanceof DTMNodeProxy))
    171       return false;
    172 
    173     DTMNodeProxy that = (DTMNodeProxy) other;
    174 
    175     return this.dtm == that.dtm && this.node == that.node;
    176   }
    177 
    178   /**
    179    *
    180    *
    181    * @see org.w3c.dom.Node
    182    */
    183   public final String getNodeName()
    184   {
    185     return dtm.getNodeName(node);
    186   }
    187 
    188   /**
    189    * A PI's "target" states what processor channel the PI's data
    190    * should be directed to. It is defined differently in HTML and XML.
    191    * <p>
    192    * In XML, a PI's "target" is the first (whitespace-delimited) token
    193    * following the "<?" token that begins the PI.
    194    * <p>
    195    * In HTML, target is always null.
    196    * <p>
    197    * Note that getNodeName is aliased to getTarget.
    198    *
    199    *
    200    */
    201   public final String getTarget()
    202   {
    203     return dtm.getNodeName(node);
    204   }  // getTarget():String
    205 
    206   /**
    207    *
    208    *
    209    * @see org.w3c.dom.Node as of DOM Level 2
    210    */
    211   public final String getLocalName()
    212   {
    213     return dtm.getLocalName(node);
    214   }
    215 
    216   /**
    217    * @return The prefix for this node.
    218    * @see org.w3c.dom.Node as of DOM Level 2
    219    */
    220   public final String getPrefix()
    221   {
    222     return dtm.getPrefix(node);
    223   }
    224 
    225   /**
    226    *
    227    * @param prefix
    228    *
    229    * @throws DOMException
    230    * @see org.w3c.dom.Node as of DOM Level 2 -- DTMNodeProxy is read-only
    231    */
    232   public final void setPrefix(String prefix) throws DOMException
    233   {
    234     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
    235   }
    236 
    237   /**
    238    *
    239    *
    240    * @see org.w3c.dom.Node as of DOM Level 2
    241    */
    242   public final String getNamespaceURI()
    243   {
    244     return dtm.getNamespaceURI(node);
    245   }
    246 
    247   /** Ask whether we support a given DOM feature.
    248    * In fact, we do not _fully_ support any DOM feature -- we're a
    249    * read-only subset -- so arguably we should always return false.
    250    * Or we could say that we support DOM Core Level 2 but all nodes
    251    * are read-only. Unclear which answer is least misleading.
    252    *
    253    * NON-DOM method. This was present in early drafts of DOM Level 2,
    254    * but was renamed isSupported. It's present here only because it's
    255    * cheap, harmless, and might help some poor fool who is still trying
    256    * to use an early Working Draft of the DOM.
    257    *
    258    * @param feature
    259    * @param version
    260    *
    261    * @return false
    262    */
    263   public final boolean supports(String feature, String version)
    264   {
    265     return implementation.hasFeature(feature,version);
    266     //throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    267   }
    268 
    269   /** Ask whether we support a given DOM feature.
    270    * In fact, we do not _fully_ support any DOM feature -- we're a
    271    * read-only subset -- so arguably we should always return false.
    272    *
    273    * @param feature
    274    * @param version
    275    *
    276    * @return false
    277    * @see org.w3c.dom.Node as of DOM Level 2
    278    */
    279   public final boolean isSupported(String feature, String version)
    280   {
    281     return implementation.hasFeature(feature,version);
    282     // throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    283   }
    284 
    285   /**
    286    *
    287    *
    288    *
    289    * @throws DOMException
    290    * @see org.w3c.dom.Node
    291    */
    292   public final String getNodeValue() throws DOMException
    293   {
    294     return dtm.getNodeValue(node);
    295   }
    296 
    297   /**
    298    * @return The string value of the node
    299    *
    300    * @throws DOMException
    301    */
    302   public final String getStringValue() throws DOMException
    303   {
    304   	return dtm.getStringValue(node).toString();
    305   }
    306 
    307   /**
    308    *
    309    * @param nodeValue
    310    *
    311    * @throws DOMException
    312    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    313    */
    314   public final void setNodeValue(String nodeValue) throws DOMException
    315   {
    316     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
    317   }
    318 
    319   /**
    320    *
    321    *
    322    * @see org.w3c.dom.Node
    323    */
    324   public final short getNodeType()
    325   {
    326     return (short) dtm.getNodeType(node);
    327   }
    328 
    329   /**
    330    *
    331    *
    332    * @see org.w3c.dom.Node
    333    */
    334   public final Node getParentNode()
    335   {
    336 
    337     if (getNodeType() == Node.ATTRIBUTE_NODE)
    338       return null;
    339 
    340     int newnode = dtm.getParent(node);
    341 
    342     return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
    343   }
    344 
    345   /**
    346    *
    347    *
    348    * @see org.w3c.dom.Node
    349    */
    350   public final Node getOwnerNode()
    351   {
    352 
    353     int newnode = dtm.getParent(node);
    354 
    355     return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
    356   }
    357 
    358   /**
    359    *
    360    *
    361    * @see org.w3c.dom.Node
    362    */
    363   public final NodeList getChildNodes()
    364   {
    365 
    366     // Annoyingly, AxisIterators do not currently implement DTMIterator, so
    367     // we can't just wap DTMNodeList around an Axis.CHILD iterator.
    368     // Instead, we've created a special-case operating mode for that object.
    369     return new DTMChildIterNodeList(dtm,node);
    370 
    371     // throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    372   }
    373 
    374   /**
    375    *
    376    *
    377    * @see org.w3c.dom.Node
    378    */
    379   public final Node getFirstChild()
    380   {
    381 
    382     int newnode = dtm.getFirstChild(node);
    383 
    384     return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
    385   }
    386 
    387   /**
    388    *
    389    *
    390    * @see org.w3c.dom.Node
    391    */
    392   public final Node getLastChild()
    393   {
    394 
    395     int newnode = dtm.getLastChild(node);
    396 
    397     return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
    398   }
    399 
    400   /**
    401    *
    402    *
    403    * @see org.w3c.dom.Node
    404    */
    405   public final Node getPreviousSibling()
    406   {
    407 
    408     int newnode = dtm.getPreviousSibling(node);
    409 
    410     return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
    411   }
    412 
    413   /**
    414    *
    415    *
    416    * @see org.w3c.dom.Node
    417    */
    418   public final Node getNextSibling()
    419   {
    420 
    421     // Attr's Next is defined at DTM level, but not at DOM level.
    422     if (dtm.getNodeType(node) == Node.ATTRIBUTE_NODE)
    423       return null;
    424 
    425     int newnode = dtm.getNextSibling(node);
    426 
    427     return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
    428   }
    429 
    430   // DTMNamedNodeMap m_attrs;
    431 
    432   /**
    433    *
    434    *
    435    * @see org.w3c.dom.Node
    436    */
    437   public final NamedNodeMap getAttributes()
    438   {
    439 
    440     return new DTMNamedNodeMap(dtm, node);
    441   }
    442 
    443   /**
    444    * Method hasAttribute
    445    *
    446    *
    447    * @param name
    448    *
    449    *
    450    */
    451   public boolean hasAttribute(String name)
    452   {
    453     return DTM.NULL != dtm.getAttributeNode(node,null,name);
    454   }
    455 
    456   /**
    457    * Method hasAttributeNS
    458    *
    459    *
    460    * @param namespaceURI
    461    * @param localName
    462    *
    463    *
    464    */
    465   public boolean hasAttributeNS(String namespaceURI, String localName)
    466   {
    467     return DTM.NULL != dtm.getAttributeNode(node,namespaceURI,localName);
    468   }
    469 
    470   /**
    471    *
    472    *
    473    * @see org.w3c.dom.Node
    474    */
    475   public final Document getOwnerDocument()
    476   {
    477   	// Note that this uses the DOM-compatable version of the call
    478 	return (Document)(dtm.getNode(dtm.getOwnerDocument(node)));
    479   }
    480 
    481   /**
    482    *
    483    * @param newChild
    484    * @param refChild
    485    *
    486    *
    487    *
    488    * @throws DOMException
    489    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    490    */
    491   public final Node insertBefore(Node newChild, Node refChild)
    492     throws DOMException
    493   {
    494     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
    495   }
    496 
    497   /**
    498    *
    499    * @param newChild
    500    * @param oldChild
    501    *
    502    *
    503    *
    504    * @throws DOMException
    505    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    506    */
    507   public final Node replaceChild(Node newChild, Node oldChild)
    508     throws DOMException
    509   {
    510     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
    511   }
    512 
    513   /**
    514    *
    515    * @param oldChild
    516    *
    517    *
    518    *
    519    * @throws DOMException
    520    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    521    */
    522   public final Node removeChild(Node oldChild) throws DOMException
    523   {
    524     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
    525   }
    526 
    527   /**
    528    *
    529    * @param newChild
    530    *
    531    *
    532    *
    533    * @throws DOMException
    534    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    535    */
    536   public final Node appendChild(Node newChild) throws DOMException
    537   {
    538     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
    539   }
    540 
    541   /**
    542    *
    543    *
    544    * @see org.w3c.dom.Node
    545    */
    546   public final boolean hasChildNodes()
    547   {
    548     return (DTM.NULL != dtm.getFirstChild(node));
    549   }
    550 
    551   /**
    552    *
    553    * @param deep
    554    *
    555    *
    556    * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
    557    */
    558   public final Node cloneNode(boolean deep)
    559   {
    560     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    561   }
    562 
    563   /**
    564    *
    565    *
    566    * @see org.w3c.dom.Document
    567    */
    568   public final DocumentType getDoctype()
    569   {
    570     return null;
    571   }
    572 
    573   /**
    574    *
    575    *
    576    * @see org.w3c.dom.Document
    577    */
    578   public final DOMImplementation getImplementation()
    579   {
    580     return implementation;
    581   }
    582 
    583   /** This is a bit of a problem in DTM, since a DTM may be a Document
    584    * Fragment and hence not have a clear-cut Document Element. We can
    585    * make it work in the well-formed cases but would that be confusing for others?
    586    *
    587    *
    588    * @see org.w3c.dom.Document
    589    */
    590   public final Element getDocumentElement()
    591   {
    592 		int dochandle=dtm.getDocument();
    593 		int elementhandle=DTM.NULL;
    594 		for(int kidhandle=dtm.getFirstChild(dochandle);
    595 				kidhandle!=DTM.NULL;
    596 				kidhandle=dtm.getNextSibling(kidhandle))
    597 		{
    598 			switch(dtm.getNodeType(kidhandle))
    599 			{
    600 			case Node.ELEMENT_NODE:
    601 				if(elementhandle!=DTM.NULL)
    602 				{
    603 					elementhandle=DTM.NULL; // More than one; ill-formed.
    604 					kidhandle=dtm.getLastChild(dochandle); // End loop
    605 				}
    606 				else
    607 					elementhandle=kidhandle;
    608 				break;
    609 
    610 			// These are harmless; document is still wellformed
    611 			case Node.COMMENT_NODE:
    612 			case Node.PROCESSING_INSTRUCTION_NODE:
    613 			case Node.DOCUMENT_TYPE_NODE:
    614 				break;
    615 
    616 			default:
    617 				elementhandle=DTM.NULL; // ill-formed
    618 				kidhandle=dtm.getLastChild(dochandle); // End loop
    619 				break;
    620 			}
    621 		}
    622 		if(elementhandle==DTM.NULL)
    623 			throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    624 		else
    625 			return (Element)(dtm.getNode(elementhandle));
    626   }
    627 
    628   /**
    629    *
    630    * @param tagName
    631    *
    632    *
    633    *
    634    * @throws DOMException
    635    * @see org.w3c.dom.Document
    636    */
    637   public final Element createElement(String tagName) throws DOMException
    638   {
    639     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    640   }
    641 
    642   /**
    643    *
    644    *
    645    * @see org.w3c.dom.Document
    646    */
    647   public final DocumentFragment createDocumentFragment()
    648   {
    649     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    650   }
    651 
    652   /**
    653    *
    654    * @param data
    655    *
    656    *
    657    * @see org.w3c.dom.Document
    658    */
    659   public final Text createTextNode(String data)
    660   {
    661     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    662   }
    663 
    664   /**
    665    *
    666    * @param data
    667    *
    668    *
    669    * @see org.w3c.dom.Document
    670    */
    671   public final Comment createComment(String data)
    672   {
    673     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    674   }
    675 
    676   /**
    677    *
    678    * @param data
    679    *
    680    *
    681    *
    682    * @throws DOMException
    683    * @see org.w3c.dom.Document
    684    */
    685   public final CDATASection createCDATASection(String data)
    686     throws DOMException
    687   {
    688     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    689   }
    690 
    691   /**
    692    *
    693    * @param target
    694    * @param data
    695    *
    696    *
    697    *
    698    * @throws DOMException
    699    * @see org.w3c.dom.Document
    700    */
    701   public final ProcessingInstruction createProcessingInstruction(
    702                                                                  String target, String data) throws DOMException
    703   {
    704     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    705   }
    706 
    707   /**
    708    *
    709    * @param name
    710    *
    711    *
    712    *
    713    * @throws DOMException
    714    * @see org.w3c.dom.Document
    715    */
    716   public final Attr createAttribute(String name) throws DOMException
    717   {
    718     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    719   }
    720 
    721   /**
    722    *
    723    * @param name
    724    *
    725    *
    726    *
    727    * @throws DOMException
    728    * @see org.w3c.dom.Document
    729    */
    730   public final EntityReference createEntityReference(String name)
    731     throws DOMException
    732   {
    733     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    734   }
    735 
    736   /**
    737    *
    738    * @param tagname
    739    *
    740    *
    741    * @see org.w3c.dom.Document
    742    */
    743   public final NodeList getElementsByTagName(String tagname)
    744   {
    745        Vector listVector = new Vector();
    746        Node retNode = dtm.getNode(node);
    747        if (retNode != null)
    748        {
    749          boolean isTagNameWildCard = "*".equals(tagname);
    750          if (DTM.ELEMENT_NODE == retNode.getNodeType())
    751          {
    752            NodeList nodeList = retNode.getChildNodes();
    753            for (int i = 0; i < nodeList.getLength(); i++)
    754            {
    755              traverseChildren(listVector, nodeList.item(i), tagname,
    756                               isTagNameWildCard);
    757            }
    758          } else if (DTM.DOCUMENT_NODE == retNode.getNodeType()) {
    759            traverseChildren(listVector, dtm.getNode(node), tagname,
    760                             isTagNameWildCard);
    761          }
    762        }
    763        int size = listVector.size();
    764        NodeSet nodeSet = new NodeSet(size);
    765        for (int i = 0; i < size; i++)
    766        {
    767          nodeSet.addNode((Node) listVector.elementAt(i));
    768        }
    769        return (NodeList) nodeSet;
    770   }
    771   /**
    772    *
    773    * @param listVector
    774    * @param tempNode
    775    * @param tagname
    776    * @param isTagNameWildCard
    777    *
    778    *
    779    * Private method to be used for recursive iterations to obtain elements by tag name.
    780    */
    781   private final void traverseChildren
    782   (
    783     Vector listVector,
    784     Node tempNode,
    785     String tagname,
    786     boolean isTagNameWildCard) {
    787     if (tempNode == null)
    788     {
    789       return;
    790     }
    791     else
    792     {
    793       if (tempNode.getNodeType() == DTM.ELEMENT_NODE
    794             && (isTagNameWildCard || tempNode.getNodeName().equals(tagname)))
    795       {
    796         listVector.add(tempNode);
    797       }
    798       if(tempNode.hasChildNodes())
    799       {
    800         NodeList nodeList = tempNode.getChildNodes();
    801         for (int i = 0; i < nodeList.getLength(); i++)
    802         {
    803           traverseChildren(listVector, nodeList.item(i), tagname,
    804                            isTagNameWildCard);
    805         }
    806       }
    807     }
    808   }
    809 
    810   /**
    811    *
    812    * @param importedNode
    813    * @param deep
    814    *
    815    *
    816    *
    817    * @throws DOMException
    818    * @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only
    819    */
    820   public final Node importNode(Node importedNode, boolean deep)
    821     throws DOMException
    822   {
    823     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
    824   }
    825 
    826   /**
    827    *
    828    * @param namespaceURI
    829    * @param qualifiedName
    830    *
    831    *
    832    *
    833    * @throws DOMException
    834    * @see org.w3c.dom.Document as of DOM Level 2
    835    */
    836   public final Element createElementNS(
    837                                        String namespaceURI, String qualifiedName) throws DOMException
    838   {
    839     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    840   }
    841 
    842   /**
    843    *
    844    * @param namespaceURI
    845    * @param qualifiedName
    846    *
    847    *
    848    *
    849    * @throws DOMException
    850    * @see org.w3c.dom.Document as of DOM Level 2
    851    */
    852   public final Attr createAttributeNS(
    853                                       String namespaceURI, String qualifiedName) throws DOMException
    854   {
    855     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    856   }
    857 
    858   /**
    859    *
    860    * @param namespaceURI
    861    * @param localName
    862    *
    863    *
    864    * @see org.w3c.dom.Document as of DOM Level 2
    865    */
    866   public final NodeList getElementsByTagNameNS(String namespaceURI,
    867                                                String localName)
    868   {
    869     Vector listVector = new Vector();
    870     Node retNode = dtm.getNode(node);
    871     if (retNode != null)
    872     {
    873       boolean isNamespaceURIWildCard = "*".equals(namespaceURI);
    874       boolean isLocalNameWildCard    = "*".equals(localName);
    875       if (DTM.ELEMENT_NODE == retNode.getNodeType())
    876       {
    877         NodeList nodeList = retNode.getChildNodes();
    878         for(int i = 0; i < nodeList.getLength(); i++)
    879         {
    880           traverseChildren(listVector, nodeList.item(i), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard);
    881         }
    882       }
    883       else if(DTM.DOCUMENT_NODE == retNode.getNodeType())
    884       {
    885         traverseChildren(listVector, dtm.getNode(node), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard);
    886       }
    887     }
    888     int size = listVector.size();
    889     NodeSet nodeSet = new NodeSet(size);
    890     for (int i = 0; i < size; i++)
    891     {
    892       nodeSet.addNode((Node)listVector.elementAt(i));
    893     }
    894     return (NodeList) nodeSet;
    895   }
    896   /**
    897    *
    898    * @param listVector
    899    * @param tempNode
    900    * @param namespaceURI
    901    * @param localname
    902    * @param isNamespaceURIWildCard
    903    * @param isLocalNameWildCard
    904    *
    905    * Private method to be used for recursive iterations to obtain elements by tag name
    906    * and namespaceURI.
    907    */
    908   private final void traverseChildren
    909   (
    910    Vector listVector,
    911    Node tempNode,
    912    String namespaceURI,
    913    String localname,
    914    boolean isNamespaceURIWildCard,
    915    boolean isLocalNameWildCard)
    916    {
    917     if (tempNode == null)
    918     {
    919       return;
    920     }
    921     else
    922     {
    923       if (tempNode.getNodeType() == DTM.ELEMENT_NODE
    924               && (isLocalNameWildCard
    925                       || tempNode.getLocalName().equals(localname)))
    926       {
    927         String nsURI = tempNode.getNamespaceURI();
    928         if ((namespaceURI == null && nsURI == null)
    929                || isNamespaceURIWildCard
    930                || (namespaceURI != null && namespaceURI.equals(nsURI)))
    931         {
    932           listVector.add(tempNode);
    933         }
    934       }
    935       if(tempNode.hasChildNodes())
    936       {
    937         NodeList nl = tempNode.getChildNodes();
    938         for(int i = 0; i < nl.getLength(); i++)
    939         {
    940           traverseChildren(listVector, nl.item(i), namespaceURI, localname,
    941                            isNamespaceURIWildCard, isLocalNameWildCard);
    942         }
    943       }
    944     }
    945   }
    946   /**
    947    *
    948    * @param elementId
    949    *
    950    *
    951    * @see org.w3c.dom.Document as of DOM Level 2
    952    */
    953   public final Element getElementById(String elementId)
    954   {
    955        return (Element) dtm.getNode(dtm.getElementById(elementId));
    956   }
    957 
    958   /**
    959    *
    960    * @param offset
    961    *
    962    *
    963    *
    964    * @throws DOMException
    965    * @see org.w3c.dom.Text
    966    */
    967   public final Text splitText(int offset) throws DOMException
    968   {
    969     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    970   }
    971 
    972   /**
    973    *
    974    *
    975    *
    976    * @throws DOMException
    977    * @see org.w3c.dom.CharacterData
    978    */
    979   public final String getData() throws DOMException
    980   {
    981     return dtm.getNodeValue(node);
    982   }
    983 
    984   /**
    985    *
    986    * @param data
    987    *
    988    * @throws DOMException
    989    * @see org.w3c.dom.CharacterData
    990    */
    991   public final void setData(String data) throws DOMException
    992   {
    993     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
    994   }
    995 
    996   /**
    997    *
    998    *
    999    * @see org.w3c.dom.CharacterData
   1000    */
   1001   public final int getLength()
   1002   {
   1003     // %OPT% This should do something smarter?
   1004     return dtm.getNodeValue(node).length();
   1005   }
   1006 
   1007   /**
   1008    *
   1009    * @param offset
   1010    * @param count
   1011    *
   1012    *
   1013    *
   1014    * @throws DOMException
   1015    * @see org.w3c.dom.CharacterData
   1016    */
   1017   public final String substringData(int offset, int count) throws DOMException
   1018   {
   1019     return getData().substring(offset,offset+count);
   1020   }
   1021 
   1022   /**
   1023    *
   1024    * @param arg
   1025    *
   1026    * @throws DOMException
   1027    * @see org.w3c.dom.CharacterData
   1028    */
   1029   public final void appendData(String arg) throws DOMException
   1030   {
   1031     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1032   }
   1033 
   1034   /**
   1035    *
   1036    * @param offset
   1037    * @param arg
   1038    *
   1039    * @throws DOMException
   1040    * @see org.w3c.dom.CharacterData
   1041    */
   1042   public final void insertData(int offset, String arg) throws DOMException
   1043   {
   1044     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1045   }
   1046 
   1047   /**
   1048    *
   1049    * @param offset
   1050    * @param count
   1051    *
   1052    * @throws DOMException
   1053    * @see org.w3c.dom.CharacterData
   1054    */
   1055   public final void deleteData(int offset, int count) throws DOMException
   1056   {
   1057     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1058   }
   1059 
   1060   /**
   1061    *
   1062    * @param offset
   1063    * @param count
   1064    * @param arg
   1065    *
   1066    * @throws DOMException
   1067    * @see org.w3c.dom.CharacterData
   1068    */
   1069   public final void replaceData(int offset, int count, String arg)
   1070     throws DOMException
   1071   {
   1072     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1073   }
   1074 
   1075   /**
   1076    *
   1077    *
   1078    * @see org.w3c.dom.Element
   1079    */
   1080   public final String getTagName()
   1081   {
   1082     return dtm.getNodeName(node);
   1083   }
   1084 
   1085   /**
   1086    *
   1087    * @param name
   1088    *
   1089    *
   1090    * @see org.w3c.dom.Element
   1091    */
   1092   public final String getAttribute(String name)
   1093   {
   1094 
   1095     DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
   1096     Node node = map.getNamedItem(name);
   1097     return (null == node) ? EMPTYSTRING : node.getNodeValue();
   1098   }
   1099 
   1100   /**
   1101    *
   1102    * @param name
   1103    * @param value
   1104    *
   1105    * @throws DOMException
   1106    * @see org.w3c.dom.Element
   1107    */
   1108   public final void setAttribute(String name, String value)
   1109     throws DOMException
   1110   {
   1111     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1112   }
   1113 
   1114   /**
   1115    *
   1116    * @param name
   1117    *
   1118    * @throws DOMException
   1119    * @see org.w3c.dom.Element
   1120    */
   1121   public final void removeAttribute(String name) throws DOMException
   1122   {
   1123     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1124   }
   1125 
   1126   /**
   1127    *
   1128    * @param name
   1129    *
   1130    *
   1131    * @see org.w3c.dom.Element
   1132    */
   1133   public final Attr getAttributeNode(String name)
   1134   {
   1135 
   1136     DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
   1137     return (Attr)map.getNamedItem(name);
   1138   }
   1139 
   1140   /**
   1141    *
   1142    * @param newAttr
   1143    *
   1144    *
   1145    *
   1146    * @throws DOMException
   1147    * @see org.w3c.dom.Element
   1148    */
   1149   public final Attr setAttributeNode(Attr newAttr) throws DOMException
   1150   {
   1151     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1152   }
   1153 
   1154   /**
   1155    *
   1156    * @param oldAttr
   1157    *
   1158    *
   1159    *
   1160    * @throws DOMException
   1161    * @see org.w3c.dom.Element
   1162    */
   1163   public final Attr removeAttributeNode(Attr oldAttr) throws DOMException
   1164   {
   1165     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1166   }
   1167 
   1168   /**
   1169    * Introduced in DOM Level 2.
   1170    *
   1171    *
   1172    */
   1173   public boolean hasAttributes()
   1174   {
   1175     return DTM.NULL != dtm.getFirstAttribute(node);
   1176   }
   1177 
   1178   /** @see org.w3c.dom.Element */
   1179   public final void normalize()
   1180   {
   1181     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1182   }
   1183 
   1184   /**
   1185    *
   1186    * @param namespaceURI
   1187    * @param localName
   1188    *
   1189    *
   1190    * @see org.w3c.dom.Element
   1191    */
   1192   public final String getAttributeNS(String namespaceURI, String localName)
   1193   {
   1194        Node retNode = null;
   1195        int n = dtm.getAttributeNode(node,namespaceURI,localName);
   1196        if(n != DTM.NULL)
   1197                retNode = dtm.getNode(n);
   1198        return (null == retNode) ? EMPTYSTRING : retNode.getNodeValue();
   1199   }
   1200 
   1201   /**
   1202    *
   1203    * @param namespaceURI
   1204    * @param qualifiedName
   1205    * @param value
   1206    *
   1207    * @throws DOMException
   1208    * @see org.w3c.dom.Element
   1209    */
   1210   public final void setAttributeNS(
   1211                                    String namespaceURI, String qualifiedName, String value)
   1212     throws DOMException
   1213   {
   1214     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1215   }
   1216 
   1217   /**
   1218    *
   1219    * @param namespaceURI
   1220    * @param localName
   1221    *
   1222    * @throws DOMException
   1223    * @see org.w3c.dom.Element
   1224    */
   1225   public final void removeAttributeNS(String namespaceURI, String localName)
   1226     throws DOMException
   1227   {
   1228     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1229   }
   1230 
   1231   /**
   1232    *
   1233    * @param namespaceURI
   1234    * @param localName
   1235    *
   1236    *
   1237    * @see org.w3c.dom.Element
   1238    */
   1239   public final Attr getAttributeNodeNS(String namespaceURI, String localName)
   1240   {
   1241        Attr retAttr = null;
   1242        int n = dtm.getAttributeNode(node,namespaceURI,localName);
   1243        if(n != DTM.NULL)
   1244                retAttr = (Attr) dtm.getNode(n);
   1245        return retAttr;
   1246   }
   1247 
   1248   /**
   1249    *
   1250    * @param newAttr
   1251    *
   1252    *
   1253    *
   1254    * @throws DOMException
   1255    * @see org.w3c.dom.Element
   1256    */
   1257   public final Attr setAttributeNodeNS(Attr newAttr) throws DOMException
   1258   {
   1259     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1260   }
   1261 
   1262   /**
   1263    *
   1264    *
   1265    * @see org.w3c.dom.Attr
   1266    */
   1267   public final String getName()
   1268   {
   1269     return dtm.getNodeName(node);
   1270   }
   1271 
   1272   /**
   1273    *
   1274    *
   1275    * @see org.w3c.dom.Attr
   1276    */
   1277   public final boolean getSpecified()
   1278   {
   1279     // We really don't know which attributes might have come from the
   1280     // source document versus from the DTD. Treat them all as having
   1281     // been provided by the user.
   1282     // %REVIEW% if/when we become aware of DTDs/schemae.
   1283     return true;
   1284   }
   1285 
   1286   /**
   1287    *
   1288    *
   1289    * @see org.w3c.dom.Attr
   1290    */
   1291   public final String getValue()
   1292   {
   1293     return dtm.getNodeValue(node);
   1294   }
   1295 
   1296   /**
   1297    *
   1298    * @param value
   1299    * @see org.w3c.dom.Attr
   1300    */
   1301   public final void setValue(String value)
   1302   {
   1303     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1304   }
   1305 
   1306   /**
   1307    * Get the owner element of an attribute.
   1308    *
   1309    *
   1310    * @see org.w3c.dom.Attr as of DOM Level 2
   1311    */
   1312   public final Element getOwnerElement()
   1313   {
   1314     if (getNodeType() != Node.ATTRIBUTE_NODE)
   1315       return null;
   1316     // In XPath and DTM data models, unlike DOM, an Attr's parent is its
   1317     // owner element.
   1318     int newnode = dtm.getParent(node);
   1319     return (newnode == DTM.NULL) ? null : (Element)(dtm.getNode(newnode));
   1320   }
   1321 
   1322   /**
   1323    * NEEDSDOC Method adoptNode
   1324    *
   1325    *
   1326    * NEEDSDOC @param source
   1327    *
   1328    *
   1329    *
   1330    * @throws DOMException
   1331    */
   1332   public Node adoptNode(Node source) throws DOMException
   1333   {
   1334 
   1335     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1336   }
   1337 
   1338   /**
   1339    * <p>Based on the <a
   1340    * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
   1341    * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
   1342    * <p>
   1343    * An attribute specifying, as part of the XML declaration, the encoding
   1344    * of this document. This is <code>null</code> when unspecified.
   1345    * @since DOM Level 3
   1346    *
   1347    *
   1348    */
   1349   public String getInputEncoding()
   1350   {
   1351 
   1352     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1353   }
   1354 
   1355   /**
   1356    * <p>Based on the <a
   1357    * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
   1358    * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
   1359    * <p>
   1360    * An attribute specifying whether errors checking is enforced or not.
   1361    * When set to <code>false</code>, the implementation is free to not
   1362    * test every possible error case normally defined on DOM operations,
   1363    * and not raise any <code>DOMException</code>. In case of error, the
   1364    * behavior is undefined. This attribute is <code>true</code> by
   1365    * defaults.
   1366    * @since DOM Level 3
   1367    *
   1368    *
   1369    */
   1370   public boolean getStrictErrorChecking()
   1371   {
   1372 
   1373     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1374   }
   1375 
   1376   /**
   1377    * <p>Based on the <a
   1378    * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
   1379    * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
   1380    * <p>
   1381    * An attribute specifying whether errors checking is enforced or not.
   1382    * When set to <code>false</code>, the implementation is free to not
   1383    * test every possible error case normally defined on DOM operations,
   1384    * and not raise any <code>DOMException</code>. In case of error, the
   1385    * behavior is undefined. This attribute is <code>true</code> by
   1386    * defaults.
   1387    * @since DOM Level 3
   1388    *
   1389    * NEEDSDOC @param strictErrorChecking
   1390    */
   1391   public void setStrictErrorChecking(boolean strictErrorChecking)
   1392   {
   1393     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1394   }
   1395 
   1396   /** Inner class to support getDOMImplementation.
   1397    */
   1398   static class DTMNodeProxyImplementation implements DOMImplementation
   1399   {
   1400     public DocumentType createDocumentType(String qualifiedName,String publicId, String systemId)
   1401     {
   1402       throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1403     }
   1404     public Document createDocument(String namespaceURI,String qualfiedName,DocumentType doctype)
   1405     {
   1406       // Could create a DTM... but why, when it'd have to be permanantly empty?
   1407       throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
   1408     }
   1409     /** Ask whether we support a given DOM feature.
   1410      *
   1411      * In fact, we do not _fully_ support any DOM feature -- we're a
   1412      * read-only subset -- so arguably we should always return false.
   1413      * On the other hand, it may be more practically useful to return
   1414      * true and simply treat the whole DOM as read-only, failing on the
   1415      * methods we can't support. I'm not sure which would be more useful
   1416      * to the caller.
   1417      */
   1418     public boolean hasFeature(String feature,String version)
   1419     {
   1420       if( ("CORE".equals(feature.toUpperCase()) || "XML".equals(feature.toUpperCase()))
   1421 					&&
   1422           ("1.0".equals(version) || "2.0".equals(version))
   1423           )
   1424         return true;
   1425       return false;
   1426     }
   1427 
   1428     /**
   1429      *  This method returns a specialized object which implements the
   1430      * specialized APIs of the specified feature and version. The
   1431      * specialized object may also be obtained by using binding-specific
   1432      * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations
   1433 .
   1434      * @param feature The name of the feature requested (case-insensitive).
   1435      * @param version  This is the version number of the feature to test. If
   1436      *   the version is <code>null</code> or the empty string, supporting
   1437      *   any version of the feature will cause the method to return an
   1438      *   object that supports at least one version of the feature.
   1439      * @return  Returns an object which implements the specialized APIs of
   1440      *   the specified feature and version, if any, or <code>null</code> if
   1441      *   there is no object which implements interfaces associated with that
   1442      *   feature. If the <code>DOMObject</code> returned by this method
   1443      *   implements the <code>Node</code> interface, it must delegate to the
   1444      *   primary core <code>Node</code> and not return results inconsistent
   1445      *   with the primary core <code>Node</code> such as attributes,
   1446      *   childNodes, etc.
   1447      * @since DOM Level 3
   1448      */
   1449     public Object getFeature(String feature, String version) {
   1450         // we don't have any alternate node, either this node does the job
   1451         // or we don't have anything that does
   1452         //return hasFeature(feature, version) ? this : null;
   1453         return null; //PENDING
   1454     }
   1455 
   1456   }
   1457 
   1458 
   1459     //RAMESH : Pending proper implementation of DOM Level 3
   1460 
   1461     public Object setUserData(String key,
   1462                               Object data,
   1463                               UserDataHandler handler) {
   1464         return getOwnerDocument().setUserData( key, data, handler);
   1465     }
   1466 
   1467     /**
   1468      * Retrieves the object associated to a key on a this node. The object
   1469      * must first have been set to this node by calling
   1470      * <code>setUserData</code> with the same key.
   1471      * @param key The key the object is associated to.
   1472      * @return Returns the <code>DOMObject</code> associated to the given key
   1473      *   on this node, or <code>null</code> if there was none.
   1474      * @since DOM Level 3
   1475      */
   1476     public Object getUserData(String key) {
   1477         return getOwnerDocument().getUserData( key);
   1478     }
   1479 
   1480     /**
   1481      *  This method returns a specialized object which implements the
   1482      * specialized APIs of the specified feature and version. The
   1483      * specialized object may also be obtained by using binding-specific
   1484      * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations.
   1485      * @param feature The name of the feature requested (case-insensitive).
   1486      * @param version  This is the version number of the feature to test. If
   1487      *   the version is <code>null</code> or the empty string, supporting
   1488      *   any version of the feature will cause the method to return an
   1489      *   object that supports at least one version of the feature.
   1490      * @return  Returns an object which implements the specialized APIs of
   1491      *   the specified feature and version, if any, or <code>null</code> if
   1492      *   there is no object which implements interfaces associated with that
   1493      *   feature. If the <code>DOMObject</code> returned by this method
   1494      *   implements the <code>Node</code> interface, it must delegate to the
   1495      *   primary core <code>Node</code> and not return results inconsistent
   1496      *   with the primary core <code>Node</code> such as attributes,
   1497      *   childNodes, etc.
   1498      * @since DOM Level 3
   1499      */
   1500     public Object getFeature(String feature, String version) {
   1501         // we don't have any alternate node, either this node does the job
   1502         // or we don't have anything that does
   1503         return isSupported(feature, version) ? this : null;
   1504     }
   1505 
   1506     /**
   1507      * Tests whether two nodes are equal.
   1508      * <br>This method tests for equality of nodes, not sameness (i.e.,
   1509      * whether the two nodes are references to the same object) which can be
   1510      * tested with <code>Node.isSameNode</code>. All nodes that are the same
   1511      * will also be equal, though the reverse may not be true.
   1512      * <br>Two nodes are equal if and only if the following conditions are
   1513      * satisfied: The two nodes are of the same type.The following string
   1514      * attributes are equal: <code>nodeName</code>, <code>localName</code>,
   1515      * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
   1516      * , <code>baseURI</code>. This is: they are both <code>null</code>, or
   1517      * they have the same length and are character for character identical.
   1518      * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
   1519      * This is: they are both <code>null</code>, or they have the same
   1520      * length and for each node that exists in one map there is a node that
   1521      * exists in the other map and is equal, although not necessarily at the
   1522      * same index.The <code>childNodes</code> <code>NodeLists</code> are
   1523      * equal. This is: they are both <code>null</code>, or they have the
   1524      * same length and contain equal nodes at the same index. This is true
   1525      * for <code>Attr</code> nodes as for any other type of node. Note that
   1526      * normalization can affect equality; to avoid this, nodes should be
   1527      * normalized before being compared.
   1528      * <br>For two <code>DocumentType</code> nodes to be equal, the following
   1529      * conditions must also be satisfied: The following string attributes
   1530      * are equal: <code>publicId</code>, <code>systemId</code>,
   1531      * <code>internalSubset</code>.The <code>entities</code>
   1532      * <code>NamedNodeMaps</code> are equal.The <code>notations</code>
   1533      * <code>NamedNodeMaps</code> are equal.
   1534      * <br>On the other hand, the following do not affect equality: the
   1535      * <code>ownerDocument</code> attribute, the <code>specified</code>
   1536      * attribute for <code>Attr</code> nodes, the
   1537      * <code>isWhitespaceInElementContent</code> attribute for
   1538      * <code>Text</code> nodes, as well as any user data or event listeners
   1539      * registered on the nodes.
   1540      * @param arg The node to compare equality with.
   1541      * @param deep If <code>true</code>, recursively compare the subtrees; if
   1542      *   <code>false</code>, compare only the nodes themselves (and its
   1543      *   attributes, if it is an <code>Element</code>).
   1544      * @return If the nodes, and possibly subtrees are equal,
   1545      *   <code>true</code> otherwise <code>false</code>.
   1546      * @since DOM Level 3
   1547      */
   1548     public boolean isEqualNode(Node arg) {
   1549         if (arg == this) {
   1550             return true;
   1551         }
   1552         if (arg.getNodeType() != getNodeType()) {
   1553             return false;
   1554         }
   1555         // in theory nodeName can't be null but better be careful
   1556         // who knows what other implementations may be doing?...
   1557         if (getNodeName() == null) {
   1558             if (arg.getNodeName() != null) {
   1559                 return false;
   1560             }
   1561         }
   1562         else if (!getNodeName().equals(arg.getNodeName())) {
   1563             return false;
   1564         }
   1565 
   1566         if (getLocalName() == null) {
   1567             if (arg.getLocalName() != null) {
   1568                 return false;
   1569             }
   1570         }
   1571         else if (!getLocalName().equals(arg.getLocalName())) {
   1572             return false;
   1573         }
   1574 
   1575         if (getNamespaceURI() == null) {
   1576             if (arg.getNamespaceURI() != null) {
   1577                 return false;
   1578             }
   1579         }
   1580         else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
   1581             return false;
   1582         }
   1583 
   1584         if (getPrefix() == null) {
   1585             if (arg.getPrefix() != null) {
   1586                 return false;
   1587             }
   1588         }
   1589         else if (!getPrefix().equals(arg.getPrefix())) {
   1590             return false;
   1591         }
   1592 
   1593         if (getNodeValue() == null) {
   1594             if (arg.getNodeValue() != null) {
   1595                 return false;
   1596             }
   1597         }
   1598         else if (!getNodeValue().equals(arg.getNodeValue())) {
   1599             return false;
   1600         }
   1601     /*
   1602         if (getBaseURI() == null) {
   1603             if (((NodeImpl) arg).getBaseURI() != null) {
   1604                 return false;
   1605             }
   1606         }
   1607         else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) {
   1608             return false;
   1609         }
   1610 */
   1611         return true;
   1612     }
   1613 
   1614     /**
   1615      * DOM Level 3:
   1616      * Look up the namespace URI associated to the given prefix, starting from this node.
   1617      * Use lookupNamespaceURI(null) to lookup the default namespace
   1618      *
   1619      * @param namespaceURI
   1620      * @return th URI for the namespace
   1621      * @since DOM Level 3
   1622      */
   1623     public String lookupNamespaceURI(String specifiedPrefix) {
   1624         short type = this.getNodeType();
   1625         switch (type) {
   1626         case Node.ELEMENT_NODE : {
   1627 
   1628                 String namespace = this.getNamespaceURI();
   1629                 String prefix = this.getPrefix();
   1630                 if (namespace !=null) {
   1631                     // REVISIT: is it possible that prefix is empty string?
   1632                     if (specifiedPrefix== null && prefix==specifiedPrefix) {
   1633                         // looking for default namespace
   1634                         return namespace;
   1635                     } else if (prefix != null && prefix.equals(specifiedPrefix)) {
   1636                         // non default namespace
   1637                         return namespace;
   1638                     }
   1639                 }
   1640                 if (this.hasAttributes()) {
   1641                     NamedNodeMap map = this.getAttributes();
   1642                     int length = map.getLength();
   1643                     for (int i=0;i<length;i++) {
   1644                         Node attr = map.item(i);
   1645                         String attrPrefix = attr.getPrefix();
   1646                         String value = attr.getNodeValue();
   1647                         namespace = attr.getNamespaceURI();
   1648                         if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
   1649                             // at this point we are dealing with DOM Level 2 nodes only
   1650                             if (specifiedPrefix == null &&
   1651                                 attr.getNodeName().equals("xmlns")) {
   1652                                 // default namespace
   1653                                 return value;
   1654                             } else if (attrPrefix !=null &&
   1655                                        attrPrefix.equals("xmlns") &&
   1656                                        attr.getLocalName().equals(specifiedPrefix)) {
   1657                  // non default namespace
   1658                                 return value;
   1659                             }
   1660                         }
   1661                     }
   1662                 }
   1663 		/*
   1664                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
   1665                 if (ancestor != null) {
   1666                     return ancestor.lookupNamespaceURI(specifiedPrefix);
   1667                 }
   1668 		*/
   1669                 return null;
   1670             }
   1671 /*
   1672         case Node.DOCUMENT_NODE : {
   1673                 return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ;
   1674             }
   1675 */
   1676         case Node.ENTITY_NODE :
   1677         case Node.NOTATION_NODE:
   1678         case Node.DOCUMENT_FRAGMENT_NODE:
   1679         case Node.DOCUMENT_TYPE_NODE:
   1680             // type is unknown
   1681             return null;
   1682         case Node.ATTRIBUTE_NODE:{
   1683                 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
   1684                     return getOwnerElement().lookupNamespaceURI(specifiedPrefix);
   1685                 }
   1686                 return null;
   1687             }
   1688         default:{
   1689 	   /*
   1690                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
   1691                 if (ancestor != null) {
   1692                     return ancestor.lookupNamespaceURI(specifiedPrefix);
   1693                 }
   1694              */
   1695                 return null;
   1696             }
   1697 
   1698         }
   1699     }
   1700 
   1701     /**
   1702      *  DOM Level 3:
   1703      *  This method checks if the specified <code>namespaceURI</code> is the
   1704      *  default namespace or not.
   1705      *  @param namespaceURI The namespace URI to look for.
   1706      *  @return  <code>true</code> if the specified <code>namespaceURI</code>
   1707      *   is the default namespace, <code>false</code> otherwise.
   1708      * @since DOM Level 3
   1709      */
   1710     public boolean isDefaultNamespace(String namespaceURI){
   1711        /*
   1712         // REVISIT: remove casts when DOM L3 becomes REC.
   1713         short type = this.getNodeType();
   1714         switch (type) {
   1715         case Node.ELEMENT_NODE: {
   1716             String namespace = this.getNamespaceURI();
   1717             String prefix = this.getPrefix();
   1718 
   1719             // REVISIT: is it possible that prefix is empty string?
   1720             if (prefix == null || prefix.length() == 0) {
   1721                 if (namespaceURI == null) {
   1722                     return (namespace == namespaceURI);
   1723                 }
   1724                 return namespaceURI.equals(namespace);
   1725             }
   1726             if (this.hasAttributes()) {
   1727                 ElementImpl elem = (ElementImpl)this;
   1728                 NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns");
   1729                 if (attr != null) {
   1730                     String value = attr.getNodeValue();
   1731                     if (namespaceURI == null) {
   1732                         return (namespace == value);
   1733                     }
   1734                     return namespaceURI.equals(value);
   1735                 }
   1736             }
   1737 
   1738             NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
   1739             if (ancestor != null) {
   1740                 return ancestor.isDefaultNamespace(namespaceURI);
   1741             }
   1742             return false;
   1743         }
   1744         case Node.DOCUMENT_NODE:{
   1745                 return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
   1746             }
   1747 
   1748         case Node.ENTITY_NODE :
   1749           case Node.NOTATION_NODE:
   1750         case Node.DOCUMENT_FRAGMENT_NODE:
   1751         case Node.DOCUMENT_TYPE_NODE:
   1752             // type is unknown
   1753             return false;
   1754         case Node.ATTRIBUTE_NODE:{
   1755                 if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) {
   1756                     return ownerNode.isDefaultNamespace(namespaceURI);
   1757 
   1758                 }
   1759                 return false;
   1760             }
   1761         default:{
   1762                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
   1763                 if (ancestor != null) {
   1764                     return ancestor.isDefaultNamespace(namespaceURI);
   1765                 }
   1766                 return false;
   1767             }
   1768 
   1769         }
   1770 */
   1771         return false;
   1772     }
   1773 
   1774     /**
   1775      * DOM Level 3:
   1776      * Look up the prefix associated to the given namespace URI, starting from this node.
   1777      *
   1778      * @param namespaceURI
   1779      * @return the prefix for the namespace
   1780      */
   1781     public String lookupPrefix(String namespaceURI){
   1782 
   1783         // REVISIT: When Namespaces 1.1 comes out this may not be true
   1784         // Prefix can't be bound to null namespace
   1785         if (namespaceURI == null) {
   1786             return null;
   1787         }
   1788 
   1789         short type = this.getNodeType();
   1790 
   1791         switch (type) {
   1792 /*
   1793         case Node.ELEMENT_NODE: {
   1794 
   1795                 String namespace = this.getNamespaceURI(); // to flip out children
   1796                 return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
   1797             }
   1798 
   1799         case Node.DOCUMENT_NODE:{
   1800                 return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
   1801             }
   1802 */
   1803         case Node.ENTITY_NODE :
   1804         case Node.NOTATION_NODE:
   1805         case Node.DOCUMENT_FRAGMENT_NODE:
   1806         case Node.DOCUMENT_TYPE_NODE:
   1807             // type is unknown
   1808             return null;
   1809         case Node.ATTRIBUTE_NODE:{
   1810                 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
   1811                     return getOwnerElement().lookupPrefix(namespaceURI);
   1812 
   1813                 }
   1814                 return null;
   1815             }
   1816         default:{
   1817 /*
   1818                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
   1819                 if (ancestor != null) {
   1820                     return ancestor.lookupPrefix(namespaceURI);
   1821                 }
   1822 */
   1823                 return null;
   1824             }
   1825          }
   1826     }
   1827 
   1828     /**
   1829      * Returns whether this node is the same node as the given one.
   1830      * <br>This method provides a way to determine whether two
   1831      * <code>Node</code> references returned by the implementation reference
   1832      * the same object. When two <code>Node</code> references are references
   1833      * to the same object, even if through a proxy, the references may be
   1834      * used completely interchangably, such that all attributes have the
   1835      * same values and calling the same DOM method on either reference
   1836      * always has exactly the same effect.
   1837      * @param other The node to test against.
   1838      * @return Returns <code>true</code> if the nodes are the same,
   1839      *   <code>false</code> otherwise.
   1840      * @since DOM Level 3
   1841      */
   1842     public boolean isSameNode(Node other) {
   1843         // we do not use any wrapper so the answer is obvious
   1844         return this == other;
   1845     }
   1846 
   1847     /**
   1848      * This attribute returns the text content of this node and its
   1849      * descendants. When it is defined to be null, setting it has no effect.
   1850      * When set, any possible children this node may have are removed and
   1851      * replaced by a single <code>Text</code> node containing the string
   1852      * this attribute is set to. On getting, no serialization is performed,
   1853      * the returned string does not contain any markup. No whitespace
   1854      * normalization is performed, the returned string does not contain the
   1855      * element content whitespaces . Similarly, on setting, no parsing is
   1856      * performed either, the input string is taken as pure textual content.
   1857      * <br>The string returned is made of the text content of this node
   1858      * depending on its type, as defined below:
   1859      * <table border='1'>
   1860      * <tr>
   1861      * <th>Node type</th>
   1862      * <th>Content</th>
   1863      * </tr>
   1864      * <tr>
   1865      * <td valign='top' rowspan='1' colspan='1'>
   1866      * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
   1867      * DOCUMENT_FRAGMENT_NODE</td>
   1868      * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
   1869      * attribute value of every child node, excluding COMMENT_NODE and
   1870      * PROCESSING_INSTRUCTION_NODE nodes</td>
   1871      * </tr>
   1872      * <tr>
   1873      * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
   1874      * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
   1875      * <td valign='top' rowspan='1' colspan='1'>
   1876      * <code>nodeValue</code></td>
   1877      * </tr>
   1878      * <tr>
   1879      * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
   1880      * <td valign='top' rowspan='1' colspan='1'>
   1881      * null</td>
   1882      * </tr>
   1883      * </table>
   1884      * @exception DOMException
   1885      *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
   1886      * @exception DOMException
   1887      *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
   1888      *   fit in a <code>DOMString</code> variable on the implementation
   1889      *   platform.
   1890      * @since DOM Level 3
   1891      */
   1892     public void setTextContent(String textContent)
   1893         throws DOMException {
   1894         setNodeValue(textContent);
   1895     }
   1896 
   1897     /**
   1898      * This attribute returns the text content of this node and its
   1899      * descendants. When it is defined to be null, setting it has no effect.
   1900      * When set, any possible children this node may have are removed and
   1901      * replaced by a single <code>Text</code> node containing the string
   1902      * this attribute is set to. On getting, no serialization is performed,
   1903      * the returned string does not contain any markup. No whitespace
   1904      * normalization is performed, the returned string does not contain the
   1905      * element content whitespaces . Similarly, on setting, no parsing is
   1906      * performed either, the input string is taken as pure textual content.
   1907      * <br>The string returned is made of the text content of this node
   1908      * depending on its type, as defined below:
   1909      * <table border='1'>
   1910      * <tr>
   1911      * <th>Node type</th>
   1912      * <th>Content</th>
   1913      * </tr>
   1914      * <tr>
   1915      * <td valign='top' rowspan='1' colspan='1'>
   1916      * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
   1917      * DOCUMENT_FRAGMENT_NODE</td>
   1918      * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
   1919      * attribute value of every child node, excluding COMMENT_NODE and
   1920      * PROCESSING_INSTRUCTION_NODE nodes</td>
   1921      * </tr>
   1922      * <tr>
   1923      * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
   1924      * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
   1925      * <td valign='top' rowspan='1' colspan='1'>
   1926      * <code>nodeValue</code></td>
   1927      * </tr>
   1928      * <tr>
   1929      * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
   1930      * <td valign='top' rowspan='1' colspan='1'>
   1931      * null</td>
   1932      * </tr>
   1933      * </table>
   1934      * @exception DOMException
   1935      *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
   1936      * @exception DOMException
   1937      *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
   1938      *   fit in a <code>DOMString</code> variable on the implementation
   1939      *   platform.
   1940      * @since DOM Level 3
   1941      */
   1942     public String getTextContent() throws DOMException {
   1943         return dtm.getStringValue(node).toString();
   1944     }
   1945 
   1946     /**
   1947      * Compares a node with this node with regard to their position in the
   1948      * document.
   1949      * @param other The node to compare against this node.
   1950      * @return Returns how the given node is positioned relatively to this
   1951      *   node.
   1952      * @since DOM Level 3
   1953      */
   1954     public short compareDocumentPosition(Node other) throws DOMException {
   1955         return 0;
   1956     }
   1957 
   1958     /**
   1959      * The absolute base URI of this node or <code>null</code> if undefined.
   1960      * This value is computed according to . However, when the
   1961      * <code>Document</code> supports the feature "HTML" , the base URI is
   1962      * computed using first the value of the href attribute of the HTML BASE
   1963      * element if any, and the value of the <code>documentURI</code>
   1964      * attribute from the <code>Document</code> interface otherwise.
   1965      * <br> When the node is an <code>Element</code>, a <code>Document</code>
   1966      * or a a <code>ProcessingInstruction</code>, this attribute represents
   1967      * the properties [base URI] defined in . When the node is a
   1968      * <code>Notation</code>, an <code>Entity</code>, or an
   1969      * <code>EntityReference</code>, this attribute represents the
   1970      * properties [declaration base URI] in the . How will this be affected
   1971      * by resolution of relative namespace URIs issue?It's not.Should this
   1972      * only be on Document, Element, ProcessingInstruction, Entity, and
   1973      * Notation nodes, according to the infoset? If not, what is it equal to
   1974      * on other nodes? Null? An empty string? I think it should be the
   1975      * parent's.No.Should this be read-only and computed or and actual
   1976      * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and
   1977      * teleconference 30 May 2001).If the base HTML element is not yet
   1978      * attached to a document, does the insert change the Document.baseURI?
   1979      * Yes. (F2F 26 Sep 2001)
   1980      * @since DOM Level 3
   1981      */
   1982     public String getBaseURI() {
   1983         return null;
   1984     }
   1985 
   1986     /**
   1987      * DOM Level 3
   1988      * Renaming node
   1989      */
   1990     public Node renameNode(Node n,
   1991                            String namespaceURI,
   1992                            String name)
   1993                            throws DOMException{
   1994         return n;
   1995     }
   1996 
   1997     /**
   1998      *  DOM Level 3
   1999      *  Normalize document.
   2000      */
   2001     public void normalizeDocument(){
   2002 
   2003     }
   2004 
   2005     /**
   2006      *  The configuration used when <code>Document.normalizeDocument</code> is
   2007      * invoked.
   2008      * @since DOM Level 3
   2009      */
   2010     public DOMConfiguration getDomConfig(){
   2011        return null;
   2012     }
   2013 
   2014     /** DOM Level 3 feature: documentURI */
   2015     protected String fDocumentURI;
   2016 
   2017     /**
   2018      * DOM Level 3
   2019      */
   2020     public void setDocumentURI(String documentURI){
   2021 
   2022         fDocumentURI= documentURI;
   2023     }
   2024 
   2025     /**
   2026      * DOM Level 3
   2027      * The location of the document or <code>null</code> if undefined.
   2028      * <br>Beware that when the <code>Document</code> supports the feature
   2029      * "HTML" , the href attribute of the HTML BASE element takes precedence
   2030      * over this attribute.
   2031      * @since DOM Level 3
   2032      */
   2033     public String getDocumentURI(){
   2034         return fDocumentURI;
   2035     }
   2036 
   2037     /** DOM Level 3 feature: Document actualEncoding */
   2038     protected String actualEncoding;
   2039 
   2040     /**
   2041      * DOM Level 3
   2042      * An attribute specifying the actual encoding of this document. This is
   2043      * <code>null</code> otherwise.
   2044      * <br> This attribute represents the property [character encoding scheme]
   2045      * defined in .
   2046      * @since DOM Level 3
   2047      */
   2048     public String getActualEncoding() {
   2049         return actualEncoding;
   2050     }
   2051 
   2052     /**
   2053      * DOM Level 3
   2054      * An attribute specifying the actual encoding of this document. This is
   2055      * <code>null</code> otherwise.
   2056      * <br> This attribute represents the property [character encoding scheme]
   2057      * defined in .
   2058      * @since DOM Level 3
   2059      */
   2060     public void setActualEncoding(String value) {
   2061         actualEncoding = value;
   2062     }
   2063 
   2064    /**
   2065     * DOM Level 3
   2066     */
   2067     public Text replaceWholeText(String content)
   2068                                  throws DOMException{
   2069 /*
   2070 
   2071         if (needsSyncData()) {
   2072             synchronizeData();
   2073         }
   2074 
   2075         // make sure we can make the replacement
   2076         if (!canModify(nextSibling)) {
   2077             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
   2078                 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
   2079         }
   2080 
   2081         Node parent = this.getParentNode();
   2082         if (content == null || content.length() == 0) {
   2083             // remove current node
   2084             if (parent !=null) { // check if node in the tree
   2085                 parent.removeChild(this);
   2086                 return null;
   2087             }
   2088         }
   2089         Text currentNode = null;
   2090         if (isReadOnly()){
   2091             Text newNode = this.ownerDocument().createTextNode(content);
   2092             if (parent !=null) { // check if node in the tree
   2093                 parent.insertBefore(newNode, this);
   2094                 parent.removeChild(this);
   2095                 currentNode = newNode;
   2096             } else {
   2097                 return newNode;
   2098             }
   2099         }  else {
   2100             this.setData(content);
   2101             currentNode = this;
   2102         }
   2103         Node sibling =  currentNode.getNextSibling();
   2104         while ( sibling !=null) {
   2105             parent.removeChild(sibling);
   2106             sibling = currentNode.getNextSibling();
   2107         }
   2108 
   2109         return currentNode;
   2110 */
   2111         return null; //Pending
   2112     }
   2113 
   2114     /**
   2115      * DOM Level 3
   2116      * Returns all text of <code>Text</code> nodes logically-adjacent text
   2117      * nodes to this node, concatenated in document order.
   2118      * @since DOM Level 3
   2119      */
   2120     public String getWholeText(){
   2121 
   2122 /*
   2123         if (needsSyncData()) {
   2124             synchronizeData();
   2125         }
   2126         if (nextSibling == null) {
   2127             return data;
   2128         }
   2129         StringBuffer buffer = new StringBuffer();
   2130         if (data != null && data.length() != 0) {
   2131             buffer.append(data);
   2132         }
   2133         getWholeText(nextSibling, buffer);
   2134         return buffer.toString();
   2135 */
   2136         return null; // PENDING
   2137     }
   2138 
   2139     /**
   2140      * DOM Level 3
   2141      * Returns whether this text node contains whitespace in element content,
   2142      * often abusively called "ignorable whitespace".
   2143      */
   2144     public boolean isElementContentWhitespace(){
   2145         return false;
   2146     }
   2147 
   2148     /**
   2149      * NON-DOM: set the type of this attribute to be ID type.
   2150      *
   2151      * @param id
   2152      */
   2153     public void setIdAttribute(boolean id){
   2154         //PENDING
   2155     }
   2156 
   2157     /**
   2158      * DOM Level 3: register the given attribute node as an ID attribute
   2159      */
   2160     public void setIdAttribute(String name, boolean makeId) {
   2161         //PENDING
   2162     }
   2163 
   2164 
   2165     /**
   2166      * DOM Level 3: register the given attribute node as an ID attribute
   2167      */
   2168     public void setIdAttributeNode(Attr at, boolean makeId) {
   2169         //PENDING
   2170     }
   2171 
   2172     /**
   2173      * DOM Level 3: register the given attribute node as an ID attribute
   2174      */
   2175     public void setIdAttributeNS(String namespaceURI, String localName,
   2176                                     boolean makeId) {
   2177         //PENDING
   2178     }
   2179 
   2180     public TypeInfo getSchemaTypeInfo(){
   2181       return null; //PENDING
   2182     }
   2183 
   2184     public boolean isId() {
   2185         return false; //PENDING
   2186     }
   2187 
   2188 
   2189     private String xmlEncoding;
   2190 
   2191     public String getXmlEncoding( ) {
   2192         return xmlEncoding;
   2193     }
   2194 
   2195     public void setXmlEncoding( String xmlEncoding ) {
   2196         this.xmlEncoding = xmlEncoding;
   2197     }
   2198 
   2199     private boolean xmlStandalone;
   2200 
   2201     public boolean getXmlStandalone() {
   2202         return xmlStandalone;
   2203     }
   2204 
   2205     public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
   2206         this.xmlStandalone = xmlStandalone;
   2207     }
   2208 
   2209     private String xmlVersion;
   2210 
   2211     public String getXmlVersion() {
   2212         return xmlVersion;
   2213     }
   2214 
   2215     public void setXmlVersion(String xmlVersion) throws DOMException {
   2216         this.xmlVersion = xmlVersion;
   2217     }
   2218 }
   2219