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