001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: DOM2DTMdefaultNamespaceDeclarationNode.java 1225427 2011-12-29 04:33:32Z mrglavas $ 020 */ 021 022 package org.apache.xml.dtm.ref.dom2dtm; 023 024 import org.apache.xml.dtm.DTMException; 025 026 import org.w3c.dom.Attr; 027 import org.w3c.dom.Document; 028 import org.w3c.dom.Element; 029 import org.w3c.dom.NamedNodeMap; 030 import org.w3c.dom.Node; 031 import org.w3c.dom.NodeList; 032 import org.w3c.dom.TypeInfo; 033 import org.w3c.dom.UserDataHandler; 034 import org.w3c.dom.DOMException; 035 036 /** This is a kluge to let us shove a declaration for xml: into the 037 * DOM2DTM model. Basically, it creates a proxy node in DOM space to 038 * carry the additional information. This is _NOT_ a full DOM 039 * implementation, and shouldn't be one since it sits alongside the 040 * DOM rather than becoming part of the DOM model. 041 * 042 * (This used to be an internal class within DOM2DTM. Moved out because 043 * I need to perform an instanceof operation on it to support a temporary 044 * workaround in DTMManagerDefault.) 045 * 046 * %REVIEW% What if the DOM2DTM was built around a DocumentFragment and 047 * there isn't a single root element? I think this fails that case... 048 * 049 * %REVIEW% An alternative solution would be to create the node _only_ 050 * in DTM space, but given how DOM2DTM is currently written I think 051 * this is simplest. 052 * */ 053 public class DOM2DTMdefaultNamespaceDeclarationNode implements Attr,TypeInfo 054 { 055 static final String NOT_SUPPORTED_ERR="Unsupported operation on pseudonode"; 056 057 Element pseudoparent; 058 String prefix,uri,nodename; 059 int handle; 060 DOM2DTMdefaultNamespaceDeclarationNode(Element pseudoparent,String prefix,String uri,int handle) 061 { 062 this.pseudoparent=pseudoparent; 063 this.prefix=prefix; 064 this.uri=uri; 065 this.handle=handle; 066 this.nodename="xmlns:"+prefix; 067 } 068 public String getNodeName() {return nodename;} 069 public String getName() {return nodename;} 070 public String getNamespaceURI() {return "http://www.w3.org/2000/xmlns/";} 071 public String getPrefix() {return prefix;} 072 public String getLocalName() {return prefix;} 073 public String getNodeValue() {return uri;} 074 public String getValue() {return uri;} 075 public Element getOwnerElement() {return pseudoparent;} 076 077 public boolean isSupported(String feature, String version) {return false;} 078 public boolean hasChildNodes() {return false;} 079 public boolean hasAttributes() {return false;} 080 public Node getParentNode() {return null;} 081 public Node getFirstChild() {return null;} 082 public Node getLastChild() {return null;} 083 public Node getPreviousSibling() {return null;} 084 public Node getNextSibling() {return null;} 085 public boolean getSpecified() {return false;} 086 public void normalize() {return;} 087 public NodeList getChildNodes() {return null;} 088 public NamedNodeMap getAttributes() {return null;} 089 public short getNodeType() {return Node.ATTRIBUTE_NODE;} 090 public void setNodeValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} 091 public void setValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} 092 public void setPrefix(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} 093 public Node insertBefore(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);} 094 public Node replaceChild(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);} 095 public Node appendChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);} 096 public Node removeChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);} 097 public Document getOwnerDocument() {return pseudoparent.getOwnerDocument();} 098 public Node cloneNode(boolean deep) {throw new DTMException(NOT_SUPPORTED_ERR);} 099 100 /** Non-DOM method, part of the temporary kluge 101 * %REVIEW% This would be a pruning problem, but since it will always be 102 * added to the root element and we prune on elements, we shouldn't have 103 * to worry. 104 */ 105 public int getHandleOfNode() 106 { 107 return handle; 108 } 109 110 //RAMESH: PENDING=> Add proper implementation for the below DOM L3 additions 111 112 /** 113 * @see org.w3c.dom.TypeInfo#getTypeName() 114 */ 115 public String getTypeName() {return null; } 116 117 /** 118 * @see org.w3c.dom.TypeInfo#getTypeNamespace() 119 */ 120 public String getTypeNamespace() { return null;} 121 122 /** 123 * @see or.gw3c.dom.TypeInfo#isDerivedFrom(String,String,int) 124 */ 125 public boolean isDerivedFrom( String ns, String localName, int derivationMethod ) { 126 return false; 127 } 128 129 public TypeInfo getSchemaTypeInfo() { return this; } 130 131 public boolean isId( ) { return false; } 132 133 /** 134 * Associate an object to a key on this node. The object can later be 135 * retrieved from this node by calling <code>getUserData</code> with the 136 * same key. 137 * @param key The key to associate the object to. 138 * @param data The object to associate to the given key, or 139 * <code>null</code> to remove any existing association to that key. 140 * @param handler The handler to associate to that key, or 141 * <code>null</code>. 142 * @return Returns the <code>DOMObject</code> previously associated to 143 * the given key on this node, or <code>null</code> if there was none. 144 * @since DOM Level 3 145 */ 146 public Object setUserData(String key, 147 Object data, 148 UserDataHandler handler) { 149 return getOwnerDocument().setUserData( key, data, handler); 150 } 151 152 /** 153 * Retrieves the object associated to a key on a this node. The object 154 * must first have been set to this node by calling 155 * <code>setUserData</code> with the same key. 156 * @param key The key the object is associated to. 157 * @return Returns the <code>DOMObject</code> associated to the given key 158 * on this node, or <code>null</code> if there was none. 159 * @since DOM Level 3 160 */ 161 public Object getUserData(String key) { 162 return getOwnerDocument().getUserData( key); 163 } 164 165 /** 166 * This method returns a specialized object which implements the 167 * specialized APIs of the specified feature and version. The 168 * specialized object may also be obtained by using binding-specific 169 * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations. 170 * @param feature The name of the feature requested (case-insensitive). 171 * @param version This is the version number of the feature to test. If 172 * the version is <code>null</code> or the empty string, supporting 173 * any version of the feature will cause the method to return an 174 * object that supports at least one version of the feature. 175 * @return Returns an object which implements the specialized APIs of 176 * the specified feature and version, if any, or <code>null</code> if 177 * there is no object which implements interfaces associated with that 178 * feature. If the <code>DOMObject</code> returned by this method 179 * implements the <code>Node</code> interface, it must delegate to the 180 * primary core <code>Node</code> and not return results inconsistent 181 * with the primary core <code>Node</code> such as attributes, 182 * childNodes, etc. 183 * @since DOM Level 3 184 */ 185 public Object getFeature(String feature, String version) { 186 // we don't have any alternate node, either this node does the job 187 // or we don't have anything that does 188 return isSupported(feature, version) ? this : null; 189 } 190 191 /** 192 * Tests whether two nodes are equal. 193 * <br>This method tests for equality of nodes, not sameness (i.e., 194 * whether the two nodes are references to the same object) which can be 195 * tested with <code>Node.isSameNode</code>. All nodes that are the same 196 * will also be equal, though the reverse may not be true. 197 * <br>Two nodes are equal if and only if the following conditions are 198 * satisfied: The two nodes are of the same type.The following string 199 * attributes are equal: <code>nodeName</code>, <code>localName</code>, 200 * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code> 201 * , <code>baseURI</code>. This is: they are both <code>null</code>, or 202 * they have the same length and are character for character identical. 203 * The <code>attributes</code> <code>NamedNodeMaps</code> are equal. 204 * This is: they are both <code>null</code>, or they have the same 205 * length and for each node that exists in one map there is a node that 206 * exists in the other map and is equal, although not necessarily at the 207 * same index.The <code>childNodes</code> <code>NodeLists</code> are 208 * equal. This is: they are both <code>null</code>, or they have the 209 * same length and contain equal nodes at the same index. This is true 210 * for <code>Attr</code> nodes as for any other type of node. Note that 211 * normalization can affect equality; to avoid this, nodes should be 212 * normalized before being compared. 213 * <br>For two <code>DocumentType</code> nodes to be equal, the following 214 * conditions must also be satisfied: The following string attributes 215 * are equal: <code>publicId</code>, <code>systemId</code>, 216 * <code>internalSubset</code>.The <code>entities</code> 217 * <code>NamedNodeMaps</code> are equal.The <code>notations</code> 218 * <code>NamedNodeMaps</code> are equal. 219 * <br>On the other hand, the following do not affect equality: the 220 * <code>ownerDocument</code> attribute, the <code>specified</code> 221 * attribute for <code>Attr</code> nodes, the 222 * <code>isWhitespaceInElementContent</code> attribute for 223 * <code>Text</code> nodes, as well as any user data or event listeners 224 * registered on the nodes. 225 * @param arg The node to compare equality with. 226 * @param deep If <code>true</code>, recursively compare the subtrees; if 227 * <code>false</code>, compare only the nodes themselves (and its 228 * attributes, if it is an <code>Element</code>). 229 * @return If the nodes, and possibly subtrees are equal, 230 * <code>true</code> otherwise <code>false</code>. 231 * @since DOM Level 3 232 */ 233 public boolean isEqualNode(Node arg) { 234 if (arg == this) { 235 return true; 236 } 237 if (arg.getNodeType() != getNodeType()) { 238 return false; 239 } 240 // in theory nodeName can't be null but better be careful 241 // who knows what other implementations may be doing?... 242 if (getNodeName() == null) { 243 if (arg.getNodeName() != null) { 244 return false; 245 } 246 } 247 else if (!getNodeName().equals(arg.getNodeName())) { 248 return false; 249 } 250 251 if (getLocalName() == null) { 252 if (arg.getLocalName() != null) { 253 return false; 254 } 255 } 256 else if (!getLocalName().equals(arg.getLocalName())) { 257 return false; 258 } 259 260 if (getNamespaceURI() == null) { 261 if (arg.getNamespaceURI() != null) { 262 return false; 263 } 264 } 265 else if (!getNamespaceURI().equals(arg.getNamespaceURI())) { 266 return false; 267 } 268 269 if (getPrefix() == null) { 270 if (arg.getPrefix() != null) { 271 return false; 272 } 273 } 274 else if (!getPrefix().equals(arg.getPrefix())) { 275 return false; 276 } 277 278 if (getNodeValue() == null) { 279 if (arg.getNodeValue() != null) { 280 return false; 281 } 282 } 283 else if (!getNodeValue().equals(arg.getNodeValue())) { 284 return false; 285 } 286 /* 287 if (getBaseURI() == null) { 288 if (((NodeImpl) arg).getBaseURI() != null) { 289 return false; 290 } 291 } 292 else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) { 293 return false; 294 } 295 */ 296 297 return true; 298 } 299 300 /** 301 * DOM Level 3 - Experimental: 302 * Look up the namespace URI associated to the given prefix, starting from this node. 303 * Use lookupNamespaceURI(null) to lookup the default namespace 304 * 305 * @param namespaceURI 306 * @return th URI for the namespace 307 * @since DOM Level 3 308 */ 309 public String lookupNamespaceURI(String specifiedPrefix) { 310 short type = this.getNodeType(); 311 switch (type) { 312 case Node.ELEMENT_NODE : { 313 314 String namespace = this.getNamespaceURI(); 315 String prefix = this.getPrefix(); 316 if (namespace !=null) { 317 // REVISIT: is it possible that prefix is empty string? 318 if (specifiedPrefix== null && prefix==specifiedPrefix) { 319 // looking for default namespace 320 return namespace; 321 } else if (prefix != null && prefix.equals(specifiedPrefix)) { 322 // non default namespace 323 return namespace; 324 } 325 } 326 if (this.hasAttributes()) { 327 NamedNodeMap map = this.getAttributes(); 328 int length = map.getLength(); 329 for (int i=0;i<length;i++) { 330 Node attr = map.item(i); 331 String attrPrefix = attr.getPrefix(); 332 String value = attr.getNodeValue(); 333 namespace = attr.getNamespaceURI(); 334 if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) { 335 // at this point we are dealing with DOM Level 2 nodes only 336 if (specifiedPrefix == null && 337 attr.getNodeName().equals("xmlns")) { 338 // default namespace 339 return value; 340 } else if (attrPrefix !=null && 341 attrPrefix.equals("xmlns") && 342 attr.getLocalName().equals(specifiedPrefix)) { 343 // non default namespace 344 return value; 345 } 346 } 347 } 348 } 349 /* 350 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 351 if (ancestor != null) { 352 return ancestor.lookupNamespaceURI(specifiedPrefix); 353 } 354 */ 355 356 return null; 357 358 359 } 360 /* 361 case Node.DOCUMENT_NODE : { 362 return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ; 363 } 364 */ 365 case Node.ENTITY_NODE : 366 case Node.NOTATION_NODE: 367 case Node.DOCUMENT_FRAGMENT_NODE: 368 case Node.DOCUMENT_TYPE_NODE: 369 // type is unknown 370 return null; 371 case Node.ATTRIBUTE_NODE:{ 372 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) { 373 return getOwnerElement().lookupNamespaceURI(specifiedPrefix); 374 375 } 376 return null; 377 } 378 default:{ 379 /* 380 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 381 if (ancestor != null) { 382 return ancestor.lookupNamespaceURI(specifiedPrefix); 383 } 384 */ 385 return null; 386 } 387 388 } 389 } 390 391 /** 392 * DOM Level 3: Experimental 393 * This method checks if the specified <code>namespaceURI</code> is the 394 * default namespace or not. 395 * @param namespaceURI The namespace URI to look for. 396 * @return <code>true</code> if the specified <code>namespaceURI</code> 397 * is the default namespace, <code>false</code> otherwise. 398 * @since DOM Level 3 399 */ 400 public boolean isDefaultNamespace(String namespaceURI){ 401 /* 402 // REVISIT: remove casts when DOM L3 becomes REC. 403 short type = this.getNodeType(); 404 switch (type) { 405 case Node.ELEMENT_NODE: { 406 String namespace = this.getNamespaceURI(); 407 String prefix = this.getPrefix(); 408 409 // REVISIT: is it possible that prefix is empty string? 410 if (prefix == null || prefix.length() == 0) { 411 if (namespaceURI == null) { 412 return (namespace == namespaceURI); 413 } 414 return namespaceURI.equals(namespace); 415 } 416 if (this.hasAttributes()) { 417 ElementImpl elem = (ElementImpl)this; 418 NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns"); 419 if (attr != null) { 420 String value = attr.getNodeValue(); 421 if (namespaceURI == null) { 422 return (namespace == value); 423 } 424 return namespaceURI.equals(value); 425 } 426 } 427 428 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 429 if (ancestor != null) { 430 return ancestor.isDefaultNamespace(namespaceURI); 431 } 432 return false; 433 } 434 case Node.DOCUMENT_NODE:{ 435 return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI); 436 } 437 438 case Node.ENTITY_NODE : 439 case Node.NOTATION_NODE: 440 case Node.DOCUMENT_FRAGMENT_NODE: 441 case Node.DOCUMENT_TYPE_NODE: 442 // type is unknown 443 return false; 444 case Node.ATTRIBUTE_NODE:{ 445 if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) { 446 return ownerNode.isDefaultNamespace(namespaceURI); 447 448 } 449 return false; 450 } 451 default:{ 452 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 453 if (ancestor != null) { 454 return ancestor.isDefaultNamespace(namespaceURI); 455 } 456 return false; 457 } 458 459 } 460 */ 461 return false; 462 463 464 } 465 466 /** 467 * 468 * DOM Level 3 - Experimental: 469 * Look up the prefix associated to the given namespace URI, starting from this node. 470 * 471 * @param namespaceURI 472 * @return the prefix for the namespace 473 */ 474 public String lookupPrefix(String namespaceURI){ 475 476 // REVISIT: When Namespaces 1.1 comes out this may not be true 477 // Prefix can't be bound to null namespace 478 if (namespaceURI == null) { 479 return null; 480 } 481 482 short type = this.getNodeType(); 483 484 switch (type) { 485 /* 486 case Node.ELEMENT_NODE: { 487 488 String namespace = this.getNamespaceURI(); // to flip out children 489 return lookupNamespacePrefix(namespaceURI, (ElementImpl)this); 490 } 491 492 case Node.DOCUMENT_NODE:{ 493 return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI); 494 } 495 */ 496 case Node.ENTITY_NODE : 497 case Node.NOTATION_NODE: 498 case Node.DOCUMENT_FRAGMENT_NODE: 499 case Node.DOCUMENT_TYPE_NODE: 500 // type is unknown 501 return null; 502 case Node.ATTRIBUTE_NODE:{ 503 if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) { 504 return getOwnerElement().lookupPrefix(namespaceURI); 505 506 } 507 return null; 508 } 509 default:{ 510 /* 511 NodeImpl ancestor = (NodeImpl)getElementAncestor(this); 512 if (ancestor != null) { 513 return ancestor.lookupPrefix(namespaceURI); 514 } 515 */ 516 return null; 517 } 518 } 519 } 520 521 /** 522 * Returns whether this node is the same node as the given one. 523 * <br>This method provides a way to determine whether two 524 * <code>Node</code> references returned by the implementation reference 525 * the same object. When two <code>Node</code> references are references 526 * to the same object, even if through a proxy, the references may be 527 * used completely interchangably, such that all attributes have the 528 * same values and calling the same DOM method on either reference 529 * always has exactly the same effect. 530 * @param other The node to test against. 531 * @return Returns <code>true</code> if the nodes are the same, 532 * <code>false</code> otherwise. 533 * @since DOM Level 3 534 */ 535 public boolean isSameNode(Node other) { 536 // we do not use any wrapper so the answer is obvious 537 return this == other; 538 } 539 540 /** 541 * This attribute returns the text content of this node and its 542 * descendants. When it is defined to be null, setting it has no effect. 543 * When set, any possible children this node may have are removed and 544 * replaced by a single <code>Text</code> node containing the string 545 * this attribute is set to. On getting, no serialization is performed, 546 * the returned string does not contain any markup. No whitespace 547 * normalization is performed, the returned string does not contain the 548 * element content whitespaces . Similarly, on setting, no parsing is 549 * performed either, the input string is taken as pure textual content. 550 * <br>The string returned is made of the text content of this node 551 * depending on its type, as defined below: 552 * <table border='1'> 553 * <tr> 554 * <th>Node type</th> 555 * <th>Content</th> 556 * </tr> 557 * <tr> 558 * <td valign='top' rowspan='1' colspan='1'> 559 * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, 560 * DOCUMENT_FRAGMENT_NODE</td> 561 * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> 562 * attribute value of every child node, excluding COMMENT_NODE and 563 * PROCESSING_INSTRUCTION_NODE nodes</td> 564 * </tr> 565 * <tr> 566 * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE, 567 * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td> 568 * <td valign='top' rowspan='1' colspan='1'> 569 * <code>nodeValue</code></td> 570 * </tr> 571 * <tr> 572 * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td> 573 * <td valign='top' rowspan='1' colspan='1'> 574 * null</td> 575 * </tr> 576 * </table> 577 * @exception DOMException 578 * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. 579 * @exception DOMException 580 * DOMSTRING_SIZE_ERR: Raised when it would return more characters than 581 * fit in a <code>DOMString</code> variable on the implementation 582 * platform. 583 * @since DOM Level 3 584 */ 585 public void setTextContent(String textContent) 586 throws DOMException { 587 setNodeValue(textContent); 588 } 589 590 /** 591 * This attribute returns the text content of this node and its 592 * descendants. When it is defined to be null, setting it has no effect. 593 * When set, any possible children this node may have are removed and 594 * replaced by a single <code>Text</code> node containing the string 595 * this attribute is set to. On getting, no serialization is performed, 596 * the returned string does not contain any markup. No whitespace 597 * normalization is performed, the returned string does not contain the 598 * element content whitespaces . Similarly, on setting, no parsing is 599 * performed either, the input string is taken as pure textual content. 600 * <br>The string returned is made of the text content of this node 601 * depending on its type, as defined below: 602 * <table border='1'> 603 * <tr> 604 * <th>Node type</th> 605 * <th>Content</th> 606 * </tr> 607 * <tr> 608 * <td valign='top' rowspan='1' colspan='1'> 609 * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, 610 * DOCUMENT_FRAGMENT_NODE</td> 611 * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> 612 * attribute value of every child node, excluding COMMENT_NODE and 613 * PROCESSING_INSTRUCTION_NODE nodes</td> 614 * </tr> 615 * <tr> 616 * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE, 617 * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td> 618 * <td valign='top' rowspan='1' colspan='1'> 619 * <code>nodeValue</code></td> 620 * </tr> 621 * <tr> 622 * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td> 623 * <td valign='top' rowspan='1' colspan='1'> 624 * null</td> 625 * </tr> 626 * </table> 627 * @exception DOMException 628 * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. 629 * @exception DOMException 630 * DOMSTRING_SIZE_ERR: Raised when it would return more characters than 631 * fit in a <code>DOMString</code> variable on the implementation 632 * platform. 633 * @since DOM Level 3 634 */ 635 public String getTextContent() throws DOMException { 636 return getNodeValue(); // overriden in some subclasses 637 } 638 639 /** 640 * Compares a node with this node with regard to their position in the 641 * document. 642 * @param other The node to compare against this node. 643 * @return Returns how the given node is positioned relatively to this 644 * node. 645 * @since DOM Level 3 646 */ 647 public short compareDocumentPosition(Node other) throws DOMException { 648 return 0; 649 } 650 651 /** 652 * The absolute base URI of this node or <code>null</code> if undefined. 653 * This value is computed according to . However, when the 654 * <code>Document</code> supports the feature "HTML" , the base URI is 655 * computed using first the value of the href attribute of the HTML BASE 656 * element if any, and the value of the <code>documentURI</code> 657 * attribute from the <code>Document</code> interface otherwise. 658 * <br> When the node is an <code>Element</code>, a <code>Document</code> 659 * or a a <code>ProcessingInstruction</code>, this attribute represents 660 * the properties [base URI] defined in . When the node is a 661 * <code>Notation</code>, an <code>Entity</code>, or an 662 * <code>EntityReference</code>, this attribute represents the 663 * properties [declaration base URI] in the . How will this be affected 664 * by resolution of relative namespace URIs issue?It's not.Should this 665 * only be on Document, Element, ProcessingInstruction, Entity, and 666 * Notation nodes, according to the infoset? If not, what is it equal to 667 * on other nodes? Null? An empty string? I think it should be the 668 * parent's.No.Should this be read-only and computed or and actual 669 * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and 670 * teleconference 30 May 2001).If the base HTML element is not yet 671 * attached to a document, does the insert change the Document.baseURI? 672 * Yes. (F2F 26 Sep 2001) 673 * @since DOM Level 3 674 */ 675 public String getBaseURI() { 676 return null; 677 } 678 } 679