1 /*
2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3  */
4 /*
5  * Licensed to the Apache Software Foundation (ASF) under one or more
6  * contributor license agreements.  See the NOTICE file distributed with
7  * this work for additional information regarding copyright ownership.
8  * The ASF licenses this file to You under the Apache License, Version 2.0
9  * (the "License"); you may not use this file except in compliance with
10  * the License.  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 
24 package com.sun.org.apache.xml.internal.dtm.ref;
25 
26 import com.sun.org.apache.xml.internal.dtm.DTM;
27 import com.sun.org.apache.xml.internal.dtm.DTMDOMException;
28 import com.sun.org.apache.xpath.internal.NodeSet;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Objects;
32 import org.w3c.dom.Attr;
33 import org.w3c.dom.CDATASection;
34 import org.w3c.dom.Comment;
35 import org.w3c.dom.DOMConfiguration;
36 import org.w3c.dom.DOMException;
37 import org.w3c.dom.DOMImplementation;
38 import org.w3c.dom.Document;
39 import org.w3c.dom.DocumentFragment;
40 import org.w3c.dom.DocumentType;
41 import org.w3c.dom.Element;
42 import org.w3c.dom.EntityReference;
43 import org.w3c.dom.NamedNodeMap;
44 import org.w3c.dom.Node;
45 import org.w3c.dom.NodeList;
46 import org.w3c.dom.ProcessingInstruction;
47 import org.w3c.dom.Text;
48 import org.w3c.dom.TypeInfo;
49 import org.w3c.dom.UserDataHandler;
50 
51 /**
52  * <code>DTMNodeProxy</code> presents a DOM Node API front-end to the DTM model.
53  * <p>
54  * It does _not_ attempt to address the "node identity" question; no effort
55  * is made to prevent the creation of multiple proxies referring to a single
56  * DTM node. Users can create a mechanism for managing this, or relinquish the
57  * use of "==" and use the .sameNodeAs() mechanism, which is under
58  * consideration for future versions of the DOM.
59  * <p>
60  * DTMNodeProxy may be subclassed further to present specific DOM node types.
61  *
62  * @see org.w3c.dom
63  * @LastModified: Nov 2017
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    */
DTMNodeProxy(DTM dtm, int node)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    */
getDTM()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    */
getDTMNodeNumber()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    */
equals(Node node)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
equals(Object node)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
hashCode()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    */
sameNodeAs(Node other)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
getNodeName()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
getTarget()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
getLocalName()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
getPrefix()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
setPrefix(String prefix)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
getNamespaceURI()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    */
supports(String feature, String version)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
isSupported(String feature, String version)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
getNodeValue()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    */
getStringValue()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
setNodeValue(String nodeValue)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
getNodeType()336   public final short getNodeType()
337   {
338     return dtm.getNodeType(node);
339   }
340 
341   /**
342    *
343    *
344    * @see org.w3c.dom.Node
345    */
346   @Override
getParentNode()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    */
getOwnerNode()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
getChildNodes()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
getFirstChild()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
getLastChild()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
getPreviousSibling()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
getNextSibling()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
getAttributes()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
hasAttribute(String name)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
hasAttributeNS(String namespaceURI, String localName)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
getOwnerDocument()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
insertBefore(Node newChild, Node refChild)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
replaceChild(Node newChild, Node oldChild)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
removeChild(Node oldChild)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
appendChild(Node newChild)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
hasChildNodes()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
cloneNode(boolean deep)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
getDoctype()596   public final DocumentType getDoctype()
597   {
598     return null;
599   }
600 
601   /**
602    *
603    *
604    * @see org.w3c.dom.Document
605    */
606   @Override
getImplementation()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
getDocumentElement()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
createElement(String tagName)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
createDocumentFragment()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
createTextNode(String data)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
createComment(String data)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
createCDATASection(String data)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
createProcessingInstruction( String target, String data)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
createAttribute(String name)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
createEntityReference(String name)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
getElementsByTagName(String tagname)781   public final NodeList getElementsByTagName(String tagname)
782   {
783        List<Node> listVector = new ArrayList<>();
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(listVector.get(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    */
traverseChildren(List<Node> listVector, Node tempNode, String tagname, boolean isTagNameWildCard)820   private final void traverseChildren(List<Node> listVector, Node tempNode,
821           String tagname, boolean isTagNameWildCard) {
822     if (tempNode == null)
823     {
824       return;
825     }
826     else
827     {
828       if (tempNode.getNodeType() == DTM.ELEMENT_NODE
829             && (isTagNameWildCard || tempNode.getNodeName().equals(tagname)))
830       {
831         listVector.add(tempNode);
832       }
833       if(tempNode.hasChildNodes())
834       {
835         NodeList nodeList = tempNode.getChildNodes();
836         for (int i = 0; i < nodeList.getLength(); i++)
837         {
838           traverseChildren(listVector, nodeList.item(i), tagname,
839                            isTagNameWildCard);
840         }
841       }
842     }
843   }
844 
845 
846 
847   /**
848    *
849    * @param importedNode
850    * @param deep
851    *
852    *
853    *
854    * @throws DOMException
855    * @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only
856    */
857   @Override
importNode(Node importedNode, boolean deep)858   public final Node importNode(Node importedNode, boolean deep)
859     throws DOMException
860   {
861     throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
862   }
863 
864   /**
865    *
866    * @param namespaceURI
867    * @param qualifiedName
868    *
869    *
870    *
871    * @throws DOMException
872    * @see org.w3c.dom.Document as of DOM Level 2
873    */
874   @Override
createElementNS( String namespaceURI, String qualifiedName)875   public final Element createElementNS(
876                  String namespaceURI, String qualifiedName) throws DOMException
877   {
878     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
879   }
880 
881   /**
882    *
883    * @param namespaceURI
884    * @param qualifiedName
885    *
886    *
887    *
888    * @throws DOMException
889    * @see org.w3c.dom.Document as of DOM Level 2
890    */
891   @Override
createAttributeNS( String namespaceURI, String qualifiedName)892   public final Attr createAttributeNS(
893                   String namespaceURI, String qualifiedName) throws DOMException
894   {
895     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
896   }
897 
898    /**
899    *
900    * @param namespaceURI
901    * @param localName
902    *
903    *
904    * @see org.w3c.dom.Document as of DOM Level 2
905    */
906   @Override
getElementsByTagNameNS(String namespaceURI, String localName)907   public final NodeList getElementsByTagNameNS(String namespaceURI,
908                                                String localName)
909   {
910     List<Node> listVector = new ArrayList<>();
911     Node retNode = dtm.getNode(node);
912     if (retNode != null)
913     {
914       boolean isNamespaceURIWildCard = "*".equals(namespaceURI);
915       boolean isLocalNameWildCard    = "*".equals(localName);
916       if (DTM.ELEMENT_NODE == retNode.getNodeType())
917       {
918         NodeList nodeList = retNode.getChildNodes();
919         for(int i = 0; i < nodeList.getLength(); i++)
920         {
921           traverseChildren(listVector, nodeList.item(i), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard);
922         }
923       }
924       else if(DTM.DOCUMENT_NODE == retNode.getNodeType())
925       {
926         traverseChildren(listVector, dtm.getNode(node), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard);
927       }
928     }
929     int size = listVector.size();
930     NodeSet nodeSet = new NodeSet(size);
931     for (int i = 0; i < size; i++)
932     {
933       nodeSet.addNode(listVector.get(i));
934     }
935     return (NodeList) nodeSet;
936   }
937   /**
938    *
939    * @param listVector
940    * @param tempNode
941    * @param namespaceURI
942    * @param localname
943    * @param isNamespaceURIWildCard
944    * @param isLocalNameWildCard
945    *
946    * Private method to be used for recursive iterations to obtain elements by tag name
947    * and namespaceURI.
948    */
traverseChildren(List<Node> listVector, Node tempNode, String namespaceURI, String localname, boolean isNamespaceURIWildCard, boolean isLocalNameWildCard)949   private final void traverseChildren(List<Node> listVector, Node tempNode,
950           String namespaceURI, String localname, boolean isNamespaceURIWildCard,
951           boolean isLocalNameWildCard)
952    {
953     if (tempNode == null)
954     {
955       return;
956     }
957     else
958     {
959       if (tempNode.getNodeType() == DTM.ELEMENT_NODE
960               && (isLocalNameWildCard
961                       || tempNode.getLocalName().equals(localname)))
962       {
963         String nsURI = tempNode.getNamespaceURI();
964         if ((namespaceURI == null && nsURI == null)
965                || isNamespaceURIWildCard
966                || (namespaceURI != null && namespaceURI.equals(nsURI)))
967         {
968           listVector.add(tempNode);
969         }
970       }
971       if(tempNode.hasChildNodes())
972       {
973         NodeList nl = tempNode.getChildNodes();
974         for(int i = 0; i < nl.getLength(); i++)
975         {
976           traverseChildren(listVector, nl.item(i), namespaceURI, localname,
977                            isNamespaceURIWildCard, isLocalNameWildCard);
978         }
979       }
980     }
981   }
982   /**
983    *
984    * @param elementId
985    *
986    *
987    * @see org.w3c.dom.Document as of DOM Level 2
988    */
989   @Override
getElementById(String elementId)990   public final Element getElementById(String elementId)
991   {
992        return (Element) dtm.getNode(dtm.getElementById(elementId));
993   }
994 
995   /**
996    *
997    * @param offset
998    *
999    *
1000    *
1001    * @throws DOMException
1002    * @see org.w3c.dom.Text
1003    */
1004   @Override
splitText(int offset)1005   public final Text splitText(int offset) throws DOMException
1006   {
1007     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1008   }
1009 
1010   /**
1011    *
1012    *
1013    *
1014    * @throws DOMException
1015    * @see org.w3c.dom.CharacterData
1016    */
1017   @Override
getData()1018   public final String getData() throws DOMException
1019   {
1020     return dtm.getNodeValue(node);
1021   }
1022 
1023   /**
1024    *
1025    * @param data
1026    *
1027    * @throws DOMException
1028    * @see org.w3c.dom.CharacterData
1029    */
1030   @Override
setData(String data)1031   public final void setData(String data) throws DOMException
1032   {
1033     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1034   }
1035 
1036   /**
1037    *
1038    *
1039    * @see org.w3c.dom.CharacterData
1040    */
1041   @Override
getLength()1042   public final int getLength()
1043   {
1044     // %OPT% This should do something smarter?
1045     return dtm.getNodeValue(node).length();
1046   }
1047 
1048   /**
1049    *
1050    * @param offset
1051    * @param count
1052    *
1053    *
1054    *
1055    * @throws DOMException
1056    * @see org.w3c.dom.CharacterData
1057    */
1058   @Override
substringData(int offset, int count)1059   public final String substringData(int offset, int count) throws DOMException
1060   {
1061     return getData().substring(offset,offset+count);
1062   }
1063 
1064   /**
1065    *
1066    * @param arg
1067    *
1068    * @throws DOMException
1069    * @see org.w3c.dom.CharacterData
1070    */
1071   @Override
appendData(String arg)1072   public final void appendData(String arg) throws DOMException
1073   {
1074     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1075   }
1076 
1077   /**
1078    *
1079    * @param offset
1080    * @param arg
1081    *
1082    * @throws DOMException
1083    * @see org.w3c.dom.CharacterData
1084    */
1085   @Override
insertData(int offset, String arg)1086   public final void insertData(int offset, String arg) throws DOMException
1087   {
1088     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1089   }
1090 
1091   /**
1092    *
1093    * @param offset
1094    * @param count
1095    *
1096    * @throws DOMException
1097    * @see org.w3c.dom.CharacterData
1098    */
1099   @Override
deleteData(int offset, int count)1100   public final void deleteData(int offset, int count) throws DOMException
1101   {
1102     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1103   }
1104 
1105   /**
1106    *
1107    * @param offset
1108    * @param count
1109    * @param arg
1110    *
1111    * @throws DOMException
1112    * @see org.w3c.dom.CharacterData
1113    */
1114   @Override
replaceData(int offset, int count, String arg)1115   public final void replaceData(int offset, int count, String arg)
1116     throws DOMException
1117   {
1118     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1119   }
1120 
1121   /**
1122    *
1123    *
1124    * @see org.w3c.dom.Element
1125    */
1126   @Override
getTagName()1127   public final String getTagName()
1128   {
1129     return dtm.getNodeName(node);
1130   }
1131 
1132   /**
1133    *
1134    * @param name
1135    *
1136    *
1137    * @see org.w3c.dom.Element
1138    */
1139   @Override
getAttribute(String name)1140   public final String getAttribute(String name)
1141   {
1142     DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
1143     Node n = map.getNamedItem(name);
1144     return (null == n) ? EMPTYSTRING : n.getNodeValue();
1145   }
1146 
1147   /**
1148    *
1149    * @param name
1150    * @param value
1151    *
1152    * @throws DOMException
1153    * @see org.w3c.dom.Element
1154    */
1155   @Override
setAttribute(String name, String value)1156   public final void setAttribute(String name, String value)
1157     throws DOMException
1158   {
1159     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1160   }
1161 
1162   /**
1163    *
1164    * @param name
1165    *
1166    * @throws DOMException
1167    * @see org.w3c.dom.Element
1168    */
1169   @Override
removeAttribute(String name)1170   public final void removeAttribute(String name) throws DOMException
1171   {
1172     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1173   }
1174 
1175   /**
1176    *
1177    * @param name
1178    *
1179    *
1180    * @see org.w3c.dom.Element
1181    */
1182   @Override
getAttributeNode(String name)1183   public final Attr getAttributeNode(String name)
1184   {
1185     DTMNamedNodeMap  map = new DTMNamedNodeMap(dtm, node);
1186     return (Attr)map.getNamedItem(name);
1187   }
1188 
1189   /**
1190    *
1191    * @param newAttr
1192    *
1193    *
1194    *
1195    * @throws DOMException
1196    * @see org.w3c.dom.Element
1197    */
1198   @Override
setAttributeNode(Attr newAttr)1199   public final Attr setAttributeNode(Attr newAttr) throws DOMException
1200   {
1201     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1202   }
1203 
1204   /**
1205    *
1206    * @param oldAttr
1207    *
1208    *
1209    *
1210    * @throws DOMException
1211    * @see org.w3c.dom.Element
1212    */
1213   @Override
removeAttributeNode(Attr oldAttr)1214   public final Attr removeAttributeNode(Attr oldAttr) throws DOMException
1215   {
1216     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1217   }
1218 
1219   /**
1220    * Introduced in DOM Level 2.
1221    *
1222    *
1223    */
1224   @Override
hasAttributes()1225   public boolean hasAttributes()
1226   {
1227     return DTM.NULL != dtm.getFirstAttribute(node);
1228   }
1229 
1230   /** @see org.w3c.dom.Element */
1231   @Override
normalize()1232   public final void normalize()
1233   {
1234     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1235   }
1236 
1237   /**
1238    *
1239    * @param namespaceURI
1240    * @param localName
1241    *
1242    *
1243    * @see org.w3c.dom.Element
1244    */
1245   @Override
getAttributeNS(String namespaceURI, String localName)1246   public final String getAttributeNS(String namespaceURI, String localName)
1247   {
1248     Node retNode = null;
1249     int n = dtm.getAttributeNode(node,namespaceURI,localName);
1250     if(n != DTM.NULL)
1251             retNode = dtm.getNode(n);
1252     return (null == retNode) ? EMPTYSTRING : retNode.getNodeValue();
1253   }
1254 
1255   /**
1256    *
1257    * @param namespaceURI
1258    * @param qualifiedName
1259    * @param value
1260    *
1261    * @throws DOMException
1262    * @see org.w3c.dom.Element
1263    */
1264   @Override
setAttributeNS( String namespaceURI, String qualifiedName, String value)1265   public final void setAttributeNS(
1266                                    String namespaceURI, String qualifiedName, String value)
1267     throws DOMException
1268   {
1269     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1270   }
1271 
1272   /**
1273    *
1274    * @param namespaceURI
1275    * @param localName
1276    *
1277    * @throws DOMException
1278    * @see org.w3c.dom.Element
1279    */
1280   @Override
removeAttributeNS(String namespaceURI, String localName)1281   public final void removeAttributeNS(String namespaceURI, String localName)
1282     throws DOMException
1283   {
1284     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1285   }
1286 
1287   /**
1288    *
1289    * @param namespaceURI
1290    * @param localName
1291    *
1292    *
1293    * @see org.w3c.dom.Element
1294    */
1295   @Override
getAttributeNodeNS(String namespaceURI, String localName)1296   public final Attr getAttributeNodeNS(String namespaceURI, String localName)
1297   {
1298        Attr retAttr = null;
1299        int n = dtm.getAttributeNode(node,namespaceURI,localName);
1300        if(n != DTM.NULL)
1301                retAttr = (Attr) dtm.getNode(n);
1302        return retAttr;
1303 
1304   }
1305 
1306   /**
1307    *
1308    * @param newAttr
1309    *
1310    *
1311    *
1312    * @throws DOMException
1313    * @see org.w3c.dom.Element
1314    */
1315   @Override
setAttributeNodeNS(Attr newAttr)1316   public final Attr setAttributeNodeNS(Attr newAttr) throws DOMException
1317   {
1318     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1319   }
1320 
1321   /**
1322    *
1323    *
1324    * @see org.w3c.dom.Attr
1325    */
1326   @Override
getName()1327   public final String getName()
1328   {
1329     return dtm.getNodeName(node);
1330   }
1331 
1332   /**
1333    *
1334    *
1335    * @see org.w3c.dom.Attr
1336    */
1337   @Override
getSpecified()1338   public final boolean getSpecified()
1339   {
1340     // We really don't know which attributes might have come from the
1341     // source document versus from the DTD. Treat them all as having
1342     // been provided by the user.
1343     // %REVIEW% if/when we become aware of DTDs/schemae.
1344     return true;
1345   }
1346 
1347   /**
1348    *
1349    *
1350    * @see org.w3c.dom.Attr
1351    */
1352   @Override
getValue()1353   public final String getValue()
1354   {
1355     return dtm.getNodeValue(node);
1356   }
1357 
1358   /**
1359    *
1360    * @param value
1361    * @see org.w3c.dom.Attr
1362    */
1363   @Override
setValue(String value)1364   public final void setValue(String value)
1365   {
1366     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1367   }
1368 
1369   /**
1370    * Get the owner element of an attribute.
1371    *
1372    *
1373    * @see org.w3c.dom.Attr as of DOM Level 2
1374    */
1375   @Override
getOwnerElement()1376   public final Element getOwnerElement()
1377   {
1378     if (getNodeType() != Node.ATTRIBUTE_NODE)
1379       return null;
1380     // In XPath and DTM data models, unlike DOM, an Attr's parent is its
1381     // owner element.
1382     int newnode = dtm.getParent(node);
1383     return (newnode == DTM.NULL) ? null : (Element)(dtm.getNode(newnode));
1384   }
1385 
1386   /**
1387    * NEEDSDOC Method adoptNode
1388    *
1389    *
1390    * NEEDSDOC @param source
1391    *
1392    * NEEDSDOC (adoptNode) @return
1393    *
1394    * @throws DOMException
1395    */
1396   @Override
adoptNode(Node source)1397   public Node adoptNode(Node source) throws DOMException
1398   {
1399     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1400   }
1401 
1402   /**
1403    * <p>EXPERIMENTAL! Based on the <a
1404    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1405    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1406    * <p>
1407    * An attribute specifying, as part of the XML declaration, the encoding
1408    * of this document. This is <code>null</code> when unspecified.
1409    * @since DOM Level 3
1410    *
1411    * NEEDSDOC ($objectName$) @return
1412    */
1413   @Override
getInputEncoding()1414   public String getInputEncoding()
1415   {
1416     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1417   }
1418 
1419   /**
1420    * <p>EXPERIMENTAL! Based on the <a
1421    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1422    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1423    * <p>
1424    * An attribute specifying, as part of the XML declaration, the encoding
1425    * of this document. This is <code>null</code> when unspecified.
1426    * @since DOM Level 3
1427    *
1428    * NEEDSDOC @param encoding
1429    */
setEncoding(String encoding)1430   public void setEncoding(String encoding)
1431   {
1432     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1433   }
1434 
1435   /**
1436    * <p>EXPERIMENTAL! Based on the <a
1437    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1438    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1439    * <p>
1440    * An attribute specifying, as part of the XML declaration, whether this
1441    * document is standalone.
1442    * @since DOM Level 3
1443    *
1444    * NEEDSDOC ($objectName$) @return
1445    */
getStandalone()1446   public boolean getStandalone()
1447   {
1448     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1449   }
1450 
1451   /**
1452    * <p>EXPERIMENTAL! Based on the <a
1453    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1454    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1455    * <p>
1456    * An attribute specifying, as part of the XML declaration, whether this
1457    * document is standalone.
1458    * @since DOM Level 3
1459    *
1460    * NEEDSDOC @param standalone
1461    */
setStandalone(boolean standalone)1462   public void setStandalone(boolean standalone)
1463   {
1464     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1465   }
1466 
1467   /**
1468    * <p>EXPERIMENTAL! Based on the <a
1469    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1470    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1471    * <p>
1472    * An attribute specifying whether errors checking is enforced or not.
1473    * When set to <code>false</code>, the implementation is free to not
1474    * test every possible error case normally defined on DOM operations,
1475    * and not raise any <code>DOMException</code>. In case of error, the
1476    * behavior is undefined. This attribute is <code>true</code> by
1477    * defaults.
1478    * @since DOM Level 3
1479    *
1480    * NEEDSDOC ($objectName$) @return
1481    */
1482   @Override
getStrictErrorChecking()1483   public boolean getStrictErrorChecking()
1484   {
1485     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1486   }
1487 
1488   /**
1489    * <p>EXPERIMENTAL! Based on the <a
1490    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1491    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1492    * <p>
1493    * An attribute specifying whether errors checking is enforced or not.
1494    * When set to <code>false</code>, the implementation is free to not
1495    * test every possible error case normally defined on DOM operations,
1496    * and not raise any <code>DOMException</code>. In case of error, the
1497    * behavior is undefined. This attribute is <code>true</code> by
1498    * defaults.
1499    * @since DOM Level 3
1500    *
1501    * NEEDSDOC @param strictErrorChecking
1502    */
1503   @Override
setStrictErrorChecking(boolean strictErrorChecking)1504   public void setStrictErrorChecking(boolean strictErrorChecking)
1505   {
1506     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1507   }
1508 
1509   /**
1510    * <p>EXPERIMENTAL! Based on the <a
1511    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1512    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1513    * <p>
1514    * An attribute specifying, as part of the XML declaration, the version
1515    * number of this document. This is <code>null</code> when unspecified.
1516    * @since DOM Level 3
1517    *
1518    * NEEDSDOC ($objectName$) @return
1519    */
getVersion()1520   public String getVersion()
1521   {
1522     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1523   }
1524 
1525   /**
1526    * <p>EXPERIMENTAL! Based on the <a
1527    * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
1528    * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>.
1529    * <p>
1530    * An attribute specifying, as part of the XML declaration, the version
1531    * number of this document. This is <code>null</code> when unspecified.
1532    * @since DOM Level 3
1533    *
1534    * NEEDSDOC @param version
1535    */
setVersion(String version)1536   public void setVersion(String version)
1537   {
1538     throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1539   }
1540 
1541 
1542   /** Inner class to support getDOMImplementation.
1543    */
1544   static class DTMNodeProxyImplementation implements DOMImplementation
1545   {
1546     @Override
createDocumentType(String qualifiedName,String publicId, String systemId)1547     public DocumentType createDocumentType(String qualifiedName,String publicId, String systemId)
1548     {
1549       throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1550     }
1551     @Override
createDocument(String namespaceURI,String qualfiedName,DocumentType doctype)1552     public Document createDocument(String namespaceURI,String qualfiedName,DocumentType doctype)
1553     {
1554       // Could create a DTM... but why, when it'd have to be permanantly empty?
1555       throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1556     }
1557     /** Ask whether we support a given DOM feature.
1558      *
1559      * In fact, we do not _fully_ support any DOM feature -- we're a
1560      * read-only subset -- so arguably we should always return false.
1561      * On the other hand, it may be more practically useful to return
1562      * true and simply treat the whole DOM as read-only, failing on the
1563      * methods we can't support. I'm not sure which would be more useful
1564      * to the caller.
1565      */
1566     @Override
hasFeature(String feature,String version)1567     public boolean hasFeature(String feature,String version)
1568     {
1569       if( ("CORE".equals(feature.toUpperCase()) || "XML".equals(feature.toUpperCase()))
1570                                         &&
1571           ("1.0".equals(version) || "2.0".equals(version)))
1572         return true;
1573       return false;
1574     }
1575 
1576     /**
1577      *  This method returns a specialized object which implements the
1578      * specialized APIs of the specified feature and version. The
1579      * specialized object may also be obtained by using binding-specific
1580      * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations
1581 .
1582      * @param feature The name of the feature requested (case-insensitive).
1583      * @param version  This is the version number of the feature to test. If
1584      *   the version is <code>null</code> or the empty string, supporting
1585      *   any version of the feature will cause the method to return an
1586      *   object that supports at least one version of the feature.
1587      * @return  Returns an object which implements the specialized APIs of
1588      *   the specified feature and version, if any, or <code>null</code> if
1589      *   there is no object which implements interfaces associated with that
1590      *   feature. If the <code>DOMObject</code> returned by this method
1591      *   implements the <code>Node</code> interface, it must delegate to the
1592      *   primary core <code>Node</code> and not return results inconsistent
1593      *   with the primary core <code>Node</code> such as attributes,
1594      *   childNodes, etc.
1595      * @since DOM Level 3
1596      */
1597     @Override
getFeature(String feature, String version)1598     public Object getFeature(String feature, String version) {
1599         // we don't have any alternate node, either this node does the job
1600         // or we don't have anything that does
1601         //return hasFeature(feature, version) ? this : null;
1602         return null; //PENDING
1603     }
1604 
1605   }
1606 
1607 
1608 //RAMESH : Pending proper implementation of DOM Level 3
1609 
1610     @Override
setUserData(String key, Object data, UserDataHandler handler)1611     public Object setUserData(String key,
1612                               Object data,
1613                               UserDataHandler handler) {
1614         return getOwnerDocument().setUserData( key, data, handler);
1615     }
1616 
1617     /**
1618      * Retrieves the object associated to a key on a this node. The object
1619      * must first have been set to this node by calling
1620      * <code>setUserData</code> with the same key.
1621      * @param key The key the object is associated to.
1622      * @return Returns the <code>DOMObject</code> associated to the given key
1623      *   on this node, or <code>null</code> if there was none.
1624      * @since DOM Level 3
1625      */
1626     @Override
getUserData(String key)1627     public Object getUserData(String key) {
1628         return getOwnerDocument().getUserData( key);
1629     }
1630 
1631       /**
1632      *  This method returns a specialized object which implements the
1633      * specialized APIs of the specified feature and version. The
1634      * specialized object may also be obtained by using binding-specific
1635      * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations.
1636      * @param feature The name of the feature requested (case-insensitive).
1637      * @param version  This is the version number of the feature to test. If
1638      *   the version is <code>null</code> or the empty string, supporting
1639      *   any version of the feature will cause the method to return an
1640      *   object that supports at least one version of the feature.
1641      * @return  Returns an object which implements the specialized APIs of
1642      *   the specified feature and version, if any, or <code>null</code> if
1643      *   there is no object which implements interfaces associated with that
1644      *   feature. If the <code>DOMObject</code> returned by this method
1645      *   implements the <code>Node</code> interface, it must delegate to the
1646      *   primary core <code>Node</code> and not return results inconsistent
1647      *   with the primary core <code>Node</code> such as attributes,
1648      *   childNodes, etc.
1649      * @since DOM Level 3
1650      */
1651     @Override
getFeature(String feature, String version)1652     public Object getFeature(String feature, String version) {
1653         // we don't have any alternate node, either this node does the job
1654         // or we don't have anything that does
1655         return isSupported(feature, version) ? this : null;
1656     }
1657 
1658     /**
1659      * Tests whether two nodes are equal.
1660      * <br>This method tests for equality of nodes, not sameness (i.e.,
1661      * whether the two nodes are references to the same object) which can be
1662      * tested with <code>Node.isSameNode</code>. All nodes that are the same
1663      * will also be equal, though the reverse may not be true.
1664      * <br>Two nodes are equal if and only if the following conditions are
1665      * satisfied: The two nodes are of the same type.The following string
1666      * attributes are equal: <code>nodeName</code>, <code>localName</code>,
1667      * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
1668      * , <code>baseURI</code>. This is: they are both <code>null</code>, or
1669      * they have the same length and are character for character identical.
1670      * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
1671      * This is: they are both <code>null</code>, or they have the same
1672      * length and for each node that exists in one map there is a node that
1673      * exists in the other map and is equal, although not necessarily at the
1674      * same index.The <code>childNodes</code> <code>NodeLists</code> are
1675      * equal. This is: they are both <code>null</code>, or they have the
1676      * same length and contain equal nodes at the same index. This is true
1677      * for <code>Attr</code> nodes as for any other type of node. Note that
1678      * normalization can affect equality; to avoid this, nodes should be
1679      * normalized before being compared.
1680      * <br>For two <code>DocumentType</code> nodes to be equal, the following
1681      * conditions must also be satisfied: The following string attributes
1682      * are equal: <code>publicId</code>, <code>systemId</code>,
1683      * <code>internalSubset</code>.The <code>entities</code>
1684      * <code>NamedNodeMaps</code> are equal.The <code>notations</code>
1685      * <code>NamedNodeMaps</code> are equal.
1686      * <br>On the other hand, the following do not affect equality: the
1687      * <code>ownerDocument</code> attribute, the <code>specified</code>
1688      * attribute for <code>Attr</code> nodes, the
1689      * <code>isWhitespaceInElementContent</code> attribute for
1690      * <code>Text</code> nodes, as well as any user data or event listeners
1691      * registered on the nodes.
1692      * @param arg The node to compare equality with.
1693      * @param deep If <code>true</code>, recursively compare the subtrees; if
1694      *   <code>false</code>, compare only the nodes themselves (and its
1695      *   attributes, if it is an <code>Element</code>).
1696      * @return If the nodes, and possibly subtrees are equal,
1697      *   <code>true</code> otherwise <code>false</code>.
1698      * @since DOM Level 3
1699      */
1700     @Override
isEqualNode(Node arg)1701     public boolean isEqualNode(Node arg) {
1702         if (arg == this) {
1703             return true;
1704         }
1705         if (arg.getNodeType() != getNodeType()) {
1706             return false;
1707         }
1708         // in theory nodeName can't be null but better be careful
1709         // who knows what other implementations may be doing?...
1710         if (getNodeName() == null) {
1711             if (arg.getNodeName() != null) {
1712                 return false;
1713             }
1714         }
1715         else if (!getNodeName().equals(arg.getNodeName())) {
1716             return false;
1717         }
1718 
1719         if (getLocalName() == null) {
1720             if (arg.getLocalName() != null) {
1721                 return false;
1722             }
1723         }
1724         else if (!getLocalName().equals(arg.getLocalName())) {
1725             return false;
1726         }
1727 
1728         if (getNamespaceURI() == null) {
1729             if (arg.getNamespaceURI() != null) {
1730                 return false;
1731             }
1732         }
1733         else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
1734             return false;
1735         }
1736 
1737         if (getPrefix() == null) {
1738             if (arg.getPrefix() != null) {
1739                 return false;
1740             }
1741         }
1742         else if (!getPrefix().equals(arg.getPrefix())) {
1743             return false;
1744         }
1745 
1746         if (getNodeValue() == null) {
1747             if (arg.getNodeValue() != null) {
1748                 return false;
1749             }
1750         }
1751         else if (!getNodeValue().equals(arg.getNodeValue())) {
1752             return false;
1753         }
1754     /*
1755         if (getBaseURI() == null) {
1756             if (((NodeImpl) arg).getBaseURI() != null) {
1757                 return false;
1758             }
1759         }
1760         else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) {
1761             return false;
1762         }
1763 */
1764 
1765              return true;
1766     }
1767 
1768       /**
1769      * DOM Level 3
1770      * Look up the namespace URI associated to the given prefix, starting from this node.
1771      * Use lookupNamespaceURI(null) to lookup the default namespace
1772      *
1773      * @param namespaceURI
1774      * @return th URI for the namespace
1775      * @since DOM Level 3
1776      */
1777     @Override
lookupNamespaceURI(String specifiedPrefix)1778     public String lookupNamespaceURI(String specifiedPrefix) {
1779         short type = this.getNodeType();
1780         switch (type) {
1781         case Node.ELEMENT_NODE : {
1782 
1783                 String namespace = this.getNamespaceURI();
1784                 String prefix = this.getPrefix();
1785                 if (namespace !=null) {
1786                     // REVISIT: is it possible that prefix is empty string?
1787                     if (specifiedPrefix== null && prefix==specifiedPrefix) {
1788                         // looking for default namespace
1789                         return namespace;
1790                     } else if (prefix != null && prefix.equals(specifiedPrefix)) {
1791                         // non default namespace
1792                         return namespace;
1793                     }
1794                 }
1795                 if (this.hasAttributes()) {
1796                     NamedNodeMap map = this.getAttributes();
1797                     int length = map.getLength();
1798                     for (int i=0;i<length;i++) {
1799                         Node attr = map.item(i);
1800                         String attrPrefix = attr.getPrefix();
1801                         String value = attr.getNodeValue();
1802                         namespace = attr.getNamespaceURI();
1803                         if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
1804                             // at this point we are dealing with DOM Level 2 nodes only
1805                             if (specifiedPrefix == null &&
1806                                 attr.getNodeName().equals("xmlns")) {
1807                                 // default namespace
1808                                 return value;
1809                             } else if (attrPrefix !=null &&
1810                                        attrPrefix.equals("xmlns") &&
1811                                        attr.getLocalName().equals(specifiedPrefix)) {
1812                  // non default namespace
1813                                 return value;
1814                             }
1815                         }
1816                     }
1817                 }
1818                 /*
1819                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1820                 if (ancestor != null) {
1821                     return ancestor.lookupNamespaceURI(specifiedPrefix);
1822                 }
1823                 */
1824 
1825                 return null;
1826 
1827 
1828             }
1829 /*
1830         case Node.DOCUMENT_NODE : {
1831                 return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ;
1832             }
1833 */
1834         case Node.ENTITY_NODE :
1835         case Node.NOTATION_NODE:
1836         case Node.DOCUMENT_FRAGMENT_NODE:
1837         case Node.DOCUMENT_TYPE_NODE:
1838             // type is unknown
1839             return null;
1840         case Node.ATTRIBUTE_NODE:{
1841                 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
1842                     return getOwnerElement().lookupNamespaceURI(specifiedPrefix);
1843 
1844                 }
1845                 return null;
1846             }
1847         default:{
1848            /*
1849                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1850                 if (ancestor != null) {
1851                     return ancestor.lookupNamespaceURI(specifiedPrefix);
1852                 }
1853              */
1854                 return null;
1855             }
1856 
1857         }
1858     }
1859 
1860 
1861     /**
1862      *  DOM Level 3
1863      *  This method checks if the specified <code>namespaceURI</code> is the
1864      *  default namespace or not.
1865      *  @param namespaceURI The namespace URI to look for.
1866      *  @return  <code>true</code> if the specified <code>namespaceURI</code>
1867      *   is the default namespace, <code>false</code> otherwise.
1868      * @since DOM Level 3
1869      */
1870     @Override
isDefaultNamespace(String namespaceURI)1871     public boolean isDefaultNamespace(String namespaceURI){
1872        /*
1873         // REVISIT: remove casts when DOM L3 becomes REC.
1874         short type = this.getNodeType();
1875         switch (type) {
1876         case Node.ELEMENT_NODE: {
1877             String namespace = this.getNamespaceURI();
1878             String prefix = this.getPrefix();
1879 
1880             // REVISIT: is it possible that prefix is empty string?
1881             if (prefix == null || prefix.length() == 0) {
1882                 if (namespaceURI == null) {
1883                     return (namespace == namespaceURI);
1884                 }
1885                 return namespaceURI.equals(namespace);
1886             }
1887             if (this.hasAttributes()) {
1888                 ElementImpl elem = (ElementImpl)this;
1889                 NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns");
1890                 if (attr != null) {
1891                     String value = attr.getNodeValue();
1892                     if (namespaceURI == null) {
1893                         return (namespace == value);
1894                     }
1895                     return namespaceURI.equals(value);
1896                 }
1897             }
1898 
1899             NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1900             if (ancestor != null) {
1901                 return ancestor.isDefaultNamespace(namespaceURI);
1902             }
1903             return false;
1904         }
1905         case Node.DOCUMENT_NODE:{
1906                 return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
1907             }
1908 
1909         case Node.ENTITY_NODE :
1910           case Node.NOTATION_NODE:
1911         case Node.DOCUMENT_FRAGMENT_NODE:
1912         case Node.DOCUMENT_TYPE_NODE:
1913             // type is unknown
1914             return false;
1915         case Node.ATTRIBUTE_NODE:{
1916                 if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) {
1917                     return ownerNode.isDefaultNamespace(namespaceURI);
1918 
1919                 }
1920                 return false;
1921             }
1922         default:{
1923                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1924                 if (ancestor != null) {
1925                     return ancestor.isDefaultNamespace(namespaceURI);
1926                 }
1927                 return false;
1928             }
1929 
1930         }
1931 */
1932         return false;
1933 
1934 
1935     }
1936 
1937       /**
1938      *
1939      * DOM Level 3
1940      * Look up the prefix associated to the given namespace URI, starting from this node.
1941      *
1942      * @param namespaceURI
1943      * @return the prefix for the namespace
1944      */
1945     @Override
lookupPrefix(String namespaceURI)1946     public String lookupPrefix(String namespaceURI){
1947 
1948         // REVISIT: When Namespaces 1.1 comes out this may not be true
1949         // Prefix can't be bound to null namespace
1950         if (namespaceURI == null) {
1951             return null;
1952         }
1953 
1954         short type = this.getNodeType();
1955 
1956         switch (type) {
1957 /*
1958         case Node.ELEMENT_NODE: {
1959 
1960                 String namespace = this.getNamespaceURI(); // to flip out children
1961                 return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
1962             }
1963 
1964         case Node.DOCUMENT_NODE:{
1965                 return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
1966             }
1967 */
1968         case Node.ENTITY_NODE :
1969         case Node.NOTATION_NODE:
1970         case Node.DOCUMENT_FRAGMENT_NODE:
1971         case Node.DOCUMENT_TYPE_NODE:
1972             // type is unknown
1973             return null;
1974         case Node.ATTRIBUTE_NODE:{
1975                 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
1976                     return getOwnerElement().lookupPrefix(namespaceURI);
1977 
1978                 }
1979                 return null;
1980             }
1981         default:{
1982 /*
1983                 NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1984                 if (ancestor != null) {
1985                     return ancestor.lookupPrefix(namespaceURI);
1986                 }
1987 */
1988                 return null;
1989             }
1990          }
1991     }
1992 
1993      /**
1994      * Returns whether this node is the same node as the given one.
1995      * <br>This method provides a way to determine whether two
1996      * <code>Node</code> references returned by the implementation reference
1997      * the same object. When two <code>Node</code> references are references
1998      * to the same object, even if through a proxy, the references may be
1999      * used completely interchangably, such that all attributes have the
2000      * same values and calling the same DOM method on either reference
2001      * always has exactly the same effect.
2002      * @param other The node to test against.
2003      * @return Returns <code>true</code> if the nodes are the same,
2004      *   <code>false</code> otherwise.
2005      * @since DOM Level 3
2006      */
2007     @Override
isSameNode(Node other)2008     public boolean isSameNode(Node other) {
2009         // we do not use any wrapper so the answer is obvious
2010         return this == other;
2011     }
2012 
2013       /**
2014      * This attribute returns the text content of this node and its
2015      * descendants. When it is defined to be null, setting it has no effect.
2016      * When set, any possible children this node may have are removed and
2017      * replaced by a single <code>Text</code> node containing the string
2018      * this attribute is set to. On getting, no serialization is performed,
2019      * the returned string does not contain any markup. No whitespace
2020      * normalization is performed, the returned string does not contain the
2021      * element content whitespaces . Similarly, on setting, no parsing is
2022      * performed either, the input string is taken as pure textual content.
2023      * <br>The string returned is made of the text content of this node
2024      * depending on its type, as defined below:
2025      * <table border='1'>
2026      * <tr>
2027      * <th>Node type</th>
2028      * <th>Content</th>
2029      * </tr>
2030      * <tr>
2031      * <td valign='top' rowspan='1' colspan='1'>
2032      * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
2033      * DOCUMENT_FRAGMENT_NODE</td>
2034      * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
2035      * attribute value of every child node, excluding COMMENT_NODE and
2036      * PROCESSING_INSTRUCTION_NODE nodes</td>
2037      * </tr>
2038      * <tr>
2039      * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
2040      * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
2041      * <td valign='top' rowspan='1' colspan='1'>
2042      * <code>nodeValue</code></td>
2043      * </tr>
2044      * <tr>
2045      * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
2046      * <td valign='top' rowspan='1' colspan='1'>
2047      * null</td>
2048      * </tr>
2049      * </table>
2050      * @exception DOMException
2051      *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
2052      * @exception DOMException
2053      *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
2054      *   fit in a <code>DOMString</code> variable on the implementation
2055      *   platform.
2056      * @since DOM Level 3
2057      */
2058     @Override
setTextContent(String textContent)2059     public void setTextContent(String textContent)
2060         throws DOMException {
2061         setNodeValue(textContent);
2062     }
2063     /**
2064      * This attribute returns the text content of this node and its
2065      * descendants. When it is defined to be null, setting it has no effect.
2066      * When set, any possible children this node may have are removed and
2067      * replaced by a single <code>Text</code> node containing the string
2068      * this attribute is set to. On getting, no serialization is performed,
2069      * the returned string does not contain any markup. No whitespace
2070      * normalization is performed, the returned string does not contain the
2071      * element content whitespaces . Similarly, on setting, no parsing is
2072      * performed either, the input string is taken as pure textual content.
2073      * <br>The string returned is made of the text content of this node
2074      * depending on its type, as defined below:
2075      * <table border='1'>
2076      * <tr>
2077      * <th>Node type</th>
2078      * <th>Content</th>
2079      * </tr>
2080      * <tr>
2081      * <td valign='top' rowspan='1' colspan='1'>
2082      * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
2083      * DOCUMENT_FRAGMENT_NODE</td>
2084      * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
2085      * attribute value of every child node, excluding COMMENT_NODE and
2086      * PROCESSING_INSTRUCTION_NODE nodes</td>
2087      * </tr>
2088      * <tr>
2089      * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
2090      * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
2091      * <td valign='top' rowspan='1' colspan='1'>
2092      * <code>nodeValue</code></td>
2093      * </tr>
2094      * <tr>
2095      * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
2096      * <td valign='top' rowspan='1' colspan='1'>
2097      * null</td>
2098      * </tr>
2099      * </table>
2100      * @exception DOMException
2101      *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
2102      * @exception DOMException
2103      *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than
2104      *   fit in a <code>DOMString</code> variable on the implementation
2105      *   platform.
2106      * @since DOM Level 3
2107      */
2108     @Override
getTextContent()2109     public String getTextContent() throws DOMException {
2110         return dtm.getStringValue(node).toString();
2111     }
2112 
2113      /**
2114      * Compares a node with this node with regard to their position in the
2115      * document.
2116      * @param other The node to compare against this node.
2117      * @return Returns how the given node is positioned relatively to this
2118      *   node.
2119      * @since DOM Level 3
2120      */
2121     @Override
compareDocumentPosition(Node other)2122     public short compareDocumentPosition(Node other) throws DOMException {
2123         return 0;
2124     }
2125 
2126      /**
2127      * The absolute base URI of this node or <code>null</code> if undefined.
2128      * This value is computed according to . However, when the
2129      * <code>Document</code> supports the feature "HTML" , the base URI is
2130      * computed using first the value of the href attribute of the HTML BASE
2131      * element if any, and the value of the <code>documentURI</code>
2132      * attribute from the <code>Document</code> interface otherwise.
2133      * <br> When the node is an <code>Element</code>, a <code>Document</code>
2134      * or a a <code>ProcessingInstruction</code>, this attribute represents
2135      * the properties [base URI] defined in . When the node is a
2136      * <code>Notation</code>, an <code>Entity</code>, or an
2137      * <code>EntityReference</code>, this attribute represents the
2138      * properties [declaration base URI] in the . How will this be affected
2139      * by resolution of relative namespace URIs issue?It's not.Should this
2140      * only be on Document, Element, ProcessingInstruction, Entity, and
2141      * Notation nodes, according to the infoset? If not, what is it equal to
2142      * on other nodes? Null? An empty string? I think it should be the
2143      * parent's.No.Should this be read-only and computed or and actual
2144      * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and
2145      * teleconference 30 May 2001).If the base HTML element is not yet
2146      * attached to a document, does the insert change the Document.baseURI?
2147      * Yes. (F2F 26 Sep 2001)
2148      * @since DOM Level 3
2149      */
2150     @Override
getBaseURI()2151     public String getBaseURI() {
2152         return null;
2153     }
2154 
2155     /**
2156      * DOM Level 3
2157      * Renaming node
2158      */
2159     @Override
renameNode(Node n, String namespaceURI, String name)2160     public Node renameNode(Node n,
2161                            String namespaceURI,
2162                            String name)
2163                            throws DOMException{
2164         return n;
2165     }
2166 
2167 
2168     /**
2169      *  DOM Level 3
2170      *  Normalize document.
2171      */
2172     @Override
normalizeDocument()2173     public void normalizeDocument(){
2174 
2175     }
2176     /**
2177      * The configuration used when <code>Document.normalizeDocument</code> is
2178      * invoked.
2179      * @since DOM Level 3
2180      */
2181     @Override
getDomConfig()2182     public DOMConfiguration getDomConfig(){
2183        return null;
2184     }
2185 
2186 
2187     /** DOM Level 3 feature: documentURI */
2188     protected String fDocumentURI;
2189 
2190     /**
2191      * DOM Level 3
2192      */
2193     @Override
setDocumentURI(String documentURI)2194     public void setDocumentURI(String documentURI){
2195         fDocumentURI= documentURI;
2196     }
2197 
2198         /**
2199      * DOM Level 3
2200      * The location of the document or <code>null</code> if undefined.
2201      * <br>Beware that when the <code>Document</code> supports the feature
2202      * "HTML" , the href attribute of the HTML BASE element takes precedence
2203      * over this attribute.
2204      * @since DOM Level 3
2205      */
2206     @Override
getDocumentURI()2207     public String getDocumentURI(){
2208         return fDocumentURI;
2209     }
2210 
2211         /**DOM Level 3 feature: Document actualEncoding */
2212     protected String actualEncoding;
2213 
2214      /**
2215      * DOM Level 3
2216      * An attribute specifying the actual encoding of this document. This is
2217      * <code>null</code> otherwise.
2218      * <br> This attribute represents the property [character encoding scheme]
2219      * defined in .
2220      * @since DOM Level 3
2221      */
getActualEncoding()2222     public String getActualEncoding() {
2223         return actualEncoding;
2224     }
2225 
2226     /**
2227      * DOM Level 3
2228      * An attribute specifying the actual encoding of this document. This is
2229      * <code>null</code> otherwise.
2230      * <br> This attribute represents the property [character encoding scheme]
2231      * defined in .
2232      * @since DOM Level 3
2233      */
setActualEncoding(String value)2234     public void setActualEncoding(String value) {
2235         actualEncoding = value;
2236     }
2237 
2238    /**
2239     * DOM Level 3
2240     */
2241     @Override
replaceWholeText(String content)2242     public Text replaceWholeText(String content)
2243                                  throws DOMException{
2244 /*
2245 
2246         if (needsSyncData()) {
2247             synchronizeData();
2248         }
2249 
2250         // make sure we can make the replacement
2251         if (!canModify(nextSibling)) {
2252             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
2253                 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
2254         }
2255 
2256         Node parent = this.getParentNode();
2257         if (content == null || content.length() == 0) {
2258             // remove current node
2259             if (parent !=null) { // check if node in the tree
2260                 parent.removeChild(this);
2261                 return null;
2262             }
2263         }
2264         Text currentNode = null;
2265         if (isReadOnly()){
2266             Text newNode = this.ownerDocument().createTextNode(content);
2267             if (parent !=null) { // check if node in the tree
2268                 parent.insertBefore(newNode, this);
2269                 parent.removeChild(this);
2270                 currentNode = newNode;
2271             } else {
2272                 return newNode;
2273             }
2274         }  else {
2275             this.setData(content);
2276             currentNode = this;
2277         }
2278         Node sibling =  currentNode.getNextSibling();
2279         while ( sibling !=null) {
2280             parent.removeChild(sibling);
2281             sibling = currentNode.getNextSibling();
2282         }
2283 
2284         return currentNode;
2285 */
2286         return null; //Pending
2287     }
2288 
2289      /**
2290      * DOM Level 3
2291      * Returns all text of <code>Text</code> nodes logically-adjacent text
2292      * nodes to this node, concatenated in document order.
2293      * @since DOM Level 3
2294      */
2295     @Override
getWholeText()2296     public String getWholeText(){
2297 
2298 /*
2299         if (needsSyncData()) {
2300             synchronizeData();
2301         }
2302         if (nextSibling == null) {
2303             return data;
2304         }
2305         StringBuffer buffer = new StringBuffer();
2306         if (data != null && data.length() != 0) {
2307             buffer.append(data);
2308         }
2309         getWholeText(nextSibling, buffer);
2310         return buffer.toString();
2311 */
2312         return null; // PENDING
2313 
2314     }
2315 
2316       /**
2317     * DOM Level 3
2318      * Returns whether this text node contains whitespace in element content,
2319      * often abusively called "ignorable whitespace".
2320      */
2321     @Override
isElementContentWhitespace()2322     public boolean isElementContentWhitespace(){
2323         return false;
2324     }
2325 
2326      /**
2327      * NON-DOM: set the type of this attribute to be ID type.
2328      *
2329      * @param id
2330      */
setIdAttribute(boolean id)2331     public void setIdAttribute(boolean id){
2332         //PENDING
2333     }
2334 
2335      /**
2336      * DOM Level 3: register the given attribute node as an ID attribute
2337      */
2338     @Override
setIdAttribute(String name, boolean makeId)2339     public void setIdAttribute(String name, boolean makeId) {
2340         //PENDING
2341     }
2342 
2343 
2344     /**
2345      * DOM Level 3: register the given attribute node as an ID attribute
2346      */
2347     @Override
setIdAttributeNode(Attr at, boolean makeId)2348     public void setIdAttributeNode(Attr at, boolean makeId) {
2349         //PENDING
2350     }
2351 
2352     /**
2353      * DOM Level 3: register the given attribute node as an ID attribute
2354      */
2355     @Override
setIdAttributeNS(String namespaceURI, String localName, boolean makeId)2356     public void setIdAttributeNS(String namespaceURI, String localName,
2357                                     boolean makeId) {
2358         //PENDING
2359     }
2360          /**
2361          * Method getSchemaTypeInfo.
2362          * @return TypeInfo
2363          */
2364     @Override
getSchemaTypeInfo()2365     public TypeInfo getSchemaTypeInfo(){
2366       return null; //PENDING
2367     }
2368 
2369     @Override
isId()2370     public boolean isId() {
2371         return false; //PENDING
2372     }
2373 
2374 
2375     private String xmlEncoding;
2376     @Override
getXmlEncoding( )2377     public String getXmlEncoding( ) {
2378         return xmlEncoding;
2379     }
setXmlEncoding( String xmlEncoding )2380     public void setXmlEncoding( String xmlEncoding ) {
2381         this.xmlEncoding = xmlEncoding;
2382     }
2383 
2384     private boolean xmlStandalone;
2385     @Override
getXmlStandalone()2386     public boolean getXmlStandalone() {
2387         return xmlStandalone;
2388     }
2389 
2390     @Override
setXmlStandalone(boolean xmlStandalone)2391     public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
2392         this.xmlStandalone = xmlStandalone;
2393     }
2394 
2395     private String xmlVersion;
2396     @Override
getXmlVersion()2397     public String getXmlVersion() {
2398         return xmlVersion;
2399     }
2400 
2401     @Override
setXmlVersion(String xmlVersion)2402     public void setXmlVersion(String xmlVersion) throws DOMException {
2403         this.xmlVersion = xmlVersion;
2404     }
2405 
2406 }
2407