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