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