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