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