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