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