1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * @LastModified: Oct 2017 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 25 package com.sun.org.apache.xml.internal.dtm.ref; 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.ArrayList; 31 import java.util.List; 32 import java.util.Objects; 33 import org.w3c.dom.Attr; 34 import org.w3c.dom.CDATASection; 35 import org.w3c.dom.Comment; 36 import org.w3c.dom.DOMConfiguration; 37 import org.w3c.dom.DOMException; 38 import org.w3c.dom.DOMImplementation; 39 import org.w3c.dom.Document; 40 import org.w3c.dom.DocumentFragment; 41 import org.w3c.dom.DocumentType; 42 import org.w3c.dom.Element; 43 import org.w3c.dom.EntityReference; 44 import org.w3c.dom.NamedNodeMap; 45 import org.w3c.dom.Node; 46 import org.w3c.dom.NodeList; 47 import org.w3c.dom.ProcessingInstruction; 48 import org.w3c.dom.Text; 49 import org.w3c.dom.TypeInfo; 50 import org.w3c.dom.UserDataHandler; 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 List<Node> listVector = new ArrayList<>(); 784 Node retNode = dtm.getNode(node); 785 if (retNode != null) 786 { 787 boolean isTagNameWildCard = "*".equals(tagname); 788 if (DTM.ELEMENT_NODE == retNode.getNodeType()) 789 { 790 NodeList nodeList = retNode.getChildNodes(); 791 for (int i = 0; i < nodeList.getLength(); i++) 792 { 793 traverseChildren(listVector, nodeList.item(i), tagname, 794 isTagNameWildCard); 795 } 796 } else if (DTM.DOCUMENT_NODE == retNode.getNodeType()) { 797 traverseChildren(listVector, dtm.getNode(node), tagname, 798 isTagNameWildCard); 799 } 800 } 801 int size = listVector.size(); 802 NodeSet nodeSet = new NodeSet(size); 803 for (int i = 0; i < size; i++) 804 { 805 nodeSet.addNode(listVector.get(i)); 806 } 807 return (NodeList) nodeSet; 808 } 809 810 /** 811 * 812 * @param listVector 813 * @param tempNode 814 * @param tagname 815 * @param isTagNameWildCard 816 * 817 * 818 * Private method to be used for recursive iterations to obtain elements by tag name. 819 */ 820 private final void traverseChildren(List<Node> listVector, Node tempNode, 821 String tagname, boolean isTagNameWildCard) { 822 if (tempNode == null) 823 { 824 return; 825 } 826 else 827 { 828 if (tempNode.getNodeType() == DTM.ELEMENT_NODE 829 && (isTagNameWildCard || tempNode.getNodeName().equals(tagname))) 830 { 831 listVector.add(tempNode); 832 } 833 if(tempNode.hasChildNodes()) 834 { 835 NodeList nodeList = tempNode.getChildNodes(); 836 for (int i = 0; i < nodeList.getLength(); i++) 837 { 838 traverseChildren(listVector, nodeList.item(i), tagname, 839 isTagNameWildCard); 840 } 841 } 842 } 843 } 844 845 846 847 /** 848 * 849 * @param importedNode 850 * @param deep 851 * 852 * 853 * 854 * @throws DOMException 855 * @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only 856 */ 857 @Override 858 public final Node importNode(Node importedNode, boolean deep) 859 throws DOMException 860 { 861 throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR); 862 } 863 864 /** 865 * 866 * @param namespaceURI 867 * @param qualifiedName 868 * 869 * 870 * 871 * @throws DOMException 872 * @see org.w3c.dom.Document as of DOM Level 2 873 */ 874 @Override 875 public final Element createElementNS( 876 String namespaceURI, String qualifiedName) throws DOMException 877 { 878 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 879 } 880 881 /** 882 * 883 * @param namespaceURI 884 * @param qualifiedName 885 * 886 * 887 * 888 * @throws DOMException 889 * @see org.w3c.dom.Document as of DOM Level 2 890 */ 891 @Override 892 public final Attr createAttributeNS( 893 String namespaceURI, String qualifiedName) throws DOMException 894 { 895 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 896 } 897 898 /** 899 * 900 * @param namespaceURI 901 * @param localName 902 * 903 * 904 * @see org.w3c.dom.Document as of DOM Level 2 905 */ 906 @Override 907 public final NodeList getElementsByTagNameNS(String namespaceURI, 908 String localName) 909 { 910 List<Node> listVector = new ArrayList<>(); 911 Node retNode = dtm.getNode(node); 912 if (retNode != null) 913 { 914 boolean isNamespaceURIWildCard = "*".equals(namespaceURI); 915 boolean isLocalNameWildCard = "*".equals(localName); 916 if (DTM.ELEMENT_NODE == retNode.getNodeType()) 917 { 918 NodeList nodeList = retNode.getChildNodes(); 919 for(int i = 0; i < nodeList.getLength(); i++) 920 { 921 traverseChildren(listVector, nodeList.item(i), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard); 922 } 923 } 924 else if(DTM.DOCUMENT_NODE == retNode.getNodeType()) 925 { 926 traverseChildren(listVector, dtm.getNode(node), namespaceURI, localName, isNamespaceURIWildCard, isLocalNameWildCard); 927 } 928 } 929 int size = listVector.size(); 930 NodeSet nodeSet = new NodeSet(size); 931 for (int i = 0; i < size; i++) 932 { 933 nodeSet.addNode(listVector.get(i)); 934 } 935 return (NodeList) nodeSet; 936 } 937 /** 938 * 939 * @param listVector 940 * @param tempNode 941 * @param namespaceURI 942 * @param localname 943 * @param isNamespaceURIWildCard 944 * @param isLocalNameWildCard 945 * 946 * Private method to be used for recursive iterations to obtain elements by tag name 947 * and namespaceURI. 948 */ 949 private final void traverseChildren(List<Node> listVector, Node tempNode, 950 String namespaceURI, String localname, boolean isNamespaceURIWildCard, 951 boolean isLocalNameWildCard) 952 { 953 if (tempNode == null) 954 { 955 return; 956 } 957 else 958 { 959 if (tempNode.getNodeType() == DTM.ELEMENT_NODE 960 && (isLocalNameWildCard 961 || tempNode.getLocalName().equals(localname))) 962 { 963 String nsURI = tempNode.getNamespaceURI(); 964 if ((namespaceURI == null && nsURI == null) 965 || isNamespaceURIWildCard 966 || (namespaceURI != null && namespaceURI.equals(nsURI))) 967 { 968 listVector.add(tempNode); 969 } 970 } 971 if(tempNode.hasChildNodes()) 972 { 973 NodeList nl = tempNode.getChildNodes(); 974 for(int i = 0; i < nl.getLength(); i++) 975 { 976 traverseChildren(listVector, nl.item(i), namespaceURI, localname, 977 isNamespaceURIWildCard, isLocalNameWildCard); 978 } 979 } 980 } 981 } 982 /** 983 * 984 * @param elementId 985 * 986 * 987 * @see org.w3c.dom.Document as of DOM Level 2 988 */ 989 @Override 990 public final Element getElementById(String elementId) 991 { 992 return (Element) dtm.getNode(dtm.getElementById(elementId)); 993 } 994 995 /** 996 * 997 * @param offset 998 * 999 * 1000 * 1001 * @throws DOMException 1002 * @see org.w3c.dom.Text 1003 */ 1004 @Override 1005 public final Text splitText(int offset) throws DOMException 1006 { 1007 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1008 } 1009 1010 /** 1011 * 1012 * 1013 * 1014 * @throws DOMException 1015 * @see org.w3c.dom.CharacterData 1016 */ 1017 @Override 1018 public final String getData() throws DOMException 1019 { 1020 return dtm.getNodeValue(node); 1021 } 1022 1023 /** 1024 * 1025 * @param data 1026 * 1027 * @throws DOMException 1028 * @see org.w3c.dom.CharacterData 1029 */ 1030 @Override 1031 public final void setData(String data) throws DOMException 1032 { 1033 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1034 } 1035 1036 /** 1037 * 1038 * 1039 * @see org.w3c.dom.CharacterData 1040 */ 1041 @Override 1042 public final int getLength() 1043 { 1044 // %OPT% This should do something smarter? 1045 return dtm.getNodeValue(node).length(); 1046 } 1047 1048 /** 1049 * 1050 * @param offset 1051 * @param count 1052 * 1053 * 1054 * 1055 * @throws DOMException 1056 * @see org.w3c.dom.CharacterData 1057 */ 1058 @Override 1059 public final String substringData(int offset, int count) throws DOMException 1060 { 1061 return getData().substring(offset,offset+count); 1062 } 1063 1064 /** 1065 * 1066 * @param arg 1067 * 1068 * @throws DOMException 1069 * @see org.w3c.dom.CharacterData 1070 */ 1071 @Override 1072 public final void appendData(String arg) throws DOMException 1073 { 1074 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1075 } 1076 1077 /** 1078 * 1079 * @param offset 1080 * @param arg 1081 * 1082 * @throws DOMException 1083 * @see org.w3c.dom.CharacterData 1084 */ 1085 @Override 1086 public final void insertData(int offset, String arg) throws DOMException 1087 { 1088 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1089 } 1090 1091 /** 1092 * 1093 * @param offset 1094 * @param count 1095 * 1096 * @throws DOMException 1097 * @see org.w3c.dom.CharacterData 1098 */ 1099 @Override 1100 public final void deleteData(int offset, int count) throws DOMException 1101 { 1102 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1103 } 1104 1105 /** 1106 * 1107 * @param offset 1108 * @param count 1109 * @param arg 1110 * 1111 * @throws DOMException 1112 * @see org.w3c.dom.CharacterData 1113 */ 1114 @Override 1115 public final void replaceData(int offset, int count, String arg) 1116 throws DOMException 1117 { 1118 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1119 } 1120 1121 /** 1122 * 1123 * 1124 * @see org.w3c.dom.Element 1125 */ 1126 @Override 1127 public final String getTagName() 1128 { 1129 return dtm.getNodeName(node); 1130 } 1131 1132 /** 1133 * 1134 * @param name 1135 * 1136 * 1137 * @see org.w3c.dom.Element 1138 */ 1139 @Override 1140 public final String getAttribute(String name) 1141 { 1142 DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node); 1143 Node n = map.getNamedItem(name); 1144 return (null == n) ? EMPTYSTRING : n.getNodeValue(); 1145 } 1146 1147 /** 1148 * 1149 * @param name 1150 * @param value 1151 * 1152 * @throws DOMException 1153 * @see org.w3c.dom.Element 1154 */ 1155 @Override 1156 public final void setAttribute(String name, String value) 1157 throws DOMException 1158 { 1159 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1160 } 1161 1162 /** 1163 * 1164 * @param name 1165 * 1166 * @throws DOMException 1167 * @see org.w3c.dom.Element 1168 */ 1169 @Override 1170 public final void removeAttribute(String name) throws DOMException 1171 { 1172 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1173 } 1174 1175 /** 1176 * 1177 * @param name 1178 * 1179 * 1180 * @see org.w3c.dom.Element 1181 */ 1182 @Override 1183 public final Attr getAttributeNode(String name) 1184 { 1185 DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node); 1186 return (Attr)map.getNamedItem(name); 1187 } 1188 1189 /** 1190 * 1191 * @param newAttr 1192 * 1193 * 1194 * 1195 * @throws DOMException 1196 * @see org.w3c.dom.Element 1197 */ 1198 @Override 1199 public final Attr setAttributeNode(Attr newAttr) throws DOMException 1200 { 1201 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1202 } 1203 1204 /** 1205 * 1206 * @param oldAttr 1207 * 1208 * 1209 * 1210 * @throws DOMException 1211 * @see org.w3c.dom.Element 1212 */ 1213 @Override 1214 public final Attr removeAttributeNode(Attr oldAttr) throws DOMException 1215 { 1216 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1217 } 1218 1219 /** 1220 * Introduced in DOM Level 2. 1221 * 1222 * 1223 */ 1224 @Override 1225 public boolean hasAttributes() 1226 { 1227 return DTM.NULL != dtm.getFirstAttribute(node); 1228 } 1229 1230 /** @see org.w3c.dom.Element */ 1231 @Override 1232 public final void normalize() 1233 { 1234 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1235 } 1236 1237 /** 1238 * 1239 * @param namespaceURI 1240 * @param localName 1241 * 1242 * 1243 * @see org.w3c.dom.Element 1244 */ 1245 @Override 1246 public final String getAttributeNS(String namespaceURI, String localName) 1247 { 1248 Node retNode = null; 1249 int n = dtm.getAttributeNode(node,namespaceURI,localName); 1250 if(n != DTM.NULL) 1251 retNode = dtm.getNode(n); 1252 return (null == retNode) ? EMPTYSTRING : retNode.getNodeValue(); 1253 } 1254 1255 /** 1256 * 1257 * @param namespaceURI 1258 * @param qualifiedName 1259 * @param value 1260 * 1261 * @throws DOMException 1262 * @see org.w3c.dom.Element 1263 */ 1264 @Override 1265 public final void setAttributeNS( 1266 String namespaceURI, String qualifiedName, String value) 1267 throws DOMException 1268 { 1269 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1270 } 1271 1272 /** 1273 * 1274 * @param namespaceURI 1275 * @param localName 1276 * 1277 * @throws DOMException 1278 * @see org.w3c.dom.Element 1279 */ 1280 @Override 1281 public final void removeAttributeNS(String namespaceURI, String localName) 1282 throws DOMException 1283 { 1284 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1285 } 1286 1287 /** 1288 * 1289 * @param namespaceURI 1290 * @param localName 1291 * 1292 * 1293 * @see org.w3c.dom.Element 1294 */ 1295 @Override 1296 public final Attr getAttributeNodeNS(String namespaceURI, String localName) 1297 { 1298 Attr retAttr = null; 1299 int n = dtm.getAttributeNode(node,namespaceURI,localName); 1300 if(n != DTM.NULL) 1301 retAttr = (Attr) dtm.getNode(n); 1302 return retAttr; 1303 1304 } 1305 1306 /** 1307 * 1308 * @param newAttr 1309 * 1310 * 1311 * 1312 * @throws DOMException 1313 * @see org.w3c.dom.Element 1314 */ 1315 @Override 1316 public final Attr setAttributeNodeNS(Attr newAttr) throws DOMException 1317 { 1318 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1319 } 1320 1321 /** 1322 * 1323 * 1324 * @see org.w3c.dom.Attr 1325 */ 1326 @Override 1327 public final String getName() 1328 { 1329 return dtm.getNodeName(node); 1330 } 1331 1332 /** 1333 * 1334 * 1335 * @see org.w3c.dom.Attr 1336 */ 1337 @Override 1338 public final boolean getSpecified() 1339 { 1340 // We really don't know which attributes might have come from the 1341 // source document versus from the DTD. Treat them all as having 1342 // been provided by the user. 1343 // %REVIEW% if/when we become aware of DTDs/schemae. 1344 return true; 1345 } 1346 1347 /** 1348 * 1349 * 1350 * @see org.w3c.dom.Attr 1351 */ 1352 @Override 1353 public final String getValue() 1354 { 1355 return dtm.getNodeValue(node); 1356 } 1357 1358 /** 1359 * 1360 * @param value 1361 * @see org.w3c.dom.Attr 1362 */ 1363 @Override 1364 public final void setValue(String value) 1365 { 1366 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1367 } 1368 1369 /** 1370 * Get the owner element of an attribute. 1371 * 1372 * 1373 * @see org.w3c.dom.Attr as of DOM Level 2 1374 */ 1375 @Override 1376 public final Element getOwnerElement() 1377 { 1378 if (getNodeType() != Node.ATTRIBUTE_NODE) 1379 return null; 1380 // In XPath and DTM data models, unlike DOM, an Attr's parent is its 1381 // owner element. 1382 int newnode = dtm.getParent(node); 1383 return (newnode == DTM.NULL) ? null : (Element)(dtm.getNode(newnode)); 1384 } 1385 1386 /** 1387 * NEEDSDOC Method adoptNode 1388 * 1389 * 1390 * NEEDSDOC @param source 1391 * 1392 * NEEDSDOC (adoptNode) @return 1393 * 1394 * @throws DOMException 1395 */ 1396 @Override 1397 public Node adoptNode(Node source) throws DOMException 1398 { 1399 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1400 } 1401 1402 /** 1403 * <p>EXPERIMENTAL! Based on the <a 1404 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1405 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1406 * <p> 1407 * An attribute specifying, as part of the XML declaration, the encoding 1408 * of this document. This is <code>null</code> when unspecified. 1409 * @since DOM Level 3 1410 * 1411 * NEEDSDOC ($objectName$) @return 1412 */ 1413 @Override 1414 public String getInputEncoding() 1415 { 1416 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1417 } 1418 1419 /** 1420 * <p>EXPERIMENTAL! Based on the <a 1421 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1422 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1423 * <p> 1424 * An attribute specifying, as part of the XML declaration, the encoding 1425 * of this document. This is <code>null</code> when unspecified. 1426 * @since DOM Level 3 1427 * 1428 * NEEDSDOC @param encoding 1429 */ 1430 public void setEncoding(String encoding) 1431 { 1432 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1433 } 1434 1435 /** 1436 * <p>EXPERIMENTAL! Based on the <a 1437 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1438 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1439 * <p> 1440 * An attribute specifying, as part of the XML declaration, whether this 1441 * document is standalone. 1442 * @since DOM Level 3 1443 * 1444 * NEEDSDOC ($objectName$) @return 1445 */ 1446 public boolean getStandalone() 1447 { 1448 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1449 } 1450 1451 /** 1452 * <p>EXPERIMENTAL! Based on the <a 1453 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1454 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1455 * <p> 1456 * An attribute specifying, as part of the XML declaration, whether this 1457 * document is standalone. 1458 * @since DOM Level 3 1459 * 1460 * NEEDSDOC @param standalone 1461 */ 1462 public void setStandalone(boolean standalone) 1463 { 1464 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1465 } 1466 1467 /** 1468 * <p>EXPERIMENTAL! Based on the <a 1469 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1470 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1471 * <p> 1472 * An attribute specifying whether errors checking is enforced or not. 1473 * When set to <code>false</code>, the implementation is free to not 1474 * test every possible error case normally defined on DOM operations, 1475 * and not raise any <code>DOMException</code>. In case of error, the 1476 * behavior is undefined. This attribute is <code>true</code> by 1477 * defaults. 1478 * @since DOM Level 3 1479 * 1480 * NEEDSDOC ($objectName$) @return 1481 */ 1482 @Override 1483 public boolean getStrictErrorChecking() 1484 { 1485 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1486 } 1487 1488 /** 1489 * <p>EXPERIMENTAL! Based on the <a 1490 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1491 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1492 * <p> 1493 * An attribute specifying whether errors checking is enforced or not. 1494 * When set to <code>false</code>, the implementation is free to not 1495 * test every possible error case normally defined on DOM operations, 1496 * and not raise any <code>DOMException</code>. In case of error, the 1497 * behavior is undefined. This attribute is <code>true</code> by 1498 * defaults. 1499 * @since DOM Level 3 1500 * 1501 * NEEDSDOC @param strictErrorChecking 1502 */ 1503 @Override 1504 public void setStrictErrorChecking(boolean strictErrorChecking) 1505 { 1506 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1507 } 1508 1509 /** 1510 * <p>EXPERIMENTAL! Based on the <a 1511 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1512 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1513 * <p> 1514 * An attribute specifying, as part of the XML declaration, the version 1515 * number of this document. This is <code>null</code> when unspecified. 1516 * @since DOM Level 3 1517 * 1518 * NEEDSDOC ($objectName$) @return 1519 */ 1520 public String getVersion() 1521 { 1522 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1523 } 1524 1525 /** 1526 * <p>EXPERIMENTAL! Based on the <a 1527 * href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document 1528 * Object Model (DOM) Level 3 Core Working Draft of 5 June 2001.</a>. 1529 * <p> 1530 * An attribute specifying, as part of the XML declaration, the version 1531 * number of this document. This is <code>null</code> when unspecified. 1532 * @since DOM Level 3 1533 * 1534 * NEEDSDOC @param version 1535 */ 1536 public void setVersion(String version) 1537 { 1538 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1539 } 1540 1541 1542 /** Inner class to support getDOMImplementation. 1543 */ 1544 static class DTMNodeProxyImplementation implements DOMImplementation 1545 { 1546 @Override 1547 public DocumentType createDocumentType(String qualifiedName,String publicId, String systemId) 1548 { 1549 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1550 } 1551 @Override 1552 public Document createDocument(String namespaceURI,String qualfiedName,DocumentType doctype) 1553 { 1554 // Could create a DTM... but why, when it'd have to be permanantly empty? 1555 throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); 1556 } 1557 /** Ask whether we support a given DOM feature. 1558 * 1559 * In fact, we do not _fully_ support any DOM feature -- we're a 1560 * read-only subset -- so arguably we should always return false. 1561 * On the other hand, it may be more practically useful to return 1562 * true and simply treat the whole DOM as read-only, failing on the 1563 * methods we can't support. I'm not sure which would be more useful 1564 * to the caller. 1565 */ 1566 @Override 1567 public boolean hasFeature(String feature,String version) 1568 { 1569 if( ("CORE".equals(feature.toUpperCase()) || "XML".equals(feature.toUpperCase())) 1570 && 1571 ("1.0".equals(version) || "2.0".equals(version))) 1572 return true; 1573 return false; 1574 } 1575 1576 /** 1577 * This method returns a specialized object which implements the 1578 * specialized APIs of the specified feature and version. The 1579 * specialized object may also be obtained by using binding-specific 1580 * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations 1581 . 1582 * @param feature The name of the feature requested (case-insensitive). 1583 * @param version This is the version number of the feature to test. If 1584 * the version is <code>null</code> or the empty string, supporting 1585 * any version of the feature will cause the method to return an 1586 * object that supports at least one version of the feature. 1587 * @return Returns an object which implements the specialized APIs of 1588 * the specified feature and version, if any, or <code>null</code> if 1589 * there is no object which implements interfaces associated with that 1590 * feature. If the <code>DOMObject</code> returned by this method 1591 * implements the <code>Node</code> interface, it must delegate to the 1592 * primary core <code>Node</code> and not return results inconsistent 1593 * with the primary core <code>Node</code> such as attributes, 1594 * childNodes, etc. 1595 * @since DOM Level 3 1596 */ 1597 @Override 1598 public Object getFeature(String feature, String version) { 1599 // we don't have any alternate node, either this node does the job 1600 // or we don't have anything that does 1601 //return hasFeature(feature, version) ? this : null; 1602 return null; //PENDING 1603 } 1604 1605 } 1606 1607 1608 //RAMESH : Pending proper implementation of DOM Level 3 1609 1610 @Override 1611 public Object setUserData(String key, 1612 Object data, 1613 UserDataHandler handler) { 1614 return getOwnerDocument().setUserData( key, data, handler); 1615 } 1616 1617 /** 1618 * Retrieves the object associated to a key on a this node. The object 1619 * must first have been set to this node by calling 1620 * <code>setUserData</code> with the same key. 1621 * @param key The key the object is associated to. 1622 * @return Returns the <code>DOMObject</code> associated to the given key 1623 * on this node, or <code>null</code> if there was none. 1624 * @since DOM Level 3 1625 */ 1626 @Override 1627 public Object getUserData(String key) { 1628 return getOwnerDocument().getUserData( key); 1629 } 1630 1631 /** 1632 * This method returns a specialized object which implements the 1633 * specialized APIs of the specified feature and version. The 1634 * specialized object may also be obtained by using binding-specific 1635 * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations. 1636 * @param feature The name of the feature requested (case-insensitive). 1637 * @param version This is the version number of the feature to test. If 1638 * the version is <code>null</code> or the empty string, supporting 1639 * any version of the feature will cause the method to return an 1640 * object that supports at least one version of the feature. 1641 * @return Returns an object which implements the specialized APIs of 1642 * the specified feature and version, if any, or <code>null</code> if 1643 * there is no object which implements interfaces associated with that 1644 * feature. If the <code>DOMObject</code> returned by this method 1645 * implements the <code>Node</code> interface, it must delegate to the 1646 * primary core <code>Node</code> and not return results inconsistent 1647 * with the primary core <code>Node</code> such as attributes, 1648 * childNodes, etc. 1649 * @since DOM Level 3 1650 */ 1651 @Override 1652 public Object getFeature(String feature, String version) { 1653 // we don't have any alternate node, either this node does the job 1654 // or we don't have anything that does 1655 return isSupported(feature, version) ? this : null; 1656 } 1657 1658 /** 1659 * Tests whether two nodes are equal. 1660 * <br>This method tests for equality of nodes, not sameness (i.e., 1661 * whether the two nodes are references to the same object) which can be 1662 * tested with <code>Node.isSameNode</code>. All nodes that are the same 1663 * will also be equal, though the reverse may not be true. 1664 * <br>Two nodes are equal if and only if the following conditions are 1665 * satisfied: The two nodes are of the same type.The following string 1666 * attributes are equal: <code>nodeName</code>, <code>localName</code>, 1667 * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code> 1668 * , <code>baseURI</code>. This is: they are both <code>null</code>, or 1669 * they have the same length and are character for character identical. 1670 * The <code>attributes</code> <code>NamedNodeMaps</code> are equal. 1671 * This is: they are both <code>null</code>, or they have the same 1672 * length and for each node that exists in one map there is a node that 1673 * exists in the other map and is equal, although not necessarily at the 1674 * same index.The <code>childNodes</code> <code>NodeLists</code> are 1675 * equal. This is: they are both <code>null</code>, or they have the 1676 * same length and contain equal nodes at the same index. This is true 1677 * for <code>Attr</code> nodes as for any other type of node. Note that 1678 * normalization can affect equality; to avoid this, nodes should be 1679 * normalized before being compared. 1680 * <br>For two <code>DocumentType</code> nodes to be equal, the following 1681 * conditions must also be satisfied: The following string attributes 1682 * are equal: <code>publicId</code>, <code>systemId</code>, 1683 * <code>internalSubset</code>.The <code>entities</code> 1684 * <code>NamedNodeMaps</code> are equal.The <code>notations</code> 1685 * <code>NamedNodeMaps</code> are equal. 1686 * <br>On the other hand, the following do not affect equality: the 1687 * <code>ownerDocument</code> attribute, the <code>specified</code> 1688 * attribute for <code>Attr</code> nodes, the 1689 * <code>isWhitespaceInElementContent</code> attribute for 1690 * <code>Text</code> nodes, as well as any user data or event listeners 1691 * registered on the nodes. 1692 * @param arg The node to compare equality with. 1693 * @param deep If <code>true</code>, recursively compare the subtrees; if 1694 * <code>false</code>, compare only the nodes themselves (and its 1695 * attributes, if it is an <code>Element</code>). 1696 * @return If the nodes, and possibly subtrees are equal, 1697 * <code>true</code> otherwise <code>false</code>. 1698 * @since DOM Level 3 1699 */ 1700 @Override 1701 public boolean isEqualNode(Node arg) { 1702 if (arg == this) { 1703 return true; 1704 } 1705 if (arg.getNodeType() != getNodeType()) { 1706 return false; 1707 } 1708 // in theory nodeName can't be null but better be careful 1709 // who knows what other implementations may be doing?... 1710 if (getNodeName() == null) { 1711 if (arg.getNodeName() != null) { 1712 return false; 1713 } 1714 } 1715 else if (!getNodeName().equals(arg.getNodeName())) { 1716 return false; 1717 } 1718 1719 if (getLocalName() == null) { 1720 if (arg.getLocalName() != null) { 1721 return false; 1722 } 1723 } 1724 else if (!getLocalName().equals(arg.getLocalName())) { 1725 return false; 1726 } 1727 1728 if (getNamespaceURI() == null) { 1729 if (arg.getNamespaceURI() != null) { 1730 return false; 1731 } 1732 } 1733 else if (!getNamespaceURI().equals(arg.getNamespaceURI())) { 1734 return false; 1735 } 1736 1737 if (getPrefix() == null) { 1738 if (arg.getPrefix() != null) { 1739 return false; 1740 } 1741 } 1742 else if (!getPrefix().equals(arg.getPrefix())) { 1743 return false; 1744 } 1745 1746 if (getNodeValue() == null) { 1747 if (arg.getNodeValue() != null) { 1748 return false; 1749 } 1750 } 1751 else if (!getNodeValue().equals(arg.getNodeValue())) { 1752 return false; 1753 } 1754 /* 1755 if (getBaseURI() == null) { 1756 if (((NodeImpl) arg).getBaseURI() != null) { 1757 return false; 1758 } 1759 } 1760 else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) { 1761 return false; 1762 } 1763 */ 1764 1765 return true; 1766 } 1767 1768 /** 1769 * DOM Level 3 1770 * Look up the namespace URI associated to the given prefix, starting from this node. 1771 * Use lookupNamespaceURI(null) to lookup the default namespace 1772 * 1773 * @param namespaceURI 1774 * @return th URI for the namespace 1775 * @since DOM Level 3 1776 */ 1777 @Override 1778 public String lookupNamespaceURI(String specifiedPrefix) { 1779 short type = this.getNodeType(); 1780 switch (type) { 1781 case Node.ELEMENT_NODE : { 1782 1783 String namespace = this.getNamespaceURI(); 1784 String prefix = this.getPrefix(); 1785 if (namespace !=null) { 1786 // REVISIT: is it possible that prefix is empty string? 1787 if (specifiedPrefix== null && prefix==specifiedPrefix) { 1788 // looking for default namespace 1789 return namespace; 1790 } else if (prefix != null && prefix.equals(specifiedPrefix)) { 1791 // non default namespace 1792 return namespace; 1793 } 1794 } 1795 if (this.hasAttributes()) { 1796 NamedNodeMap map = this.getAttributes(); 1797 int length = map.getLength(); 1798 for (int i=0;i<length;i++) { 1799 Node attr = map.item(i); 1800 String attrPrefix = attr.getPrefix(); 1801 String value = attr.getNodeValue(); 1802 namespace = attr.getNamespaceURI(); 1803 if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) { 1804 // at this point we are dealing with DOM Level 2 nodes only 1805 if (specifiedPrefix == null && 1806 attr.getNodeName().equals("xmlns")) { 1807 // default namespace 1808 return value; 1809 } else if (attrPrefix !=null && 1810 attrPrefix.equals("xmlns") && 1811 attr.getLocalName().equals(specifiedPrefix)) { 1812 // non default namespace 1813 return value; 1814 } 1815 } 1816 } 1817 } 1818 /* 1819 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 1820 if (ancestor != null) { 1821 return ancestor.lookupNamespaceURI(specifiedPrefix); 1822 } 1823 */ 1824 1825 return null; 1826 1827 1828 } 1829 /* 1830 case Node.DOCUMENT_NODE : { 1831 return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ; 1832 } 1833 */ 1834 case Node.ENTITY_NODE : 1835 case Node.NOTATION_NODE: 1836 case Node.DOCUMENT_FRAGMENT_NODE: 1837 case Node.DOCUMENT_TYPE_NODE: 1838 // type is unknown 1839 return null; 1840 case Node.ATTRIBUTE_NODE:{ 1841 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) { 1842 return getOwnerElement().lookupNamespaceURI(specifiedPrefix); 1843 1844 } 1845 return null; 1846 } 1847 default:{ 1848 /* 1849 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 1850 if (ancestor != null) { 1851 return ancestor.lookupNamespaceURI(specifiedPrefix); 1852 } 1853 */ 1854 return null; 1855 } 1856 1857 } 1858 } 1859 1860 1861 /** 1862 * DOM Level 3 1863 * This method checks if the specified <code>namespaceURI</code> is the 1864 * default namespace or not. 1865 * @param namespaceURI The namespace URI to look for. 1866 * @return <code>true</code> if the specified <code>namespaceURI</code> 1867 * is the default namespace, <code>false</code> otherwise. 1868 * @since DOM Level 3 1869 */ 1870 @Override 1871 public boolean isDefaultNamespace(String namespaceURI){ 1872 /* 1873 // REVISIT: remove casts when DOM L3 becomes REC. 1874 short type = this.getNodeType(); 1875 switch (type) { 1876 case Node.ELEMENT_NODE: { 1877 String namespace = this.getNamespaceURI(); 1878 String prefix = this.getPrefix(); 1879 1880 // REVISIT: is it possible that prefix is empty string? 1881 if (prefix == null || prefix.length() == 0) { 1882 if (namespaceURI == null) { 1883 return (namespace == namespaceURI); 1884 } 1885 return namespaceURI.equals(namespace); 1886 } 1887 if (this.hasAttributes()) { 1888 ElementImpl elem = (ElementImpl)this; 1889 NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns"); 1890 if (attr != null) { 1891 String value = attr.getNodeValue(); 1892 if (namespaceURI == null) { 1893 return (namespace == value); 1894 } 1895 return namespaceURI.equals(value); 1896 } 1897 } 1898 1899 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 1900 if (ancestor != null) { 1901 return ancestor.isDefaultNamespace(namespaceURI); 1902 } 1903 return false; 1904 } 1905 case Node.DOCUMENT_NODE:{ 1906 return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI); 1907 } 1908 1909 case Node.ENTITY_NODE : 1910 case Node.NOTATION_NODE: 1911 case Node.DOCUMENT_FRAGMENT_NODE: 1912 case Node.DOCUMENT_TYPE_NODE: 1913 // type is unknown 1914 return false; 1915 case Node.ATTRIBUTE_NODE:{ 1916 if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) { 1917 return ownerNode.isDefaultNamespace(namespaceURI); 1918 1919 } 1920 return false; 1921 } 1922 default:{ 1923 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 1924 if (ancestor != null) { 1925 return ancestor.isDefaultNamespace(namespaceURI); 1926 } 1927 return false; 1928 } 1929 1930 } 1931 */ 1932 return false; 1933 1934 1935 } 1936 1937 /** 1938 * 1939 * DOM Level 3 1940 * Look up the prefix associated to the given namespace URI, starting from this node. 1941 * 1942 * @param namespaceURI 1943 * @return the prefix for the namespace 1944 */ 1945 @Override 1946 public String lookupPrefix(String namespaceURI){ 1947 1948 // REVISIT: When Namespaces 1.1 comes out this may not be true 1949 // Prefix can't be bound to null namespace 1950 if (namespaceURI == null) { 1951 return null; 1952 } 1953 1954 short type = this.getNodeType(); 1955 1956 switch (type) { 1957 /* 1958 case Node.ELEMENT_NODE: { 1959 1960 String namespace = this.getNamespaceURI(); // to flip out children 1961 return lookupNamespacePrefix(namespaceURI, (ElementImpl)this); 1962 } 1963 1964 case Node.DOCUMENT_NODE:{ 1965 return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI); 1966 } 1967 */ 1968 case Node.ENTITY_NODE : 1969 case Node.NOTATION_NODE: 1970 case Node.DOCUMENT_FRAGMENT_NODE: 1971 case Node.DOCUMENT_TYPE_NODE: 1972 // type is unknown 1973 return null; 1974 case Node.ATTRIBUTE_NODE:{ 1975 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) { 1976 return getOwnerElement().lookupPrefix(namespaceURI); 1977 1978 } 1979 return null; 1980 } 1981 default:{ 1982 /* 1983 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 1984 if (ancestor != null) { 1985 return ancestor.lookupPrefix(namespaceURI); 1986 } 1987 */ 1988 return null; 1989 } 1990 } 1991 } 1992 1993 /** 1994 * Returns whether this node is the same node as the given one. 1995 * <br>This method provides a way to determine whether two 1996 * <code>Node</code> references returned by the implementation reference 1997 * the same object. When two <code>Node</code> references are references 1998 * to the same object, even if through a proxy, the references may be 1999 * used completely interchangably, such that all attributes have the 2000 * same values and calling the same DOM method on either reference 2001 * always has exactly the same effect. 2002 * @param other The node to test against. 2003 * @return Returns <code>true</code> if the nodes are the same, 2004 * <code>false</code> otherwise. 2005 * @since DOM Level 3 2006 */ 2007 @Override 2008 public boolean isSameNode(Node other) { 2009 // we do not use any wrapper so the answer is obvious 2010 return this == other; 2011 } 2012 2013 /** 2014 * This attribute returns the text content of this node and its 2015 * descendants. When it is defined to be null, setting it has no effect. 2016 * When set, any possible children this node may have are removed and 2017 * replaced by a single <code>Text</code> node containing the string 2018 * this attribute is set to. On getting, no serialization is performed, 2019 * the returned string does not contain any markup. No whitespace 2020 * normalization is performed, the returned string does not contain the 2021 * element content whitespaces . Similarly, on setting, no parsing is 2022 * performed either, the input string is taken as pure textual content. 2023 * <br>The string returned is made of the text content of this node 2024 * depending on its type, as defined below: 2025 * <table border='1'> 2026 * <tr> 2027 * <th>Node type</th> 2028 * <th>Content</th> 2029 * </tr> 2030 * <tr> 2031 * <td valign='top' rowspan='1' colspan='1'> 2032 * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, 2033 * DOCUMENT_FRAGMENT_NODE</td> 2034 * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> 2035 * attribute value of every child node, excluding COMMENT_NODE and 2036 * PROCESSING_INSTRUCTION_NODE nodes</td> 2037 * </tr> 2038 * <tr> 2039 * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE, 2040 * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td> 2041 * <td valign='top' rowspan='1' colspan='1'> 2042 * <code>nodeValue</code></td> 2043 * </tr> 2044 * <tr> 2045 * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td> 2046 * <td valign='top' rowspan='1' colspan='1'> 2047 * null</td> 2048 * </tr> 2049 * </table> 2050 * @exception DOMException 2051 * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. 2052 * @exception DOMException 2053 * DOMSTRING_SIZE_ERR: Raised when it would return more characters than 2054 * fit in a <code>DOMString</code> variable on the implementation 2055 * platform. 2056 * @since DOM Level 3 2057 */ 2058 @Override 2059 public void setTextContent(String textContent) 2060 throws DOMException { 2061 setNodeValue(textContent); 2062 } 2063 /** 2064 * This attribute returns the text content of this node and its 2065 * descendants. When it is defined to be null, setting it has no effect. 2066 * When set, any possible children this node may have are removed and 2067 * replaced by a single <code>Text</code> node containing the string 2068 * this attribute is set to. On getting, no serialization is performed, 2069 * the returned string does not contain any markup. No whitespace 2070 * normalization is performed, the returned string does not contain the 2071 * element content whitespaces . Similarly, on setting, no parsing is 2072 * performed either, the input string is taken as pure textual content. 2073 * <br>The string returned is made of the text content of this node 2074 * depending on its type, as defined below: 2075 * <table border='1'> 2076 * <tr> 2077 * <th>Node type</th> 2078 * <th>Content</th> 2079 * </tr> 2080 * <tr> 2081 * <td valign='top' rowspan='1' colspan='1'> 2082 * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, 2083 * DOCUMENT_FRAGMENT_NODE</td> 2084 * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> 2085 * attribute value of every child node, excluding COMMENT_NODE and 2086 * PROCESSING_INSTRUCTION_NODE nodes</td> 2087 * </tr> 2088 * <tr> 2089 * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE, 2090 * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td> 2091 * <td valign='top' rowspan='1' colspan='1'> 2092 * <code>nodeValue</code></td> 2093 * </tr> 2094 * <tr> 2095 * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td> 2096 * <td valign='top' rowspan='1' colspan='1'> 2097 * null</td> 2098 * </tr> 2099 * </table> 2100 * @exception DOMException 2101 * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. 2102 * @exception DOMException 2103 * DOMSTRING_SIZE_ERR: Raised when it would return more characters than 2104 * fit in a <code>DOMString</code> variable on the implementation 2105 * platform. 2106 * @since DOM Level 3 2107 */ 2108 @Override 2109 public String getTextContent() throws DOMException { 2110 return dtm.getStringValue(node).toString(); 2111 } 2112 2113 /** 2114 * Compares a node with this node with regard to their position in the 2115 * document. 2116 * @param other The node to compare against this node. 2117 * @return Returns how the given node is positioned relatively to this 2118 * node. 2119 * @since DOM Level 3 2120 */ 2121 @Override 2122 public short compareDocumentPosition(Node other) throws DOMException { 2123 return 0; 2124 } 2125 2126 /** 2127 * The absolute base URI of this node or <code>null</code> if undefined. 2128 * This value is computed according to . However, when the 2129 * <code>Document</code> supports the feature "HTML" , the base URI is 2130 * computed using first the value of the href attribute of the HTML BASE 2131 * element if any, and the value of the <code>documentURI</code> 2132 * attribute from the <code>Document</code> interface otherwise. 2133 * <br> When the node is an <code>Element</code>, a <code>Document</code> 2134 * or a a <code>ProcessingInstruction</code>, this attribute represents 2135 * the properties [base URI] defined in . When the node is a 2136 * <code>Notation</code>, an <code>Entity</code>, or an 2137 * <code>EntityReference</code>, this attribute represents the 2138 * properties [declaration base URI] in the . How will this be affected 2139 * by resolution of relative namespace URIs issue?It's not.Should this 2140 * only be on Document, Element, ProcessingInstruction, Entity, and 2141 * Notation nodes, according to the infoset? If not, what is it equal to 2142 * on other nodes? Null? An empty string? I think it should be the 2143 * parent's.No.Should this be read-only and computed or and actual 2144 * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and 2145 * teleconference 30 May 2001).If the base HTML element is not yet 2146 * attached to a document, does the insert change the Document.baseURI? 2147 * Yes. (F2F 26 Sep 2001) 2148 * @since DOM Level 3 2149 */ 2150 @Override 2151 public String getBaseURI() { 2152 return null; 2153 } 2154 2155 /** 2156 * DOM Level 3 2157 * Renaming node 2158 */ 2159 @Override 2160 public Node renameNode(Node n, 2161 String namespaceURI, 2162 String name) 2163 throws DOMException{ 2164 return n; 2165 } 2166 2167 2168 /** 2169 * DOM Level 3 2170 * Normalize document. 2171 */ 2172 @Override 2173 public void normalizeDocument(){ 2174 2175 } 2176 /** 2177 * The configuration used when <code>Document.normalizeDocument</code> is 2178 * invoked. 2179 * @since DOM Level 3 2180 */ 2181 @Override 2182 public DOMConfiguration getDomConfig(){ 2183 return null; 2184 } 2185 2186 2187 /** DOM Level 3 feature: documentURI */ 2188 protected String fDocumentURI; 2189 2190 /** 2191 * DOM Level 3 2192 */ 2193 @Override 2194 public void setDocumentURI(String documentURI){ 2195 fDocumentURI= documentURI; 2196 } 2197 2198 /** 2199 * DOM Level 3 2200 * The location of the document or <code>null</code> if undefined. 2201 * <br>Beware that when the <code>Document</code> supports the feature 2202 * "HTML" , the href attribute of the HTML BASE element takes precedence 2203 * over this attribute. 2204 * @since DOM Level 3 2205 */ 2206 @Override 2207 public String getDocumentURI(){ 2208 return fDocumentURI; 2209 } 2210 2211 /**DOM Level 3 feature: Document actualEncoding */ 2212 protected String actualEncoding; 2213 2214 /** 2215 * DOM Level 3 2216 * An attribute specifying the actual encoding of this document. This is 2217 * <code>null</code> otherwise. 2218 * <br> This attribute represents the property [character encoding scheme] 2219 * defined in . 2220 * @since DOM Level 3 2221 */ 2222 public String getActualEncoding() { 2223 return actualEncoding; 2224 } 2225 2226 /** 2227 * DOM Level 3 2228 * An attribute specifying the actual encoding of this document. This is 2229 * <code>null</code> otherwise. 2230 * <br> This attribute represents the property [character encoding scheme] 2231 * defined in . 2232 * @since DOM Level 3 2233 */ 2234 public void setActualEncoding(String value) { 2235 actualEncoding = value; 2236 } 2237 2238 /** 2239 * DOM Level 3 2240 */ 2241 @Override 2242 public Text replaceWholeText(String content) 2243 throws DOMException{ 2244 /* 2245 2246 if (needsSyncData()) { 2247 synchronizeData(); 2248 } 2249 2250 // make sure we can make the replacement 2251 if (!canModify(nextSibling)) { 2252 throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, 2253 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null)); 2254 } 2255 2256 Node parent = this.getParentNode(); 2257 if (content == null || content.length() == 0) { 2258 // remove current node 2259 if (parent !=null) { // check if node in the tree 2260 parent.removeChild(this); 2261 return null; 2262 } 2263 } 2264 Text currentNode = null; 2265 if (isReadOnly()){ 2266 Text newNode = this.ownerDocument().createTextNode(content); 2267 if (parent !=null) { // check if node in the tree 2268 parent.insertBefore(newNode, this); 2269 parent.removeChild(this); 2270 currentNode = newNode; 2271 } else { 2272 return newNode; 2273 } 2274 } else { 2275 this.setData(content); 2276 currentNode = this; 2277 } 2278 Node sibling = currentNode.getNextSibling(); 2279 while ( sibling !=null) { 2280 parent.removeChild(sibling); 2281 sibling = currentNode.getNextSibling(); 2282 } 2283 2284 return currentNode; 2285 */ 2286 return null; //Pending 2287 } 2288 2289 /** 2290 * DOM Level 3 2291 * Returns all text of <code>Text</code> nodes logically-adjacent text 2292 * nodes to this node, concatenated in document order. 2293 * @since DOM Level 3 2294 */ 2295 @Override 2296 public String getWholeText(){ 2297 2298 /* 2299 if (needsSyncData()) { 2300 synchronizeData(); 2301 } 2302 if (nextSibling == null) { 2303 return data; 2304 } 2305 StringBuffer buffer = new StringBuffer(); 2306 if (data != null && data.length() != 0) { 2307 buffer.append(data); 2308 } 2309 getWholeText(nextSibling, buffer); 2310 return buffer.toString(); 2311 */ 2312 return null; // PENDING 2313 2314 } 2315 2316 /** 2317 * DOM Level 3 2318 * Returns whether this text node contains whitespace in element content, 2319 * often abusively called "ignorable whitespace". 2320 */ 2321 @Override 2322 public boolean isElementContentWhitespace(){ 2323 return false; 2324 } 2325 2326 /** 2327 * NON-DOM: set the type of this attribute to be ID type. 2328 * 2329 * @param id 2330 */ 2331 public void setIdAttribute(boolean id){ 2332 //PENDING 2333 } 2334 2335 /** 2336 * DOM Level 3: register the given attribute node as an ID attribute 2337 */ 2338 @Override 2339 public void setIdAttribute(String name, boolean makeId) { 2340 //PENDING 2341 } 2342 2343 2344 /** 2345 * DOM Level 3: register the given attribute node as an ID attribute 2346 */ 2347 @Override 2348 public void setIdAttributeNode(Attr at, boolean makeId) { 2349 //PENDING 2350 } 2351 2352 /** 2353 * DOM Level 3: register the given attribute node as an ID attribute 2354 */ 2355 @Override 2356 public void setIdAttributeNS(String namespaceURI, String localName, 2357 boolean makeId) { 2358 //PENDING 2359 } 2360 /** 2361 * Method getSchemaTypeInfo. 2362 * @return TypeInfo 2363 */ 2364 @Override 2365 public TypeInfo getSchemaTypeInfo(){ 2366 return null; //PENDING 2367 } 2368 2369 @Override 2370 public boolean isId() { 2371 return false; //PENDING 2372 } 2373 2374 2375 private String xmlEncoding; 2376 @Override 2377 public String getXmlEncoding( ) { 2378 return xmlEncoding; 2379 } 2380 public void setXmlEncoding( String xmlEncoding ) { 2381 this.xmlEncoding = xmlEncoding; 2382 } 2383 2384 private boolean xmlStandalone; 2385 @Override 2386 public boolean getXmlStandalone() { 2387 return xmlStandalone; 2388 } 2389 2390 @Override 2391 public void setXmlStandalone(boolean xmlStandalone) throws DOMException { 2392 this.xmlStandalone = xmlStandalone; 2393 } 2394 2395 private String xmlVersion; 2396 @Override 2397 public String getXmlVersion() { 2398 return xmlVersion; 2399 } 2400 2401 @Override 2402 public void setXmlVersion(String xmlVersion) throws DOMException { 2403 this.xmlVersion = xmlVersion; 2404 } 2405 2406 }