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