From 86a7dab44c0988fb69c5981dbad418634f03afda Mon Sep 17 00:00:00 2001 From: "Taylor C. Richberger" Date: Mon, 14 May 2018 18:14:42 -0600 Subject: [PATCH] fix DOM2DTM to work in J9 J9 wasn't coping with hot-patching standard library packages with a user class. This was done to work around a package private constructor. This is fixed by moving into a local package and copying the class with the package private constructor into a local copy. --- Manifest.txt | 3 +- .../internals/XalanDTMManagerPatch.java | 18 +- .../internals/dom2dtm/DOM2DTM.java} | 10 +- ...OM2DTMdefaultNamespaceDeclarationNode.java | 685 ++++++++++++++++++ 4 files changed, 702 insertions(+), 14 deletions(-) rename ext/java/{org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java => nokogiri/internals/dom2dtm/DOM2DTM.java} (99%) create mode 100644 ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java diff --git a/Manifest.txt b/Manifest.txt index aa62f20966c..d930f694362 100644 --- a/Manifest.txt +++ b/Manifest.txt @@ -81,6 +81,8 @@ ext/java/nokogiri/internals/XalanDTMManagerPatch.java ext/java/nokogiri/internals/XmlDeclHandler.java ext/java/nokogiri/internals/XmlDomParserContext.java ext/java/nokogiri/internals/XmlSaxParser.java +ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java ext/java/nokogiri/internals/c14n/AttrCompare.java ext/java/nokogiri/internals/c14n/C14nHelper.java ext/java/nokogiri/internals/c14n/CanonicalFilter.java @@ -108,7 +110,6 @@ ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java ext/java/nokogiri/internals/c14n/NodeFilter.java ext/java/nokogiri/internals/c14n/UtfHelpper.java ext/java/nokogiri/internals/c14n/XMLUtils.java -ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java ext/nokogiri/depend ext/nokogiri/extconf.rb ext/nokogiri/html_document.c diff --git a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java index c95bd33a8e6..2b61d266e81 100644 --- a/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +++ b/ext/java/nokogiri/internals/XalanDTMManagerPatch.java @@ -20,8 +20,9 @@ package nokogiri.internals; import org.apache.xml.dtm.DTM; +import nokogiri.internals.dom2dtm.DOM2DTM; +import nokogiri.internals.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode; import org.apache.xml.dtm.DTMWSFilter; -import org.apache.xml.dtm.ref.dom2dtm.DOM2DTMExt; import org.apache.xml.res.XMLErrorResources; import org.apache.xml.res.XMLMessages; import org.w3c.dom.Node; @@ -80,6 +81,11 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage if (handle != DTM.NULL) { return handle; } + } else if (thisDTM instanceof DOM2DTM) { + int handle = ((DOM2DTM) thisDTM).getHandleOfNode(node); + if (handle != DTM.NULL) { + return handle; + } } } @@ -107,11 +113,12 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage for (; p != null; p = p.getParentNode()) root = p; // DOM2DTM dtm = (DOM2DTM) getDTM(new DOMSource(root), false, null); - DOM2DTMExt dtm = getDTMExt(new DOMSource(root), false, null/*, true, true*/); + DOM2DTM dtm = getDTM(new DOMSource(root), false, null/*, true, true*/); int handle; - if (node instanceof org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode) { + if (node instanceof org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode + || node instanceof DOM2DTMdefaultNamespaceDeclarationNode) { // Can't return the same node since it's unique to a specific DTM, // but can return the equivalent node -- find the corresponding // Document Element, then ask it for the xml: namespace decl. @@ -153,12 +160,11 @@ public final class XalanDTMManagerPatch extends org.apache.xml.dtm.ref.DTMManage return handle; } - private DOM2DTMExt getDTMExt(DOMSource source, boolean unique, DTMWSFilter whiteSpaceFilter/*, boolean incremental, boolean doIndexing*/) { + private DOM2DTM getDTM(DOMSource source, boolean unique, DTMWSFilter whiteSpaceFilter/*, boolean incremental, boolean doIndexing*/) { int dtmPos = getFirstFreeDTMID(); int documentID = dtmPos << IDENT_DTM_NODE_BITS; - //DOM2DTM dtm = new DOM2DTM(this, source, documentID, whiteSpaceFilter, m_xsf, true); - DOM2DTMExt dtm = new DOM2DTMExt(this, source, documentID, whiteSpaceFilter, m_xsf, true); + DOM2DTM dtm = new DOM2DTM(this, source, documentID, whiteSpaceFilter, m_xsf, true); addDTM(dtm, dtmPos, 0); return dtm; diff --git a/ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java b/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java similarity index 99% rename from ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java rename to ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java index 526f2ac3a02..7c2b08da24f 100644 --- a/ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java +++ b/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java @@ -15,10 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* - * $Id: DOM2DTM.java 478671 2006-11-23 21:00:31Z minchau $ - */ -package org.apache.xml.dtm.ref.dom2dtm; +package nokogiri.internals.dom2dtm; import javax.xml.transform.SourceLocator; import javax.xml.transform.dom.DOMSource; @@ -30,7 +27,6 @@ import org.apache.xml.dtm.ref.DTMManagerDefault; import org.apache.xml.dtm.ref.ExpandedNameTable; import org.apache.xml.dtm.ref.IncrementalSAXSource; -//import org.apache.xml.dtm.ref.dom2dtm.DOM2DTMdefaultNamespaceDeclarationNode; import org.apache.xml.res.XMLErrorResources; import org.apache.xml.res.XMLMessages; import org.apache.xml.utils.FastStringBuffer; @@ -62,7 +58,7 @@ * mutation. If you alter the DOM after wrapping DOM2DTM around it, * all bets are off. * */ -public class DOM2DTMExt extends DTMDefaultBaseIterators +public class DOM2DTM extends DTMDefaultBaseIterators { // static final boolean JJK_DEBUG=false; // static final boolean JJK_NEWCODE=true; @@ -114,7 +110,7 @@ public class DOM2DTMExt extends DTMDefaultBaseIterators * @param doIndexing true if the caller considers it worth it to use * indexing schemes. */ - public DOM2DTMExt(DTMManager mgr, DOMSource domSource, + public DOM2DTM(DTMManager mgr, DOMSource domSource, int dtmIdentity, DTMWSFilter whiteSpaceFilter, XMLStringFactory xstringfactory, boolean doIndexing) diff --git a/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java b/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java new file mode 100644 index 00000000000..42a91c52bd3 --- /dev/null +++ b/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java @@ -0,0 +1,685 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * $Id: DOM2DTMdefaultNamespaceDeclarationNode.java,v 1.2.4.1 2005/09/15 08:15:11 suresh_emailid Exp $ + */ + +// This is copied directly out of the original +// com.sun.org.apache.xml.internal.dtm.ref.dom2dtm path to allow modifying +// DOM2DTM and working around package private constructors. Other than the +// package declaration, this class is unmodified + +package nokogiri.internals.dom2dtm; + +import org.apache.xml.dtm.DTMException; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.TypeInfo; +import org.w3c.dom.UserDataHandler; +import org.w3c.dom.DOMException; + +/** This is a kluge to let us shove a declaration for xml: into the + * DOM2DTM model. Basically, it creates a proxy node in DOM space to + * carry the additional information. This is _NOT_ a full DOM + * implementation, and shouldn't be one since it sits alongside the + * DOM rather than becoming part of the DOM model. + * + * (This used to be an internal class within DOM2DTM. Moved out because + * I need to perform an instanceof operation on it to support a temporary + * workaround in DTMManagerDefault.) + * + * %REVIEW% What if the DOM2DTM was built around a DocumentFragment and + * there isn't a single root element? I think this fails that case... + * + * %REVIEW% An alternative solution would be to create the node _only_ + * in DTM space, but given how DOM2DTM is currently written I think + * this is simplest. + * */ +public class DOM2DTMdefaultNamespaceDeclarationNode implements Attr,TypeInfo +{ + final String NOT_SUPPORTED_ERR="Unsupported operation on pseudonode"; + + Element pseudoparent; + String prefix,uri,nodename; + int handle; + DOM2DTMdefaultNamespaceDeclarationNode(Element pseudoparent,String prefix,String uri,int handle) + { + this.pseudoparent=pseudoparent; + this.prefix=prefix; + this.uri=uri; + this.handle=handle; + this.nodename="xmlns:"+prefix; + } + public String getNodeName() {return nodename;} + public String getName() {return nodename;} + public String getNamespaceURI() {return "http://www.w3.org/2000/xmlns/";} + public String getPrefix() {return prefix;} + public String getLocalName() {return prefix;} + public String getNodeValue() {return uri;} + public String getValue() {return uri;} + public Element getOwnerElement() {return pseudoparent;} + + public boolean isSupported(String feature, String version) {return false;} + public boolean hasChildNodes() {return false;} + public boolean hasAttributes() {return false;} + public Node getParentNode() {return null;} + public Node getFirstChild() {return null;} + public Node getLastChild() {return null;} + public Node getPreviousSibling() {return null;} + public Node getNextSibling() {return null;} + public boolean getSpecified() {return false;} + public void normalize() {return;} + public NodeList getChildNodes() {return null;} + public NamedNodeMap getAttributes() {return null;} + public short getNodeType() {return Node.ATTRIBUTE_NODE;} + public void setNodeValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} + public void setValue(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} + public void setPrefix(String value) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node insertBefore(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node replaceChild(Node a, Node b) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node appendChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Node removeChild(Node a) {throw new DTMException(NOT_SUPPORTED_ERR);} + public Document getOwnerDocument() {return pseudoparent.getOwnerDocument();} + public Node cloneNode(boolean deep) {throw new DTMException(NOT_SUPPORTED_ERR);} + + /** Non-DOM method, part of the temporary kluge + * %REVIEW% This would be a pruning problem, but since it will always be + * added to the root element and we prune on elements, we shouldn't have + * to worry. + */ + public int getHandleOfNode() + { + return handle; + } + + //RAMESH: PENDING=> Add proper implementation for the below DOM L3 additions + + /** + * @see org.w3c.dom.TypeInfo#getTypeName() + */ + public String getTypeName() {return null; } + + /** + * @see org.w3c.dom.TypeInfo#getTypeNamespace() + */ + public String getTypeNamespace() { return null;} + + /** + * @see or.gw3c.dom.TypeInfo#isDerivedFrom(String,String,int) + */ + public boolean isDerivedFrom( String ns, String localName, int derivationMethod ) { + return false; + } + + public TypeInfo getSchemaTypeInfo() { return this; } + + public boolean isId( ) { return false; } + + /** + * Associate an object to a key on this node. The object can later be + * retrieved from this node by calling getUserData with the + * same key. + * @param key The key to associate the object to. + * @param data The object to associate to the given key, or + * null to remove any existing association to that key. + * @param handler The handler to associate to that key, or + * null. + * @return Returns the DOMObject previously associated to + * the given key on this node, or null if there was none. + * @since DOM Level 3 + */ + public Object setUserData(String key, + Object data, + UserDataHandler handler) { + return getOwnerDocument().setUserData( key, data, handler); + } + + /** + * Retrieves the object associated to a key on a this node. The object + * must first have been set to this node by calling + * setUserData with the same key. + * @param key The key the object is associated to. + * @return Returns the DOMObject associated to the given key + * on this node, or null if there was none. + * @since DOM Level 3 + */ + public Object getUserData(String key) { + return getOwnerDocument().getUserData( key); + } + + /** + * This method returns a specialized object which implements the + * specialized APIs of the specified feature and version. The + * specialized object may also be obtained by using binding-specific + * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations. + * @param feature The name of the feature requested (case-insensitive). + * @param version This is the version number of the feature to test. If + * the version is null or the empty string, supporting + * any version of the feature will cause the method to return an + * object that supports at least one version of the feature. + * @return Returns an object which implements the specialized APIs of + * the specified feature and version, if any, or null if + * there is no object which implements interfaces associated with that + * feature. If the DOMObject returned by this method + * implements the Node interface, it must delegate to the + * primary core Node and not return results inconsistent + * with the primary core Node such as attributes, + * childNodes, etc. + * @since DOM Level 3 + */ + public Object getFeature(String feature, String version) { + // we don't have any alternate node, either this node does the job + // or we don't have anything that does + return isSupported(feature, version) ? this : null; + } + + /** + * Tests whether two nodes are equal. + *
This method tests for equality of nodes, not sameness (i.e., + * whether the two nodes are references to the same object) which can be + * tested with Node.isSameNode. All nodes that are the same + * will also be equal, though the reverse may not be true. + *
Two nodes are equal if and only if the following conditions are + * satisfied: The two nodes are of the same type.The following string + * attributes are equal: nodeName, localName, + * namespaceURI, prefix, nodeValue + * , baseURI. This is: they are both null, or + * they have the same length and are character for character identical. + * The attributes NamedNodeMaps are equal. + * This is: they are both null, or they have the same + * length and for each node that exists in one map there is a node that + * exists in the other map and is equal, although not necessarily at the + * same index.The childNodes NodeLists are + * equal. This is: they are both null, or they have the + * same length and contain equal nodes at the same index. This is true + * for Attr nodes as for any other type of node. Note that + * normalization can affect equality; to avoid this, nodes should be + * normalized before being compared. + *
For two DocumentType nodes to be equal, the following + * conditions must also be satisfied: The following string attributes + * are equal: publicId, systemId, + * internalSubset.The entities + * NamedNodeMaps are equal.The notations + * NamedNodeMaps are equal. + *
On the other hand, the following do not affect equality: the + * ownerDocument attribute, the specified + * attribute for Attr nodes, the + * isWhitespaceInElementContent attribute for + * Text nodes, as well as any user data or event listeners + * registered on the nodes. + * @param arg The node to compare equality with. + * @param deep If true, recursively compare the subtrees; if + * false, compare only the nodes themselves (and its + * attributes, if it is an Element). + * @return If the nodes, and possibly subtrees are equal, + * true otherwise false. + * @since DOM Level 3 + */ + public boolean isEqualNode(Node arg) { + if (arg == this) { + return true; + } + if (arg.getNodeType() != getNodeType()) { + return false; + } + // in theory nodeName can't be null but better be careful + // who knows what other implementations may be doing?... + if (getNodeName() == null) { + if (arg.getNodeName() != null) { + return false; + } + } + else if (!getNodeName().equals(arg.getNodeName())) { + return false; + } + + if (getLocalName() == null) { + if (arg.getLocalName() != null) { + return false; + } + } + else if (!getLocalName().equals(arg.getLocalName())) { + return false; + } + + if (getNamespaceURI() == null) { + if (arg.getNamespaceURI() != null) { + return false; + } + } + else if (!getNamespaceURI().equals(arg.getNamespaceURI())) { + return false; + } + + if (getPrefix() == null) { + if (arg.getPrefix() != null) { + return false; + } + } + else if (!getPrefix().equals(arg.getPrefix())) { + return false; + } + + if (getNodeValue() == null) { + if (arg.getNodeValue() != null) { + return false; + } + } + else if (!getNodeValue().equals(arg.getNodeValue())) { + return false; + } + /* + if (getBaseURI() == null) { + if (((NodeImpl) arg).getBaseURI() != null) { + return false; + } + } + else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) { + return false; + } +*/ + + return true; + } + + /** + * DOM Level 3 - Experimental: + * Look up the namespace URI associated to the given prefix, starting from this node. + * Use lookupNamespaceURI(null) to lookup the default namespace + * + * @param namespaceURI + * @return th URI for the namespace + * @since DOM Level 3 + */ + public String lookupNamespaceURI(String specifiedPrefix) { + short type = this.getNodeType(); + switch (type) { + case Node.ELEMENT_NODE : { + + String namespace = this.getNamespaceURI(); + String prefix = this.getPrefix(); + if (namespace !=null) { + // REVISIT: is it possible that prefix is empty string? + if (specifiedPrefix== null && prefix==specifiedPrefix) { + // looking for default namespace + return namespace; + } else if (prefix != null && prefix.equals(specifiedPrefix)) { + // non default namespace + return namespace; + } + } + if (this.hasAttributes()) { + NamedNodeMap map = this.getAttributes(); + int length = map.getLength(); + for (int i=0;inamespaceURI is the + * default namespace or not. + * @param namespaceURI The namespace URI to look for. + * @return true if the specified namespaceURI + * is the default namespace, false otherwise. + * @since DOM Level 3 + */ + public boolean isDefaultNamespace(String namespaceURI){ + /* + // REVISIT: remove casts when DOM L3 becomes REC. + short type = this.getNodeType(); + switch (type) { + case Node.ELEMENT_NODE: { + String namespace = this.getNamespaceURI(); + String prefix = this.getPrefix(); + + // REVISIT: is it possible that prefix is empty string? + if (prefix == null || prefix.length() == 0) { + if (namespaceURI == null) { + return (namespace == namespaceURI); + } + return namespaceURI.equals(namespace); + } + if (this.hasAttributes()) { + ElementImpl elem = (ElementImpl)this; + NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns"); + if (attr != null) { + String value = attr.getNodeValue(); + if (namespaceURI == null) { + return (namespace == value); + } + return namespaceURI.equals(value); + } + } + + NodeImpl ancestor = (NodeImpl)getElementAncestor(this); + if (ancestor != null) { + return ancestor.isDefaultNamespace(namespaceURI); + } + return false; + } + case Node.DOCUMENT_NODE:{ + return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI); + } + + case Node.ENTITY_NODE : + case Node.NOTATION_NODE: + case Node.DOCUMENT_FRAGMENT_NODE: + case Node.DOCUMENT_TYPE_NODE: + // type is unknown + return false; + case Node.ATTRIBUTE_NODE:{ + if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) { + return ownerNode.isDefaultNamespace(namespaceURI); + + } + return false; + } + default:{ + NodeImpl ancestor = (NodeImpl)getElementAncestor(this); + if (ancestor != null) { + return ancestor.isDefaultNamespace(namespaceURI); + } + return false; + } + + } +*/ + return false; + + + } + + /** + * + * DOM Level 3 - Experimental: + * Look up the prefix associated to the given namespace URI, starting from this node. + * + * @param namespaceURI + * @return the prefix for the namespace + */ + public String lookupPrefix(String namespaceURI){ + + // REVISIT: When Namespaces 1.1 comes out this may not be true + // Prefix can't be bound to null namespace + if (namespaceURI == null) { + return null; + } + + short type = this.getNodeType(); + + switch (type) { +/* + case Node.ELEMENT_NODE: { + + String namespace = this.getNamespaceURI(); // to flip out children + return lookupNamespacePrefix(namespaceURI, (ElementImpl)this); + } + + case Node.DOCUMENT_NODE:{ + return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI); + } +*/ + case Node.ENTITY_NODE : + case Node.NOTATION_NODE: + case Node.DOCUMENT_FRAGMENT_NODE: + case Node.DOCUMENT_TYPE_NODE: + // type is unknown + return null; + case Node.ATTRIBUTE_NODE:{ + if (this.getOwnerElement().getNodeType() == Node.ELEMENT_NODE) { + return getOwnerElement().lookupPrefix(namespaceURI); + + } + return null; + } + default:{ +/* + NodeImpl ancestor = (NodeImpl)getElementAncestor(this); + if (ancestor != null) { + return ancestor.lookupPrefix(namespaceURI); + } +*/ + return null; + } + } + } + + /** + * Returns whether this node is the same node as the given one. + *
This method provides a way to determine whether two + * Node references returned by the implementation reference + * the same object. When two Node references are references + * to the same object, even if through a proxy, the references may be + * used completely interchangably, such that all attributes have the + * same values and calling the same DOM method on either reference + * always has exactly the same effect. + * @param other The node to test against. + * @return Returns true if the nodes are the same, + * false otherwise. + * @since DOM Level 3 + */ + public boolean isSameNode(Node other) { + // we do not use any wrapper so the answer is obvious + return this == other; + } + + /** + * This attribute returns the text content of this node and its + * descendants. When it is defined to be null, setting it has no effect. + * When set, any possible children this node may have are removed and + * replaced by a single Text node containing the string + * this attribute is set to. On getting, no serialization is performed, + * the returned string does not contain any markup. No whitespace + * normalization is performed, the returned string does not contain the + * element content whitespaces . Similarly, on setting, no parsing is + * performed either, the input string is taken as pure textual content. + *
The string returned is made of the text content of this node + * depending on its type, as defined below: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Node typeContent
+ * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, + * DOCUMENT_FRAGMENT_NODEconcatenation of the textContent + * attribute value of every child node, excluding COMMENT_NODE and + * PROCESSING_INSTRUCTION_NODE nodes
ATTRIBUTE_NODE, TEXT_NODE, + * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE + * nodeValue
DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE + * null
+ * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters than + * fit in a DOMString variable on the implementation + * platform. + * @since DOM Level 3 + */ + public void setTextContent(String textContent) + throws DOMException { + setNodeValue(textContent); + } + + /** + * This attribute returns the text content of this node and its + * descendants. When it is defined to be null, setting it has no effect. + * When set, any possible children this node may have are removed and + * replaced by a single Text node containing the string + * this attribute is set to. On getting, no serialization is performed, + * the returned string does not contain any markup. No whitespace + * normalization is performed, the returned string does not contain the + * element content whitespaces . Similarly, on setting, no parsing is + * performed either, the input string is taken as pure textual content. + *
The string returned is made of the text content of this node + * depending on its type, as defined below: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Node typeContent
+ * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, + * DOCUMENT_FRAGMENT_NODEconcatenation of the textContent + * attribute value of every child node, excluding COMMENT_NODE and + * PROCESSING_INSTRUCTION_NODE nodes
ATTRIBUTE_NODE, TEXT_NODE, + * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE + * nodeValue
DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE + * null
+ * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters than + * fit in a DOMString variable on the implementation + * platform. + * @since DOM Level 3 + */ + public String getTextContent() throws DOMException { + return getNodeValue(); // overriden in some subclasses + } + + /** + * Compares a node with this node with regard to their position in the + * document. + * @param other The node to compare against this node. + * @return Returns how the given node is positioned relatively to this + * node. + * @since DOM Level 3 + */ + public short compareDocumentPosition(Node other) throws DOMException { + return 0; + } + + /** + * The absolute base URI of this node or null if undefined. + * This value is computed according to . However, when the + * Document supports the feature "HTML" , the base URI is + * computed using first the value of the href attribute of the HTML BASE + * element if any, and the value of the documentURI + * attribute from the Document interface otherwise. + *
When the node is an Element, a Document + * or a a ProcessingInstruction, this attribute represents + * the properties [base URI] defined in . When the node is a + * Notation, an Entity, or an + * EntityReference, this attribute represents the + * properties [declaration base URI] in the . How will this be affected + * by resolution of relative namespace URIs issue?It's not.Should this + * only be on Document, Element, ProcessingInstruction, Entity, and + * Notation nodes, according to the infoset? If not, what is it equal to + * on other nodes? Null? An empty string? I think it should be the + * parent's.No.Should this be read-only and computed or and actual + * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and + * teleconference 30 May 2001).If the base HTML element is not yet + * attached to a document, does the insert change the Document.baseURI? + * Yes. (F2F 26 Sep 2001) + * @since DOM Level 3 + */ + public String getBaseURI() { + return null; + } +}