FileDocCategorySizeDatePackage
CoreDocumentImpl.javaAPI DocApache Xerces 3.0.1100930Fri Sep 14 20:33:56 BST 2007org.apache.xerces.dom

CoreDocumentImpl

public class CoreDocumentImpl extends ParentNode implements Document
The Document interface represents the entire HTML or XML document. Conceptually, it is the root of the document tree, and provides the primary access to the document's data.

Since elements, text nodes, comments, processing instructions, etc. cannot exist outside the context of a Document, the Document interface also contains the factory methods needed to create these objects. The Node objects created have a ownerDocument attribute which associates them with the Document within whose context they were created.

The CoreDocumentImpl class only implements the DOM Core. Additional modules are supported by the more complete DocumentImpl subclass.

Note: When any node in the document is serialized, the entire document is serialized along with it.

xerces.internal
author
Arnaud Le Hors, IBM
author
Joe Kesselman, IBM
author
Andy Clark, IBM
author
Ralf Pfeiffer, IBM
version
$Id: CoreDocumentImpl.java 515302 2007-03-06 21:07:10Z mrglavas $
since
PR-DOM-Level-1-19980818.

Fields Summary
static final long
serialVersionUID
Serialization version.
protected DocumentTypeImpl
docType
Document type.
protected ElementImpl
docElement
Document element.
transient NodeListCache
fFreeNLCache
NodeListCache free list
protected String
encoding
Experimental DOM Level 3 feature: Document encoding
protected String
actualEncoding
Experimental DOM Level 3 feature: Document actualEncoding
protected String
version
Experimental DOM Level 3 feature: Document version
protected boolean
standalone
Experimental DOM Level 3 feature: Document standalone
protected String
fDocumentURI
Experimental DOM Level 3 feature: documentURI
protected Hashtable
userData
Table for user data attached to this document nodes.
protected Hashtable
identifiers
Identifiers.
transient DOMNormalizer
domNormalizer
transient DOMConfigurationImpl
fConfiguration
transient Object
fXPathEvaluator
private static final int[]
kidOK
Table for quick check of child insertion.
protected int
changes
Number of alterations made to this document since its creation. Serves as a "dirty bit" so that live objects such as NodeList can recognize when an alteration has been made and discard its cached state information.

Any method that alters the tree structure MUST cause or be accompanied by a call to changed(), to inform it that any outstanding NodeLists may have to be updated.

(Required because NodeList is simultaneously "live" and integer- indexed -- a bad decision in the DOM's design.)

Note that changes which do not affect the tree's structure -- changing the node's name, for example -- do _not_ have to call changed().

Alternative implementation would be to use a cryptographic Digest value rather than a count. This would have the advantage that "harmless" changes (those producing equal() trees) would not force NodeList to resynchronize. Disadvantage is that it's slightly more prone to "false negatives", though that's the difference between "wildly unlikely" and "absurdly unlikely". IF we start maintaining digests, we should consider taking advantage of them. Note: This used to be done a node basis, so that we knew what subtree changed. But since only DeepNodeList really use this today, the gain appears to be really small compared to the cost of having an int on every (parent) node plus having to walk up the tree all the way to the root to mark the branch as changed everytime a node is changed. So we now have a single counter global to the document. It means that some objects may flush their cache more often than necessary, but this makes nodes smaller and only the document needs to be marked as changed.

protected boolean
allowGrammarAccess
Allow grammar access.
protected boolean
errorChecking
Bypass error checking.
protected boolean
xmlVersionChanged
private int
documentNumber
The following are required for compareDocumentPosition
private int
nodeCounter
private Hashtable
nodeTable
private boolean
xml11Version
Constructors Summary
public CoreDocumentImpl()
NON-DOM: Actually creating a Document is outside the DOM's spec, since it has to operate in terms of a particular implementation.

 //by default 1.0
    //
    // Static initialization
    //

     

        kidOK = new int[13];

        kidOK[DOCUMENT_NODE] =
        1 << ELEMENT_NODE | 1 << PROCESSING_INSTRUCTION_NODE |
        1 << COMMENT_NODE | 1 << DOCUMENT_TYPE_NODE;

        kidOK[DOCUMENT_FRAGMENT_NODE] =
        kidOK[ENTITY_NODE] =
        kidOK[ENTITY_REFERENCE_NODE] =
        kidOK[ELEMENT_NODE] =
        1 << ELEMENT_NODE | 1 << PROCESSING_INSTRUCTION_NODE |
        1 << COMMENT_NODE | 1 << TEXT_NODE |
        1 << CDATA_SECTION_NODE | 1 << ENTITY_REFERENCE_NODE ;


        kidOK[ATTRIBUTE_NODE] =
        1 << TEXT_NODE | 1 << ENTITY_REFERENCE_NODE;

        kidOK[DOCUMENT_TYPE_NODE] =
        kidOK[PROCESSING_INSTRUCTION_NODE] =
        kidOK[COMMENT_NODE] =
        kidOK[TEXT_NODE] =
        kidOK[CDATA_SECTION_NODE] =
        kidOK[NOTATION_NODE] =
        0;

    
        this(false);
    
public CoreDocumentImpl(boolean grammarAccess)
Constructor.

        super(null);
        ownerDocument = this;
        allowGrammarAccess = grammarAccess;
    
public CoreDocumentImpl(DocumentType doctype)
For DOM2 support. The createDocument factory method is in DOMImplementation.

        this(doctype, false);
    
public CoreDocumentImpl(DocumentType doctype, boolean grammarAccess)
For DOM2 support.

        this(grammarAccess);
        if (doctype != null) {
            DocumentTypeImpl doctypeImpl;
            try {
                doctypeImpl = (DocumentTypeImpl) doctype;
            } catch (ClassCastException e) {
                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
                throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
            }
            doctypeImpl.ownerDocument = this;
            appendChild(doctype);
        }
    
Methods Summary
public voidabort()
DOM Level 3 WD - Experimental. If the document is currently being loaded as a result of the method load being invoked the loading and parsing is immediately aborted. The possibly partial result of parsing the document is discarded and the document is cleared.

    
protected voidaddEventListener(NodeImpl node, java.lang.String type, org.w3c.dom.events.EventListener listener, boolean useCapture)

        // does nothing by default - overidden in subclass
    
public org.w3c.dom.NodeadoptNode(org.w3c.dom.Node source)
DOM Level 3 WD - Experimental Change the node's ownerDocument, and its subtree, to this Document

param
source The node to adopt.
see
#importNode

        NodeImpl node;
		Hashtable userData = null;
        try {
            node = (NodeImpl) source;
        } catch (ClassCastException e) {
            // source node comes from a different DOMImplementation
            return null;
        }
        
        // Return null if the source is null
        
        if (source == null ) {
        	return null;
        } else if (source != null && source.getOwnerDocument() != null) {

            DOMImplementation thisImpl = this.getImplementation();
            DOMImplementation otherImpl = source.getOwnerDocument().getImplementation();
            
            // when the source node comes from a different implementation.
            if (thisImpl != otherImpl) {
            
                // Adopting from a DefferedDOM to DOM
                if (thisImpl instanceof org.apache.xerces.dom.DOMImplementationImpl &&
                        otherImpl instanceof org.apache.xerces.dom.DeferredDOMImplementationImpl) {
                    // traverse the DOM and expand deffered nodes and then allow adoption
                    undeferChildren (node);
                } else if ( thisImpl instanceof org.apache.xerces.dom.DeferredDOMImplementationImpl
                        && otherImpl instanceof org.apache.xerces.dom.DOMImplementationImpl) {
                    // Adopting from a DOM into a DefferedDOM, this should be okay
                } else {
                    // Adopting between two dissimilar DOM's is not allowed
                    return null;  
                }
        	}
        }
        
        switch (node.getNodeType()) {
            case ATTRIBUTE_NODE: {
                AttrImpl attr = (AttrImpl) node;
                // remove node from wherever it is
                if( attr.getOwnerElement() != null){
                    //1. owner element attribute is set to null
                    attr.getOwnerElement().removeAttributeNode(attr);
                }
                //2. specified flag is set to true
                attr.isSpecified(true);
				userData = node.getUserDataRecord();

                //3. change ownership
                attr.setOwnerDocument(this);
				if(userData != null )
					setUserDataTable(node,userData);
                break;
            }
            //entity, notation nodes are read only nodes.. so they can't be adopted.
            //runtime will fall through to NOTATION_NODE
            case ENTITY_NODE:
            case NOTATION_NODE:{
                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
                throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);

            }
            //document, documentype nodes can't be adopted.
            //runtime will fall through to DocumentTypeNode
            case DOCUMENT_NODE:
            case DOCUMENT_TYPE_NODE: {
                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
            }
            case ENTITY_REFERENCE_NODE: {
				userData = node.getUserDataRecord();
                // remove node from wherever it is
                Node parent = node.getParentNode();
                if (parent != null) {
                    parent.removeChild(source);
                }
                // discard its replacement value
                Node child;
                while ((child = node.getFirstChild()) != null) {
                    node.removeChild(child);
                }
                // change ownership
                node.setOwnerDocument(this);
				if(userData != null)
					setUserDataTable(node,userData);
                // set its new replacement value if any
                if (docType == null) {
                    break;
                }
                NamedNodeMap entities = docType.getEntities();
                Node entityNode = entities.getNamedItem(node.getNodeName());
                if (entityNode == null) {
                    break;
                }
                for (child = entityNode.getFirstChild();
                child != null; child = child.getNextSibling()) {
                    Node childClone = child.cloneNode(true);
                    node.appendChild(childClone);
                }
                break;
            }
            case ELEMENT_NODE: {
				userData = node.getUserDataRecord();
                // remove node from wherever it is
                Node parent = node.getParentNode();
                if (parent != null) {
                    parent.removeChild(source);
                }
                // change ownership
                node.setOwnerDocument(this);
				if(userData != null)
					setUserDataTable(node,userData);
                // reconcile default attributes
                ((ElementImpl)node).reconcileDefaultAttributes();
                break;
            }
            default: {
				userData = node.getUserDataRecord();
                // remove node from wherever it is
                Node parent = node.getParentNode();
                if (parent != null) {
                    parent.removeChild(source);
                }
                // change ownership
                node.setOwnerDocument(this);
				if(userData != null)
					setUserDataTable(node,userData);
            }
        }

		//DOM L3 Core CR
		//http://www.w3.org/TR/2003/CR-DOM-Level-3-Core-20031107/core.html#UserDataHandler-ADOPTED
		if(userData != null)
			callUserDataHandlers(source, null, UserDataHandler.NODE_ADOPTED,userData);

        return node;
    
protected voidcallUserDataHandlers(org.w3c.dom.Node n, org.w3c.dom.Node c, short operation)
Call user data handlers when a node is deleted (finalized)

param
n The node this operation applies to.
param
c The copy node or null.
param
operation The operation - import, clone, or delete.

        if (userData == null) {
            return;
        }
        //Hashtable t = (Hashtable) userData.get(n);
		if(n instanceof NodeImpl){
			Hashtable t = ((NodeImpl)n).getUserDataRecord();
			if (t == null || t.isEmpty()) {
				return;
			}
			callUserDataHandlers(n, c, operation,t);
		}
    
voidcallUserDataHandlers(org.w3c.dom.Node n, org.w3c.dom.Node c, short operation, java.util.Hashtable userData)
Call user data handlers when a node is deleted (finalized)

param
n The node this operation applies to.
param
c The copy node or null.
param
operation The operation - import, clone, or delete.
param
handlers Data associated with n.

        if (userData == null || userData.isEmpty()) {
            return;
        }
        Enumeration keys = userData.keys();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            UserDataRecord r = (UserDataRecord) userData.get(key);
            if (r.fHandler != null) {
                r.fHandler.handle(operation, key, r.fData, n, c);
            }
        }
    
protected voidchanged()
Denotes that this node has changed.

        changes++;
    
protected intchanges()
Returns the number of changes to this node.

        return changes;
    
protected final voidcheckDOMNSErr(java.lang.String prefix, java.lang.String namespace)

        if (errorChecking) {
            if (namespace == null) {
                String msg =
                DOMMessageFormatter.formatMessage(
                DOMMessageFormatter.DOM_DOMAIN,
                "NAMESPACE_ERR",
                null);
                throw new DOMException(DOMException.NAMESPACE_ERR, msg);
            }
            else if (prefix.equals("xml")
            && !namespace.equals(NamespaceContext.XML_URI)) {
                String msg =
                DOMMessageFormatter.formatMessage(
                DOMMessageFormatter.DOM_DOMAIN,
                "NAMESPACE_ERR",
                null);
                throw new DOMException(DOMException.NAMESPACE_ERR, msg);
            }
            else if (
            prefix.equals("xmlns")
            && !namespace.equals(NamespaceContext.XMLNS_URI)
            || (!prefix.equals("xmlns")
            && namespace.equals(NamespaceContext.XMLNS_URI))) {
                String msg =
                DOMMessageFormatter.formatMessage(
                DOMMessageFormatter.DOM_DOMAIN,
                "NAMESPACE_ERR",
                null);
                throw new DOMException(DOMException.NAMESPACE_ERR, msg);
            }
        }
    
protected final voidcheckNamespaceWF(java.lang.String qname, int colon1, int colon2)
Call user data handlers to let them know the nodes they are related to are being deleted. The alternative would be to do that on Node but because the nodes are used as the keys we have a reference to them that prevents them from being gc'ed until the document is. At the same time, doing it here has the advantage of avoiding a finalize() method on Node, which would affect all nodes and not just the ones that have a user data.


        if (!errorChecking) {
            return;
        }
        // it is an error for NCName to have more than one ':'
        // check if it is valid QName [Namespace in XML production 6]
        // :camera , nikon:camera:minolta, camera:
        if (colon1 == 0 || colon1 == qname.length() - 1 || colon2 != colon1) {
            String msg =
            DOMMessageFormatter.formatMessage(
            DOMMessageFormatter.DOM_DOMAIN,
            "NAMESPACE_ERR",
            null);
            throw new DOMException(DOMException.NAMESPACE_ERR, msg);
        }
    
protected final voidcheckQName(java.lang.String prefix, java.lang.String local)
Checks if the given qualified name is legal with respect to the version of XML to which this document must conform.

param
prefix prefix of qualified name
param
local local part of qualified name

        if (!errorChecking) {
            return;
        }

		// check that both prefix and local part match NCName
        boolean validNCName = false;
        if (!xml11Version) {
            validNCName = (prefix == null || XMLChar.isValidNCName(prefix))
                && XMLChar.isValidNCName(local);
        }
        else {
            validNCName = (prefix == null || XML11Char.isXML11ValidNCName(prefix))
                && XML11Char.isXML11ValidNCName(local);
        }

        if (!validNCName) {
            // REVISIT: add qname parameter to the message
            String msg =
            DOMMessageFormatter.formatMessage(
            DOMMessageFormatter.DOM_DOMAIN,
            "INVALID_CHARACTER_ERR",
            null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
    
protected final voidclearIdentifiers()
Remove all identifiers from the ID table

        if (identifiers != null){
            identifiers.clear();
        }
    
public java.lang.Objectclone()
Clone.

        CoreDocumentImpl newdoc = (CoreDocumentImpl) super.clone();
        newdoc.docType = null;
        newdoc.docElement = null;
        return newdoc;
    
public org.w3c.dom.NodecloneNode(boolean deep)
Deep-clone a document, including fixing ownerDoc for the cloned children. Note that this requires bypassing the WRONG_DOCUMENT_ERR protection. I've chosen to implement it by calling importNode which is DOM Level 2.

return
org.w3c.dom.Node
param
deep boolean, iff true replicate children


        CoreDocumentImpl newdoc = new CoreDocumentImpl();
        callUserDataHandlers(this, newdoc, UserDataHandler.NODE_CLONED);
        cloneNode(newdoc, deep);

        return newdoc;

    
protected voidcloneNode(org.apache.xerces.dom.CoreDocumentImpl newdoc, boolean deep)
internal method to share code with subclass


        // clone the children by importing them
        if (needsSyncChildren()) {
            synchronizeChildren();
        }

        if (deep) {
            Hashtable reversedIdentifiers = null;

            if (identifiers != null) {
                // Build a reverse mapping from element to identifier.
                reversedIdentifiers = new Hashtable();
                Enumeration elementIds = identifiers.keys();
                while (elementIds.hasMoreElements()) {
                    Object elementId = elementIds.nextElement();
                    reversedIdentifiers.put(identifiers.get(elementId),
                    elementId);
                }
            }

            // Copy children into new document.
            for (ChildNode kid = firstChild; kid != null;
            kid = kid.nextSibling) {
                newdoc.appendChild(newdoc.importNode(kid, true, true,
                reversedIdentifiers));
            }
        }

        // experimental
        newdoc.allowGrammarAccess = allowGrammarAccess;
        newdoc.errorChecking = errorChecking;

    
protected voidcopyEventListeners(NodeImpl src, NodeImpl tgt)

        // does nothing by default - overidden in subclass
    
public org.w3c.dom.AttrcreateAttribute(java.lang.String name)
Factory method; creates an Attribute having this Document as its OwnerDoc.

param
name The name of the attribute. Note that the attribute's value is _not_ established at the factory; remember to set it!
throws
DOMException(INVALID_NAME_ERR) if the attribute name is not acceptable.

        
        if (errorChecking && !isXMLName(name,xml11Version)) {
            String msg =
                DOMMessageFormatter.formatMessage(
                    DOMMessageFormatter.DOM_DOMAIN,
                    "INVALID_CHARACTER_ERR",
                    null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
        return new AttrImpl(this, name);
        
    
public org.w3c.dom.AttrcreateAttributeNS(java.lang.String namespaceURI, java.lang.String qualifiedName)
Introduced in DOM Level 2.

Creates an attribute of the given qualified name and namespace URI. If the given namespaceURI is null or an empty string and the qualifiedName has a prefix that is "xml", the created element is bound to the predefined namespace "http://www.w3.org/XML/1998/namespace" [Namespaces].

param
namespaceURI The namespace URI of the attribute to create. When it is null or an empty string, this method behaves like createAttribute.
param
qualifiedName The qualified name of the attribute to instantiate.
return
Attr A new Attr object.
throws
DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an invalid character.
since
WD-DOM-Level-2-19990923

        return new AttrNSImpl(this, namespaceURI, qualifiedName);
    
public org.w3c.dom.AttrcreateAttributeNS(java.lang.String namespaceURI, java.lang.String qualifiedName, java.lang.String localpart)
NON-DOM: a factory method used by the Xerces DOM parser to create an element.

param
namespaceURI The namespace URI of the attribute to create. When it is null or an empty string, this method behaves like createAttribute.
param
qualifiedName The qualified name of the attribute to instantiate.
param
localpart The local name of the attribute to instantiate.
return
Attr A new Attr object.
throws
DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an invalid character.

        return new AttrNSImpl(this, namespaceURI, qualifiedName, localpart);
    
public org.w3c.dom.CDATASectioncreateCDATASection(java.lang.String data)
Factory method; creates a CDATASection having this Document as its OwnerDoc.

param
data The initial contents of the CDATA
throws
DOMException(NOT_SUPPORTED_ERR) for HTML documents. (HTML not yet implemented.)

        return new CDATASectionImpl(this, data);
    
public org.w3c.dom.CommentcreateComment(java.lang.String data)
Factory method; creates a Comment having this Document as its OwnerDoc.

param
data The initial contents of the Comment.

        return new CommentImpl(this, data);
    
public org.w3c.dom.DocumentFragmentcreateDocumentFragment()
Factory method; creates a DocumentFragment having this Document as its OwnerDoc.

        return new DocumentFragmentImpl(this);
    
public org.w3c.dom.DocumentTypecreateDocumentType(java.lang.String qualifiedName, java.lang.String publicID, java.lang.String systemID)
NON-DOM Factory method; creates a DocumentType having this Document as its OwnerDoc. (REC-DOM-Level-1-19981001 left the process of building DTD information unspecified.)

param
qualifiedName
param
publicID
param
systemID
throws
DOMException(NOT_SUPPORTED_ERR) for HTML documents, where DTDs are not permitted. (HTML not yet implemented.)


        return new DocumentTypeImpl(this, qualifiedName, publicID, systemID);

    
public org.w3c.dom.ElementcreateElement(java.lang.String tagName)
Factory method; creates an Element having this Document as its OwnerDoc.

param
tagName The name of the element type to instantiate. For XML, this is case-sensitive. For HTML, the tagName parameter may be provided in any case, but it must be mapped to the canonical uppercase form by the DOM implementation.
throws
DOMException(INVALID_NAME_ERR) if the tag name is not acceptable.


        if (errorChecking && !isXMLName(tagName,xml11Version)) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
        return new ElementImpl(this, tagName);

    
public ElementDefinitionImplcreateElementDefinition(java.lang.String name)
NON-DOM Factory method: creates an element definition. Element definitions hold default attribute values.


        if (errorChecking && !isXMLName(name,xml11Version)) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
        return new ElementDefinitionImpl(this, name);

    
public org.w3c.dom.ElementcreateElementNS(java.lang.String namespaceURI, java.lang.String qualifiedName)
Introduced in DOM Level 2.

Creates an element of the given qualified name and namespace URI. If the given namespaceURI is null or an empty string and the qualifiedName has a prefix that is "xml", the created element is bound to the predefined namespace "http://www.w3.org/XML/1998/namespace" [Namespaces].

param
namespaceURI The namespace URI of the element to create.
param
qualifiedName The qualified name of the element type to instantiate.
return
Element A new Element object with the following attributes:
throws
DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an invalid character.
throws
DOMException NAMESPACE_ERR: Raised if the qualifiedName has a prefix that is "xml" and the namespaceURI is neither null nor an empty string nor "http://www.w3.org/XML/1998/namespace", or if the qualifiedName has a prefix different from "xml" and the namespaceURI is null or an empty string.
since
WD-DOM-Level-2-19990923

        return new ElementNSImpl(this, namespaceURI, qualifiedName);
    
public org.w3c.dom.ElementcreateElementNS(java.lang.String namespaceURI, java.lang.String qualifiedName, java.lang.String localpart)
NON-DOM: a factory method used by the Xerces DOM parser to create an element.

param
namespaceURI The namespace URI of the element to create.
param
qualifiedName The qualified name of the element type to instantiate.
param
localpart The local name of the attribute to instantiate.
return
Element A new Element object with the following attributes:
exception
DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an invalid character.

        return new ElementNSImpl(this, namespaceURI, qualifiedName, localpart);
    
public org.w3c.dom.EntitycreateEntity(java.lang.String name)
NON-DOM Factory method; creates an Entity having this Document as its OwnerDoc. (REC-DOM-Level-1-19981001 left the process of building DTD information unspecified.)

param
name The name of the Entity we wish to provide a value for.
throws
DOMException(NOT_SUPPORTED_ERR) for HTML documents, where nonstandard entities are not permitted. (HTML not yet implemented.)



        if (errorChecking && !isXMLName(name,xml11Version)) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
        return new EntityImpl(this, name);

    
public org.w3c.dom.EntityReferencecreateEntityReference(java.lang.String name)
Factory method; creates an EntityReference having this Document as its OwnerDoc.

param
name The name of the Entity we wish to refer to
throws
DOMException(NOT_SUPPORTED_ERR) for HTML documents, where nonstandard entities are not permitted. (HTML not yet implemented.)


        if (errorChecking && !isXMLName(name,xml11Version)) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
        return new EntityReferenceImpl(this, name);

    
public org.w3c.dom.NotationcreateNotation(java.lang.String name)
NON-DOM Factory method; creates a Notation having this Document as its OwnerDoc. (REC-DOM-Level-1-19981001 left the process of building DTD information unspecified.)

param
name The name of the Notation we wish to describe
throws
DOMException(NOT_SUPPORTED_ERR) for HTML documents, where notations are not permitted. (HTML not yet implemented.)


        if (errorChecking && !isXMLName(name,xml11Version)) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
        return new NotationImpl(this, name);

    
public org.w3c.dom.ProcessingInstructioncreateProcessingInstruction(java.lang.String target, java.lang.String data)
Factory method; creates a ProcessingInstruction having this Document as its OwnerDoc.

param
target The target "processor channel"
param
data Parameter string to be passed to the target.
throws
DOMException(INVALID_NAME_ERR) if the target name is not acceptable.
throws
DOMException(NOT_SUPPORTED_ERR) for HTML documents. (HTML not yet implemented.)


        if (errorChecking && !isXMLName(target,xml11Version)) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
        }
        return new ProcessingInstructionImpl(this, target, data);

    
public org.w3c.dom.TextcreateTextNode(java.lang.String data)
Factory method; creates a Text node having this Document as its OwnerDoc.

param
data The initial contents of the Text.

        return new TextImpl(this, data);
    
voiddeletedText(CharacterDataImpl node, int offset, int count)
A method to be called when some text was deleted from a text node, so that live objects can be notified.

    
protected booleandispatchEvent(NodeImpl node, org.w3c.dom.events.Event event)

        // does nothing by default - overidden in subclass
        return false;
    
voidfreeNodeListCache(NodeListCache c)
Puts the given NodeListCache in the free list. Note: The owner node can keep using it until we reuse it

        c.next = fFreeNLCache;
        fFreeNLCache = c;
    
public booleangetAsync()
DOM Level 3 WD - Experimental. Indicates whether the method load should be synchronous or asynchronous. When the async attribute is set to true the load method returns control to the caller before the document has completed loading. The default value of this property is false.
Setting the value of this attribute might throw NOT_SUPPORTED_ERR if the implementation doesn't support the mode the attribute is being set to. Should the DOM spec define the default value of this property? What if implementing both async and sync IO is impractical in some systems? 2001-09-14. default is false but we need to check with Mozilla and IE.

        return false;
    
public java.lang.StringgetBaseURI()
Returns the absolute base URI of this node or null if the implementation wasn't able to obtain an absolute URI. Note: If the URI is malformed, a null is returned.

return
The absolute base URI of this node or null.
since
DOM Level 3

        if (fDocumentURI != null && fDocumentURI.length() != 0 ) {// attribute value is always empty string
            try {
                return new URI(fDocumentURI).toString();
            }
            catch (org.apache.xerces.util.URI.MalformedURIException e){
                // REVISIT: what should happen in this case?
                return null;
            }
        }            
        return fDocumentURI;
    
public org.w3c.dom.DocumentTypegetDoctype()
For XML, this provides access to the Document Type Definition. For HTML documents, and XML documents which don't specify a DTD, it will be null.

        if (needsSyncChildren()) {
            synchronizeChildren();
        }
        return docType;
    
public org.w3c.dom.ElementgetDocumentElement()
Convenience method, allowing direct access to the child node which is considered the root of the actual document content. For HTML, where it is legal to have more than one Element at the top level of the document, we pick the one with the tagName "HTML". For XML there should be only one top-level (HTML not yet supported.)

        if (needsSyncChildren()) {
            synchronizeChildren();
        }
        return docElement;
    
public java.lang.StringgetDocumentURI()
DOM Level 3 WD - Experimental. The location of the document or null if undefined.
Beware that when the Document supports the feature "HTML" , the href attribute of the HTML BASE element takes precedence over this attribute.

since
DOM Level 3

        return fDocumentURI;
    
public org.w3c.dom.DOMConfigurationgetDomConfig()
DOM Level 3 CR - Experimental The configuration used when Document.normalizeDocument is invoked.

since
DOM Level 3

        if (fConfiguration == null) {
            fConfiguration = new DOMConfigurationImpl();
        }
        return fConfiguration;
    
public org.w3c.dom.ElementgetElementById(java.lang.String elementId)
Introduced in DOM Level 2 Returns the Element whose ID is given by elementId. If no such element exists, returns null. Behavior is not defined if more than one element has this ID.

Note: The DOM implementation must have information that says which attributes are of type ID. Attributes with the name "ID" are not of type ID unless so defined. Implementations that do not know whether attributes are of type ID or not are expected to return null.

see
#getIdentifier

        return getIdentifier(elementId);
    
public org.w3c.dom.NodeListgetElementsByTagName(java.lang.String tagname)
Return a live collection of all descendent Elements (not just immediate children) having the specified tag name.

param
tagname The type of Element we want to gather. "*" will be taken as a wildcard, meaning "all elements in the document."
see
DeepNodeListImpl

        return new DeepNodeListImpl(this,tagname);
    
public org.w3c.dom.NodeListgetElementsByTagNameNS(java.lang.String namespaceURI, java.lang.String localName)
Introduced in DOM Level 2.

Returns a NodeList of all the Elements with a given local name and namespace URI in the order in which they would be encountered in a preorder traversal of the Document tree.

param
namespaceURI The namespace URI of the elements to match on. The special value "*" matches all namespaces. When it is null or an empty string, this method behaves like getElementsByTagName.
param
localName The local name of the elements to match on. The special value "*" matches all local names.
return
NodeList A new NodeList object containing all the matched Elements.
since
WD-DOM-Level-2-19990923

        return new DeepNodeListImpl(this, namespaceURI, localName);
    
public java.lang.StringgetEncoding()

deprecated
This method is internal and only exists for compatibility with older applications. New applications should never call this method.

        return getXmlEncoding();
    
public booleangetErrorChecking()
Returns true if the DOM implementation performs error checking.

        return errorChecking;
    
public java.lang.ObjectgetFeature(java.lang.String feature, java.lang.String version)

since
DOM Level 3

        
        boolean anyVersion = version == null || version.length() == 0;
        
        // if a plus sign "+" is prepended to any feature name, implementations
        // are considered in which the specified feature may not be directly
        // castable DOMImplementation.getFeature(feature, version). Without a
        // plus, only features whose interfaces are directly castable are
        // considered.
        if ((feature.equalsIgnoreCase("+XPath"))
            && (anyVersion || version.equals("3.0"))) {
            
            // If an XPathEvaluator was created previously 
            // return it otherwise create a new one.
            if (fXPathEvaluator != null) {
                return fXPathEvaluator;
            }
            
            try {
                Class xpathClass = ObjectFactory.findProviderClass(
                    "org.apache.xpath.domapi.XPathEvaluatorImpl",
                    ObjectFactory.findClassLoader(), true);
                Constructor xpathClassConstr = 
                    xpathClass.getConstructor(new Class[] { Document.class });
                
                // Check if the DOM XPath implementation implements
                // the interface org.w3c.dom.XPathEvaluator
                Class interfaces[] = xpathClass.getInterfaces();
                for (int i = 0; i < interfaces.length; i++) {
                    if (interfaces[i].getName().equals(
                    "org.w3c.dom.xpath.XPathEvaluator")) {
                        fXPathEvaluator = xpathClassConstr.newInstance(new Object[] { this });
                        return fXPathEvaluator;
                    }
                }
                return null;
            } catch (Exception e) {
                return null;
            }
        }
        return super.getFeature(feature, version);
    
public org.w3c.dom.ElementgetIdentifier(java.lang.String idName)
Returns a previously registered element with the specified identifier name, or null if no element is registered.

see
#putIdentifier
see
#removeIdentifier


        if (needsSyncData()) {
            synchronizeData();
        }

        if (identifiers == null) {
            return null;
        }
        Element elem = (Element) identifiers.get(idName);
        if (elem != null) {
            // check that the element is in the tree
            Node parent = elem.getParentNode();
            while (parent != null) {
                if (parent == this) {
                    return elem;
                }
                parent = parent.getParentNode();
            }
        }
        return null;
    
public java.util.EnumerationgetIdentifiers()
Returns an enumeration registered of identifier names.


        if (needsSyncData()) {
            synchronizeData();
        }

        if (identifiers == null) {
            identifiers = new Hashtable();
        }

        return identifiers.keys();

    
public org.w3c.dom.DOMImplementationgetImplementation()
Retrieve information describing the abilities of this particular DOM implementation. Intended to support applications that may be using DOMs retrieved from several different sources, potentially with different underlying representations.

        // Currently implemented as a singleton, since it's hardcoded
        // information anyway.
        return CoreDOMImplementationImpl.getDOMImplementation();
    
public java.lang.StringgetInputEncoding()
DOM Level 3 CR - Experimental. (Was getActualEncoding) An attribute specifying the encoding used for this document at the time of the parsing. This is null when it is not known, such as when the Document was created in memory.

since
DOM Level 3

        return actualEncoding;
    
booleangetMutationEvents()
Returns true if the DOM implementation generates mutation events.

        // does nothing by default - overriden in subclass
        return false;
    
NodeListCachegetNodeListCache(ParentNode owner)
Returns a NodeListCache for the given node.

        if (fFreeNLCache == null) {
            return new NodeListCache(owner);
        }
        NodeListCache c = fFreeNLCache;
        fFreeNLCache = fFreeNLCache.next;
        c.fChild = null;
        c.fChildIndex = -1;
        c.fLength = -1;
        // revoke previous ownership
        if (c.fOwner != null) {
            c.fOwner.fNodeListCache = null;
        }
        c.fOwner = owner;
        // c.next = null; not necessary, except for confused people...
        return c;
    
public java.lang.StringgetNodeName()
Returns the node name.

        return "#document";
    
protected intgetNodeNumber()
NON-DOM: Get the number associated with this document. Used to order documents in the implementation.

        if (documentNumber==0) {

            CoreDOMImplementationImpl cd = (CoreDOMImplementationImpl)CoreDOMImplementationImpl.getDOMImplementation();
            documentNumber = cd.assignDocumentNumber();
        }
        return documentNumber;
    
protected intgetNodeNumber(org.w3c.dom.Node node)
NON-DOM: Get a number associated with a node created with respect to this document. Needed for compareDocumentPosition when nodes are disconnected. This is only used on demand.


        // Check if the node is already in the hash
        // If so, retrieve the node number
        // If not, assign a number to the node
        // Node numbers are negative, from -1 to -n
        int num;
        if (nodeTable == null) {
            nodeTable = new Hashtable();
            num = --nodeCounter;
            nodeTable.put(node, new Integer(num));
        }
        else {
            Integer n = (Integer)nodeTable.get(node);
            if (n== null) {
                num = --nodeCounter;
                nodeTable.put(node, new Integer(num));
            }
            else
                num = n.intValue();
        }
        return num;
    
public shortgetNodeType()
Returns the node type.

        return Node.DOCUMENT_NODE;
    
public final org.w3c.dom.DocumentgetOwnerDocument()

        return null;
    
public booleangetStandalone()

deprecated
This method is internal and only exists for compatibility with older applications. New applications should never call this method.

        return getXmlStandalone();
    
public booleangetStrictErrorChecking()

        return errorChecking;
    
public java.lang.StringgetTextContent()

        return null;
    
protected java.lang.ObjectgetUserData(NodeImpl n)
NON-DOM: kept for backward compatibility Retreive user data related to a given node

        return getUserData(n, "XERCES1DOMUSERDATA");
    
public java.lang.ObjectgetUserData(org.w3c.dom.Node n, java.lang.String key)
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
n The node the object is associated to.
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

        if (userData == null) {
            return null;
        }
        Hashtable t = (Hashtable) userData.get(n);
        if (t == null) {
            return null;
        }
        Object o = t.get(key);
        if (o != null) {
            UserDataRecord r = (UserDataRecord) o;
            return r.fData;
        }
        return null;
    
protected java.util.HashtablegetUserDataRecord(org.w3c.dom.Node n)

        if (userData == null) {
            return null;
        }
        Hashtable t = (Hashtable) userData.get(n);
        if (t == null) {
            return null;
        }
		return t;
	
public java.lang.StringgetVersion()

deprecated
This method is internal and only exists for compatibility with older applications. New applications should never call this method.

        return getXmlVersion();
    
public java.lang.StringgetXmlEncoding()
DOM Level 3 WD - Experimental. The encoding of this document (part of XML Declaration)

        return encoding;
    
public booleangetXmlStandalone()
DOM Level 3 WD - Experimental. standalone that specifies whether this document is standalone (part of XML Declaration)

        return standalone;
    
public java.lang.StringgetXmlVersion()
DOM Level 3 WD - Experimental. The version of this document (part of XML Declaration)

        return (version == null)?"1.0":version;
    
public org.w3c.dom.NodeimportNode(org.w3c.dom.Node source, boolean deep)
Copies a node from another document to this document. The new nodes are created using this document's factory methods and are populated with the data from the source's accessor methods defined by the DOM interfaces. Its behavior is otherwise similar to that of cloneNode.

According to the DOM specifications, document nodes cannot be imported and a NOT_SUPPORTED_ERR exception is thrown if attempted.

        return importNode(source, deep, false, null);
    
private org.w3c.dom.NodeimportNode(org.w3c.dom.Node source, boolean deep, boolean cloningDoc, java.util.Hashtable reversedIdentifiers)
Overloaded implementation of DOM's importNode method. This method provides the core functionality for the public importNode and cloneNode methods. The reversedIdentifiers parameter is provided for cloneNode to preserve the document's identifiers. The Hashtable has Elements as the keys and their identifiers as the values. When an element is being imported, a check is done for an associated identifier. If one exists, the identifier is registered with the new, imported element. If reversedIdentifiers is null, the parameter is not applied.

        Node newnode=null;
		Hashtable userData = null;

        // Sigh. This doesn't work; too many nodes have private data that
        // would have to be manually tweaked. May be able to add local
        // shortcuts to each nodetype. Consider ?????
        // if(source instanceof NodeImpl &&
        //  !(source instanceof DocumentImpl))
        // {
        //  // Can't clone DocumentImpl since it invokes us...
        //  newnode=(NodeImpl)source.cloneNode(false);
        //  newnode.ownerDocument=this;
        // }
        // else
		if(source instanceof NodeImpl)
			userData = ((NodeImpl)source).getUserDataRecord();
        int type = source.getNodeType();
        switch (type) {
            case ELEMENT_NODE: {
                Element newElement;
                boolean domLevel20 = source.getOwnerDocument().getImplementation().hasFeature("XML", "2.0");
                // Create element according to namespace support/qualification.
                if(domLevel20 == false || source.getLocalName() == null)
                    newElement = createElement(source.getNodeName());
                else
                    newElement = createElementNS(source.getNamespaceURI(),
                    source.getNodeName());

                // Copy element's attributes, if any.
                NamedNodeMap sourceAttrs = source.getAttributes();
                if (sourceAttrs != null) {
                    int length = sourceAttrs.getLength();
                    for (int index = 0; index < length; index++) {
                        Attr attr = (Attr)sourceAttrs.item(index);

                        // NOTE: this methods is used for both importingNode
                        // and cloning the document node. In case of the
                        // clonning default attributes should be copied.
                        // But for importNode defaults should be ignored.
                        if (attr.getSpecified() || cloningDoc) {
                            Attr newAttr = (Attr)importNode(attr, true, cloningDoc,
                            reversedIdentifiers);

                            // Attach attribute according to namespace
                            // support/qualification.
                            if (domLevel20 == false ||
                            attr.getLocalName() == null)
                                newElement.setAttributeNode(newAttr);
                            else
                                newElement.setAttributeNodeNS(newAttr);
                        }
                    }
                }

                // Register element identifier.
                if (reversedIdentifiers != null) {
                    // Does element have an associated identifier?
                    Object elementId = reversedIdentifiers.get(source);
                    if (elementId != null) {
                        if (identifiers == null)
                            identifiers = new Hashtable();

                        identifiers.put(elementId, newElement);
                    }
                }

                newnode = newElement;
                break;
            }

            case ATTRIBUTE_NODE: {

                if( source.getOwnerDocument().getImplementation().hasFeature("XML", "2.0") ){
                    if (source.getLocalName() == null) {
                        newnode = createAttribute(source.getNodeName());
                    } else {
                        newnode = createAttributeNS(source.getNamespaceURI(),
                        source.getNodeName());
                    }
                }
                else {
                    newnode = createAttribute(source.getNodeName());
                }
                // if source is an AttrImpl from this very same implementation
                // avoid creating the child nodes if possible
                if (source instanceof AttrImpl) {
                    AttrImpl attr = (AttrImpl) source;
                    if (attr.hasStringValue()) {
                        AttrImpl newattr = (AttrImpl) newnode;
                        newattr.setValue(attr.getValue());
                        deep = false;
                    }
                    else {
                        deep = true;
                    }
                }
                else {
                    // According to the DOM spec the kids carry the value.
                    // However, there are non compliant implementations out
                    // there that fail to do so. To avoid ending up with no
                    // value at all, in this case we simply copy the text value
                    // directly.
                    if (source.getFirstChild() == null) {
                        newnode.setNodeValue(source.getNodeValue());
                        deep = false;
                    } else {
                        deep = true;
                    }
                }
                break;
            }

            case TEXT_NODE: {
                newnode = createTextNode(source.getNodeValue());
                break;
            }

            case CDATA_SECTION_NODE: {
                newnode = createCDATASection(source.getNodeValue());
                break;
            }

            case ENTITY_REFERENCE_NODE: {
                newnode = createEntityReference(source.getNodeName());
                // the subtree is created according to this doc by the method
                // above, so avoid carrying over original subtree
                deep = false;
                break;
            }

            case ENTITY_NODE: {
                Entity srcentity = (Entity)source;
                EntityImpl newentity =
                (EntityImpl)createEntity(source.getNodeName());
                newentity.setPublicId(srcentity.getPublicId());
                newentity.setSystemId(srcentity.getSystemId());
                newentity.setNotationName(srcentity.getNotationName());
                // Kids carry additional value,
                // allow deep import temporarily
                newentity.isReadOnly(false);
                newnode = newentity;
                break;
            }

            case PROCESSING_INSTRUCTION_NODE: {
                newnode = createProcessingInstruction(source.getNodeName(),
                source.getNodeValue());
                break;
            }

            case COMMENT_NODE: {
                newnode = createComment(source.getNodeValue());
                break;
            }

            case DOCUMENT_TYPE_NODE: {
                // unless this is used as part of cloning a Document
                // forbid it for the sake of being compliant to the DOM spec
                if (!cloningDoc) {
                    String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
                    throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
                }
                DocumentType srcdoctype = (DocumentType)source;
                DocumentTypeImpl newdoctype = (DocumentTypeImpl)
                createDocumentType(srcdoctype.getNodeName(),
                srcdoctype.getPublicId(),
                srcdoctype.getSystemId());
                newdoctype.setInternalSubset(srcdoctype.getInternalSubset());
                // Values are on NamedNodeMaps
                NamedNodeMap smap = srcdoctype.getEntities();
                NamedNodeMap tmap = newdoctype.getEntities();
                if(smap != null) {
                    for(int i = 0; i < smap.getLength(); i++) {
                        tmap.setNamedItem(importNode(smap.item(i), true, true,
                        reversedIdentifiers));
                    }
                }
                smap = srcdoctype.getNotations();
                tmap = newdoctype.getNotations();
                if (smap != null) {
                    for(int i = 0; i < smap.getLength(); i++) {
                        tmap.setNamedItem(importNode(smap.item(i), true, true,
                        reversedIdentifiers));
                    }
                }

                // NOTE: At this time, the DOM definition of DocumentType
                // doesn't cover Elements and their Attributes. domimpl's
                // extentions in that area will not be preserved, even if
                // copying from domimpl to domimpl. We could special-case
                // that here. Arguably we should. Consider. ?????
                newnode = newdoctype;
                break;
            }

            case DOCUMENT_FRAGMENT_NODE: {
                newnode = createDocumentFragment();
                // No name, kids carry value
                break;
            }

            case NOTATION_NODE: {
                Notation srcnotation = (Notation)source;
                NotationImpl newnotation =
                (NotationImpl)createNotation(source.getNodeName());
                newnotation.setPublicId(srcnotation.getPublicId());
                newnotation.setSystemId(srcnotation.getSystemId());
                // Kids carry additional value
                newnode = newnotation;
                // No name, no value
                break;
            }
            case DOCUMENT_NODE : // Can't import document nodes
            default: {           // Unknown node type
                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
            }
        }

		if(userData != null)
			callUserDataHandlers(source, newnode, UserDataHandler.NODE_IMPORTED,userData);

        // If deep, replicate and attach the kids.
        if (deep) {
            for (Node srckid = source.getFirstChild();
            srckid != null;
            srckid = srckid.getNextSibling()) {
                newnode.appendChild(importNode(srckid, true, cloningDoc,
                reversedIdentifiers));
            }
        }
        if (newnode.getNodeType() == Node.ENTITY_NODE) {
            ((NodeImpl)newnode).setReadOnly(true, true);
        }
        return newnode;

    
public org.w3c.dom.NodeinsertBefore(org.w3c.dom.Node newChild, org.w3c.dom.Node refChild)
Since a Document may contain at most one top-level Element child, and at most one DocumentType declaraction, we need to subclass our add-children methods to implement this constraint. Since appendChild() is implemented as insertBefore(,null), altering the latter fixes both.

While I'm doing so, I've taken advantage of the opportunity to cache documentElement and docType so we don't have to search for them. REVISIT: According to the spec it is not allowed to alter neither the document element nor the document type in any way


        // Only one such child permitted
        int type = newChild.getNodeType();
        if (errorChecking) {
            if (needsSyncChildren()) {
                synchronizeChildren();
            }
            if((type == Node.ELEMENT_NODE && docElement != null) ||
            (type == Node.DOCUMENT_TYPE_NODE && docType != null)) {
                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null);
                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, msg);
            }
        }
        // Adopt orphan doctypes
        if (newChild.getOwnerDocument() == null &&
        newChild instanceof DocumentTypeImpl) {
            ((DocumentTypeImpl) newChild).ownerDocument = this;
        }
        super.insertBefore(newChild,refChild);

        // If insert succeeded, cache the kid appropriately
        if (type == Node.ELEMENT_NODE) {
            docElement = (ElementImpl)newChild;
        }
        else if (type == Node.DOCUMENT_TYPE_NODE) {
            docType = (DocumentTypeImpl)newChild;
        }

        return newChild;

    
voidinsertedNode(NodeImpl node, NodeImpl newInternal, boolean replace)
A method to be called when a node has been inserted in the tree.

    
voidinsertedText(CharacterDataImpl node, int offset, int count)
A method to be called when some text was inserted into a text node, so that live objects can be notified.

    
voidinsertingNode(NodeImpl node, boolean replace)
A method to be called when a node is about to be inserted in the tree.

    
protected booleanisKidOK(org.w3c.dom.Node parent, org.w3c.dom.Node child)
Uses the kidOK lookup table to check whether the proposed tree structure is legal.

        if (allowGrammarAccess &&
        parent.getNodeType() == Node.DOCUMENT_TYPE_NODE) {
            return child.getNodeType() == Node.ELEMENT_NODE;
        }
        return 0 != (kidOK[parent.getNodeType()] & 1 << child.getNodeType());
    
booleanisNormalizeDocRequired()

        // REVISIT: Implement to optimize when normalization
        // is required
        return true;
    
public static final booleanisValidQName(java.lang.String prefix, java.lang.String local, boolean xml11Version)
Checks if the given qualified name is legal with respect to the version of XML to which this document must conform.

param
prefix prefix of qualified name
param
local local part of qualified name


        // check that both prefix and local part match NCName
        if (local == null) return false;
        boolean validNCName = false;

        if (!xml11Version) {
            validNCName = (prefix == null || XMLChar.isValidNCName(prefix))
                && XMLChar.isValidNCName(local);
        }
        else {
            validNCName = (prefix == null || XML11Char.isXML11ValidNCName(prefix))
                && XML11Char.isXML11ValidNCName(local);
        }

        return validNCName;
    
booleanisXML11Version()
We could have more xml versions in future , but for now we could do with this to handle XML 1.0 and 1.1

        return xml11Version;
    
public static final booleanisXMLName(java.lang.String s, boolean xml11Version)
Check the string against XML's definition of acceptable names for elements and attributes and so on using the XMLCharacterProperties utility class


        if (s == null) {
            return false;
        }
        if(!xml11Version)
            return XMLChar.isValidName(s);
        else
            return XML11Char.isXML11ValidName(s);

    
booleanisXMLVersionChanged()

        return xmlVersionChanged ;
    
public booleanload(java.lang.String uri)
DOM Level 3 WD - Experimental. Replaces the content of the document with the result of parsing the given URI. Invoking this method will either block the caller or return to the caller immediately depending on the value of the async attribute. Once the document is fully loaded a "load" event (as defined in [DOM Level 3 Events] , except that the Event.targetNode will be the document, not an element) will be dispatched on the document. If an error occurs, an implementation dependent "error" event will be dispatched on the document. If this method is called on a document that is currently loading, the current load is interrupted and the new URI load is initiated.
When invoking this method the parameters used in the DOMParser interface are assumed to have their default values with the exception that the parameters "entities" , "normalize-characters", "check-character-normalization" are set to "false".
The result of a call to this method is the same the result of a call to DOMParser.parseWithContext with an input stream referencing the URI that was passed to this call, the document as the context node, and the action ACTION_REPLACE_CHILDREN.

param
uri The URI reference for the XML file to be loaded. If this is a relative URI, the base URI used by the implementation is implementation dependent.
return
If async is set to true load returns true if the document load was successfully initiated. If an error occurred when initiating the document load, load returns false.If async is set to false load returns true if the document was successfully loaded and parsed. If an error occurred when either loading or parsing the URI, load returns false.

        return false;
    
public booleanloadXML(java.lang.String source)
DOM Level 3 WD - Experimental. Replace the content of the document with the result of parsing the input string, this method is always synchronous.

param
source A string containing an XML document.
return
true if parsing the input string succeeded without errors, otherwise false.

        return false;
    
voidmodifiedAttrValue(AttrImpl attr, java.lang.String oldvalue)
A method to be called when an attribute value has been modified

    
voidmodifiedCharacterData(NodeImpl node, java.lang.String oldvalue, java.lang.String value, boolean replace)
A method to be called when a character data node has been modified

    
voidmodifyingCharacterData(NodeImpl node, boolean replace)
A method to be called when a character data node is about to be modified

    
public voidnormalizeDocument()
DOM Level 3 WD - Experimental Normalize document.

        // No need to normalize if already normalized.
        if (isNormalized() && !isNormalizeDocRequired()) {
            return;
        }
        if (needsSyncChildren()) {
            synchronizeChildren();
        }

        if (domNormalizer == null) {
            domNormalizer = new DOMNormalizer();
        }

        if (fConfiguration == null) {
            fConfiguration =  new DOMConfigurationImpl();
        }
        else {
            fConfiguration.reset();
        }

        domNormalizer.normalizeDocument(this, fConfiguration);
        isNormalized(true);
        //set the XMLversion changed value to false -- once we have finished
        //doing normalization
        xmlVersionChanged = false ;
    
public voidputIdentifier(java.lang.String idName, org.w3c.dom.Element element)
Registers an identifier name with a specified element node. If the identifier is already registered, the new element node replaces the previous node. If the specified element node is null, removeIdentifier() is called.

see
#getIdentifier
see
#removeIdentifier


        if (element == null) {
            removeIdentifier(idName);
            return;
        }

        if (needsSyncData()) {
            synchronizeData();
        }

        if (identifiers == null) {
            identifiers = new Hashtable();
        }

        identifiers.put(idName, element);

    
public org.w3c.dom.NoderemoveChild(org.w3c.dom.Node oldChild)
Since insertBefore caches the docElement (and, currently, docType), removeChild has to know how to undo the cache REVISIT: According to the spec it is not allowed to alter neither the document element nor the document type in any way


        super.removeChild(oldChild);

        // If remove succeeded, un-cache the kid appropriately
        int type = oldChild.getNodeType();
        if(type == Node.ELEMENT_NODE) {
            docElement = null;
        }
        else if (type == Node.DOCUMENT_TYPE_NODE) {
            docType = null;
        }

        return oldChild;

    
protected voidremoveEventListener(NodeImpl node, java.lang.String type, org.w3c.dom.events.EventListener listener, boolean useCapture)

        // does nothing by default - overidden in subclass
    
public voidremoveIdentifier(java.lang.String idName)
Removes a previously registered element with the specified identifier name.

see
#putIdentifier
see
#getIdentifier


        if (needsSyncData()) {
            synchronizeData();
        }

        if (identifiers == null) {
            return;
        }

        identifiers.remove(idName);

    
java.util.HashtableremoveUserDataTable(org.w3c.dom.Node n)
Remove user data table for the given node.

param
n The node this operation applies to.
return
The removed table.

        if (userData == null) {
            return null;
        }
        return (Hashtable) userData.get(n);
    
voidremovedAttrNode(AttrImpl attr, NodeImpl oldOwner, java.lang.String name)
A method to be called when an attribute node has been removed

    
voidremovedNode(NodeImpl node, boolean replace)
A method to be called when a node has been removed from the tree.

    
voidremovingNode(NodeImpl node, NodeImpl oldChild, boolean replace)
A method to be called when a node is about to be removed from the tree.

    
public org.w3c.dom.NoderenameNode(org.w3c.dom.Node n, java.lang.String namespaceURI, java.lang.String name)
DOM Level 3 WD - Experimental. Renaming node

        
        if (errorChecking && n.getOwnerDocument() != this && n != this) {
            String msg = DOMMessageFormatter.formatMessage(
                    DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
        }
        switch (n.getNodeType()) {
            case ELEMENT_NODE: {
                ElementImpl el = (ElementImpl) n;
                if (el instanceof ElementNSImpl) {
                    ((ElementNSImpl) el).rename(namespaceURI, name);
                    
                    // fire user data NODE_RENAMED event
                    callUserDataHandlers(el, null, UserDataHandler.NODE_RENAMED);
                }
                else {
                    if (namespaceURI == null) {
                        if (errorChecking) {
                            int colon1 = name.indexOf(':");
                            if(colon1 != -1){
                                String msg =
                                    DOMMessageFormatter.formatMessage(
                                            DOMMessageFormatter.DOM_DOMAIN,
                                            "NAMESPACE_ERR",
                                            null);
                                throw new DOMException(DOMException.NAMESPACE_ERR, msg);
                            }
                            if (!isXMLName(name,xml11Version)) {
                                String msg = DOMMessageFormatter.formatMessage(
                                        DOMMessageFormatter.DOM_DOMAIN,
                                        "INVALID_CHARACTER_ERR", null);
                                throw new DOMException(DOMException.INVALID_CHARACTER_ERR,
                                        msg);
                            }
                        }
                        el.rename(name);
                        
                        // fire user data NODE_RENAMED event
                        callUserDataHandlers(el, null,
                                UserDataHandler.NODE_RENAMED);
                    }
                    else {
                        // we need to create a new object
                        ElementNSImpl nel =
                            new ElementNSImpl(this, namespaceURI, name);
                        
                        // register event listeners on new node
                        copyEventListeners(el, nel);
                        
                        // remove user data from old node
                        Hashtable data = removeUserDataTable(el);
                        
                        // remove old node from parent if any
                        Node parent = el.getParentNode();
                        Node nextSib = el.getNextSibling();
                        if (parent != null) {
                            parent.removeChild(el);
                        }
                        // move children to new node
                        Node child = el.getFirstChild();
                        while (child != null) {
                            el.removeChild(child);
                            nel.appendChild(child);
                            child = el.getFirstChild();
                        }
                        // move specified attributes to new node
                        nel.moveSpecifiedAttributes(el);
                        
                        // attach user data to new node
                        setUserDataTable(nel, data);
                        
                        // and fire user data NODE_RENAMED event
                        callUserDataHandlers(el, nel,
                                UserDataHandler.NODE_RENAMED);
                        
                        // insert new node where old one was
                        if (parent != null) {
                            parent.insertBefore(nel, nextSib);
                        }
                        el = nel;
                    }
                }
                // fire ElementNameChanged event
                renamedElement((Element) n, el);
                return el;
            }
            case ATTRIBUTE_NODE: {
                AttrImpl at = (AttrImpl) n;
                
                // dettach attr from element
                Element el = at.getOwnerElement();
                if (el != null) {
                    el.removeAttributeNode(at);
                }
                if (n instanceof AttrNSImpl) {
                    ((AttrNSImpl) at).rename(namespaceURI, name);
                    // reattach attr to element
                    if (el != null) {
                        el.setAttributeNodeNS(at);
                    }
                    
                    // fire user data NODE_RENAMED event
                    callUserDataHandlers(at, null, UserDataHandler.NODE_RENAMED);
                }
                else {
                    if (namespaceURI == null) {
                        at.rename(name);
                        // reattach attr to element
                        if (el != null) {
                            el.setAttributeNode(at);
                        }
                        
                        // fire user data NODE_RENAMED event
                        callUserDataHandlers(at, null, UserDataHandler.NODE_RENAMED);
                    }
                    else {
                        // we need to create a new object
                        AttrNSImpl nat = new AttrNSImpl(this, namespaceURI, name);
                        
                        // register event listeners on new node
                        copyEventListeners(at, nat);
                        
                        // remove user data from old node
                        Hashtable data = removeUserDataTable(at);
                        
                        // move children to new node
                        Node child = at.getFirstChild();
                        while (child != null) {
                            at.removeChild(child);
                            nat.appendChild(child);
                            child = at.getFirstChild();
                        }
                        
                        // attach user data to new node
                        setUserDataTable(nat, data);
                        
                        // and fire user data NODE_RENAMED event
                        callUserDataHandlers(at, nat, UserDataHandler.NODE_RENAMED);
                        
                        // reattach attr to element
                        if (el != null) {
                            el.setAttributeNode(nat);
                        }
                        at = nat;
                    }
                }
                // fire AttributeNameChanged event
                renamedAttrNode((Attr) n, at);
                
                return at;
            }
            default: {
                String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
                throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
            }
        }
        
    
voidrenamedAttrNode(org.w3c.dom.Attr oldAt, org.w3c.dom.Attr newAt)
A method to be called when an attribute node has been renamed

    
voidrenamedElement(org.w3c.dom.Element oldEl, org.w3c.dom.Element newEl)
A method to be called when an element has been renamed

    
public org.w3c.dom.NodereplaceChild(org.w3c.dom.Node newChild, org.w3c.dom.Node oldChild)
Since we cache the docElement (and, currently, docType), replaceChild has to update the cache REVISIT: According to the spec it is not allowed to alter neither the document element nor the document type in any way


        // Adopt orphan doctypes
        if (newChild.getOwnerDocument() == null &&
        newChild instanceof DocumentTypeImpl) {
            ((DocumentTypeImpl) newChild).ownerDocument = this;
        }

        if (errorChecking &&((docType != null &&
            oldChild.getNodeType() != Node.DOCUMENT_TYPE_NODE && 
            newChild.getNodeType() == Node.DOCUMENT_TYPE_NODE) 
            || (docElement != null && 
            oldChild.getNodeType() != Node.ELEMENT_NODE && 
            newChild.getNodeType() == Node.ELEMENT_NODE))) {
            	
            throw new DOMException(
                DOMException.HIERARCHY_REQUEST_ERR,
                DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null));
        }
        super.replaceChild(newChild, oldChild);

        int type = oldChild.getNodeType();
        if(type == Node.ELEMENT_NODE) {
            docElement = (ElementImpl)newChild;
        }
        else if (type == Node.DOCUMENT_TYPE_NODE) {
            docType = (DocumentTypeImpl)newChild;
        }
        return oldChild;
    
voidreplacedCharacterData(NodeImpl node, java.lang.String oldvalue, java.lang.String value)
method to be called when a character data node has been replaced.

    
voidreplacedNode(NodeImpl node)
A method to be called when a node has been replaced in the tree.

    
voidreplacedText(CharacterDataImpl node)
A method to be called when some text was changed in a text node, so that live objects can be notified.

    
voidreplacingData(NodeImpl node)
A method to be called when a character data node is about to be replaced

    
voidreplacingNode(NodeImpl node)
A method to be called when a node is about to be replaced in the tree.

    
public java.lang.StringsaveXML(org.w3c.dom.Node node)
DOM Level 3 WD - Experimental. Save the document or the given node and all its descendants to a string (i.e. serialize the document or node).
The parameters used in the LSSerializer interface are assumed to have their default values when invoking this method.
The result of a call to this method is the same the result of a call to LSSerializer.writeToString with the document as the node to write.

param
node Specifies what to serialize, if this parameter is null the whole document is serialized, if it's non-null the given node is serialized.
return
The serialized document or null in case an error occurred.
exception
DOMException WRONG_DOCUMENT_ERR: Raised if the node passed in as the node parameter is from an other document.

        if ( errorChecking && node != null &&
            this != node.getOwnerDocument() ) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
        }
        DOMImplementationLS domImplLS = (DOMImplementationLS)DOMImplementationImpl.getDOMImplementation();
        LSSerializer xmlWriter = domImplLS.createLSSerializer();
        if (node == null) {
            node = this;
        }
        return xmlWriter.writeToString(node);
    
public voidsetAsync(boolean async)
DOM Level 3 WD - Experimental. Indicates whether the method load should be synchronous or asynchronous. When the async attribute is set to true the load method returns control to the caller before the document has completed loading. The default value of this property is false.
Setting the value of this attribute might throw NOT_SUPPORTED_ERR if the implementation doesn't support the mode the attribute is being set to. Should the DOM spec define the default value of this property? What if implementing both async and sync IO is impractical in some systems? 2001-09-14. default is false but we need to check with Mozilla and IE.

        if (async) {
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
            throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
        }
    
voidsetAttrNode(AttrImpl attr, AttrImpl previous)
A method to be called when an attribute node has been set

    
public voidsetDocumentURI(java.lang.String documentURI)
DOM Level 3 WD - Experimental.

        fDocumentURI = documentURI;
    
public voidsetEncoding(java.lang.String value)

deprecated
This method is internal and only exists for compatibility with older applications. New applications should never call this method.

        setXmlEncoding(value);
    
public voidsetErrorChecking(boolean check)
Sets whether the DOM implementation performs error checking upon operations. Turning off error checking only affects the following DOM checks:
  • Checking strings to make sure that all characters are legal XML characters
  • Hierarchy checking such as allowed children, checks for cycles, etc.

Turning off error checking does not turn off the following checks:

  • Read only checks
  • Checks related to DOM events

        errorChecking = check;
    
public voidsetInputEncoding(java.lang.String value)
DOM Internal (Was a DOM L3 Core WD public interface method setActualEncoding ) An attribute specifying the actual encoding of this document. This is null otherwise.
This attribute represents the property [character encoding scheme] defined in .

        actualEncoding = value;
    
voidsetMutationEvents(boolean set)
Sets whether the DOM implementation generates mutation events upon operations.

        // does nothing by default - overidden in subclass
    
public voidsetStandalone(boolean value)

deprecated
This method is internal and only exists for compatibility with older applications. New applications should never call this method.

        setXmlStandalone(value);
    
public voidsetStrictErrorChecking(boolean check)

        errorChecking = check;
    
public voidsetTextContent(java.lang.String textContent)

        // no-op
    
protected voidsetUserData(NodeImpl n, java.lang.Object data)
NON-DOM: kept for backward compatibility Store user data related to a given node This is a place where we could use weak references! Indeed, the node here won't be GC'ed as long as some user data is attached to it, since the userData table will have a reference to the node.

        setUserData(n, "XERCES1DOMUSERDATA", data, null);
    
public java.lang.ObjectsetUserData(org.w3c.dom.Node n, java.lang.String key, java.lang.Object data, org.w3c.dom.UserDataHandler handler)
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
n The node to associate the object to.
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 REVISIT: we could use a free list of UserDataRecord here

        if (data == null) {
            if (userData != null) {
                Hashtable t = (Hashtable) userData.get(n);
                if (t != null) {
                    Object o = t.remove(key);
                    if (o != null) {
                        UserDataRecord r = (UserDataRecord) o;
                        return r.fData;
                    }
                }
            }
            return null;
        }
        else {
            Hashtable t;
            if (userData == null) {
                userData = new Hashtable();
                t = new Hashtable();
                userData.put(n, t);
            }
            else {
                t = (Hashtable) userData.get(n);
                if (t == null) {
                    t = new Hashtable();
                    userData.put(n, t);
                }
            }
            Object o = t.put(key, new UserDataRecord(data, handler));
            if (o != null) {
                UserDataRecord r = (UserDataRecord) o;
                return r.fData;
            }
            return null;
        }
    
voidsetUserDataTable(org.w3c.dom.Node n, java.util.Hashtable data)
Set user data table for the given node.

param
n The node this operation applies to.
param
data The user data table.

		if (userData == null)
			userData = new Hashtable();
        if (data != null) {
            userData.put(n, data);
        }
    
public voidsetVersion(java.lang.String value)

deprecated
This method is internal and only exists for compatibility with older applications. New applications should never call this method.

        setXmlVersion(value);
    
public voidsetXmlEncoding(java.lang.String value)
DOM Internal (Was a DOM L3 Core WD public interface method setXMLEncoding ) An attribute specifying, as part of the XML declaration, the encoding of this document. This is null when unspecified.

        encoding = value;
    
public voidsetXmlStandalone(boolean value)
DOM Level 3 CR - Experimental. Xmlstandalone - An attribute specifying, as part of the XML declaration, whether this document is standalone

exception
DOMException NOT_SUPPORTED_ERR: Raised if this document does not support the "XML" feature.
since
DOM Level 3

            standalone = value;
    
public voidsetXmlVersion(java.lang.String value)
DOM Level 3 CR - Experimental. version - An attribute specifying, as part of the XML declaration, the version number of this document.

        if(value.equals("1.0") || value.equals("1.1")){
            //we need to change the flag value only --
            // when the version set is different than already set.
            if(!getXmlVersion().equals(value)){
                xmlVersionChanged = true ;
                //change the normalization value back to false
                isNormalized(false);
                version = value;
            }
        }
        else{
            //NOT_SUPPORTED_ERR: Raised if the vesion is set to a value that is not supported by
            //this document
            //we dont support any other XML version
            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
            throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);

        }
        if((getXmlVersion()).equals("1.1")){
            xml11Version = true;
        }
        else{
            xml11Version = false;
        }
    
protected voidundeferChildren(org.w3c.dom.Node node)
Traverses the DOM Tree and expands deferred nodes and their children.

        
        Node top = node;
        
        while (null != node) {
            
            if (((NodeImpl)node).needsSyncData()) {
                ((NodeImpl)node).synchronizeData();
            }
            
            NamedNodeMap attributes = node.getAttributes();
            if (attributes != null) {
                int length = attributes.getLength();
                for (int i = 0; i < length; ++i) {
                    undeferChildren(attributes.item(i));
                }
            }
            
            Node nextNode = null;
            nextNode = node.getFirstChild();
            
            while (null == nextNode) {
                
                if (top.equals(node))
                    break;
                
                nextNode = node.getNextSibling();
                
                if (null == nextNode) {
                    node = node.getParentNode();
                    
                    if ((null == node) || (top.equals(node))) {
                        nextNode = null;
                        break;
                    }
                }
            }
            
            node = nextNode;
        }