FileDocCategorySizeDatePackage
AbstractDOMParser.javaAPI DocApache Xerces 3.0.1106612Fri Sep 14 20:33:52 BST 2007org.apache.xerces.parsers

AbstractDOMParser

public class AbstractDOMParser extends AbstractXMLDocumentParser
This is the base class of all DOM parsers. It implements the XNI callback methods to create the DOM tree. After a successful parse of an XML document, the DOM Document object can be queried using the getDocument method. The actual pipeline is defined in parser configuration.
author
Arnaud Le Hors, IBM
author
Andy Clark, IBM
author
Elena Litani, IBM
version
$Id: AbstractDOMParser.java 568412 2007-08-22 04:40:44Z mrglavas $

Fields Summary
protected static final String
NAMESPACES
Feature id: namespace.
protected static final String
CREATE_ENTITY_REF_NODES
Feature id: create entity ref nodes.
protected static final String
INCLUDE_COMMENTS_FEATURE
Feature id: include comments.
protected static final String
CREATE_CDATA_NODES_FEATURE
Feature id: create cdata nodes.
protected static final String
INCLUDE_IGNORABLE_WHITESPACE
Feature id: include ignorable whitespace.
protected static final String
DEFER_NODE_EXPANSION
Feature id: defer node expansion.
private static final String[]
RECOGNIZED_FEATURES
Recognized features.
protected static final String
DOCUMENT_CLASS_NAME
Property id: document class name.
protected static final String
CURRENT_ELEMENT_NODE
private static final String[]
RECOGNIZED_PROPERTIES
Recognized properties.
protected static final String
DEFAULT_DOCUMENT_CLASS_NAME
Default document class name.
protected static final String
CORE_DOCUMENT_CLASS_NAME
protected static final String
PSVI_DOCUMENT_CLASS_NAME
protected static final RuntimeException
ABORT
If the user stops the process, this exception will be thrown.
private static final boolean
DEBUG_EVENTS
private static final boolean
DEBUG_BASEURI
protected org.apache.xerces.util.DOMErrorHandlerWrapper
fErrorHandler
DOM L3 error handler
protected boolean
fInDTD
True if inside DTD.
protected boolean
fCreateEntityRefNodes
Create entity reference nodes.
protected boolean
fIncludeIgnorableWhitespace
Include ignorable whitespace.
protected boolean
fIncludeComments
Include Comments.
protected boolean
fCreateCDATANodes
Create cdata nodes.
protected Document
fDocument
The document.
protected org.apache.xerces.dom.CoreDocumentImpl
fDocumentImpl
The default Xerces document implementation, if used.
protected boolean
fStorePSVI
Whether to store PSVI information in DOM tree.
protected String
fDocumentClassName
The document class name to use.
protected DocumentType
fDocumentType
The document type node.
protected Node
fCurrentNode
Current node.
protected CDATASection
fCurrentCDATASection
protected org.apache.xerces.dom.EntityImpl
fCurrentEntityDecl
protected int
fDeferredEntityDecl
protected final StringBuffer
fStringBuffer
Character buffer
protected StringBuffer
fInternalSubset
Internal subset buffer.
protected boolean
fDeferNodeExpansion
protected boolean
fNamespaceAware
protected org.apache.xerces.dom.DeferredDocumentImpl
fDeferredDocumentImpl
protected int
fDocumentIndex
protected int
fDocumentTypeIndex
protected int
fCurrentNodeIndex
protected int
fCurrentCDATASectionIndex
protected boolean
fInDTDExternalSubset
True if inside DTD external subset.
protected org.apache.xerces.xni.QName
fRoot
Root element name
protected boolean
fInCDATASection
True if inside CDATA section.
protected boolean
fFirstChunk
True if saw the first chunk of characters
protected boolean
fFilterReject
LSParserFilter: specifies that element with given QNAME and all its children must be rejected
protected Stack
fBaseURIStack
Base uri stack
protected final org.apache.xerces.xni.QName
fRejectedElement
LSParserFilter: the QNAME of rejected element
protected Stack
fSkippedElemStack
LSParserFilter: store qnames of skipped elements
protected boolean
fInEntityRef
LSParserFilter: true if inside entity reference
private org.apache.xerces.xni.QName
fAttrQName
Attribute QName.
private org.apache.xerces.xni.XMLLocator
fLocator
Document locator.
protected LSParserFilter
fDOMFilter
Constructors Summary
protected AbstractDOMParser(org.apache.xerces.xni.parser.XMLParserConfiguration config)
Default constructor.


    //
    // Constructors
    //

       
        

        super (config);


        // add recognized features
        fConfiguration.addRecognizedFeatures (RECOGNIZED_FEATURES);

        // set default values
        fConfiguration.setFeature (CREATE_ENTITY_REF_NODES, true);
        fConfiguration.setFeature (INCLUDE_IGNORABLE_WHITESPACE, true);
        fConfiguration.setFeature (DEFER_NODE_EXPANSION, true);
        fConfiguration.setFeature (INCLUDE_COMMENTS_FEATURE, true);
        fConfiguration.setFeature (CREATE_CDATA_NODES_FEATURE, true);

        // add recognized properties
        fConfiguration.addRecognizedProperties (RECOGNIZED_PROPERTIES);

        // set default values
        fConfiguration.setProperty (DOCUMENT_CLASS_NAME,
        DEFAULT_DOCUMENT_CLASS_NAME);

    
Methods Summary
public voidabort()

see
org.w3c.dom.ls.LSParser#abort()

        throw ABORT;
    
public voidattributeDecl(java.lang.String elementName, java.lang.String attributeName, java.lang.String type, java.lang.String[] enumeration, java.lang.String defaultType, org.apache.xerces.xni.XMLString defaultValue, org.apache.xerces.xni.XMLString nonNormalizedDefaultValue, org.apache.xerces.xni.Augmentations augs)
An attribute declaration.

param
elementName The name of the element that this attribute is associated with.
param
attributeName The name of the attribute.
param
type The attribute type. This value will be one of the following: "CDATA", "ENTITY", "ENTITIES", "ENUMERATION", "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", or "NOTATION".
param
enumeration If the type has the value "ENUMERATION" or "NOTATION", this array holds the allowed attribute values; otherwise, this array is null.
param
defaultType The attribute default type. This value will be one of the following: "#FIXED", "#IMPLIED", "#REQUIRED", or null.
param
defaultValue The attribute default value, or null if no default value is specified.
param
nonNormalizedDefaultValue The attribute default value with no normalization performed, or null if no default value is specified.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.


        // internal subset string
        if (fInternalSubset != null && !fInDTDExternalSubset) {
            fInternalSubset.append ("<!ATTLIST ");
            fInternalSubset.append (elementName);
            fInternalSubset.append (' ");
            fInternalSubset.append (attributeName);
            fInternalSubset.append (' ");
            if (type.equals ("ENUMERATION")) {
                fInternalSubset.append ('(");
                for (int i = 0; i < enumeration.length; i++) {
                    if (i > 0) {
                        fInternalSubset.append ('|");
                    }
                    fInternalSubset.append (enumeration[i]);
                }
                fInternalSubset.append (')");
            }
            else {
                fInternalSubset.append (type);
            }
            if (defaultType != null) {
                fInternalSubset.append (' ");
                fInternalSubset.append (defaultType);
            }
            if (defaultValue != null) {
                fInternalSubset.append (" '");
                for (int i = 0; i < defaultValue.length; i++) {
                    char c = defaultValue.ch[defaultValue.offset + i];
                    if (c == '\'") {
                        fInternalSubset.append ("'");
                    }
                    else {
                        fInternalSubset.append (c);
                    }
                }
                fInternalSubset.append ('\'");
            }
            fInternalSubset.append (">\n");
        }
        // REVISIT: This code applies to the support of domx/grammar-access
        // feature in Xerces 1

        // deferred expansion
        if (fDeferredDocumentImpl != null) {

            // get the default value
            if (defaultValue != null) {

                // get element definition
                int elementDefIndex  = fDeferredDocumentImpl.lookupElementDefinition (elementName);

                // create element definition if not already there
                if (elementDefIndex == -1) {
                    elementDefIndex = fDeferredDocumentImpl.createDeferredElementDefinition (elementName);
                    fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, elementDefIndex);
                }
                // add default attribute
                int attrIndex = fDeferredDocumentImpl.createDeferredAttribute (
                attributeName, defaultValue.toString (), false);
                if ("ID".equals (type)) {
                    fDeferredDocumentImpl.setIdAttribute (attrIndex);
                }
                // REVISIT: set ID type correctly
                fDeferredDocumentImpl.appendChild (elementDefIndex, attrIndex);
            }

        } // if deferred

        // full expansion
        else if (fDocumentImpl != null) {

            // get the default value
            if (defaultValue != null) {

                // get element definition node
                NamedNodeMap elements = ((DocumentTypeImpl)fDocumentType).getElements ();
                ElementDefinitionImpl elementDef = (ElementDefinitionImpl)elements.getNamedItem (elementName);
                if (elementDef == null) {
                    elementDef = fDocumentImpl.createElementDefinition (elementName);
                    ((DocumentTypeImpl)fDocumentType).getElements ().setNamedItem (elementDef);
                }

                // REVISIT: Check for uniqueness of element name? -Ac

                // create attribute and set properties
                boolean nsEnabled = fNamespaceAware;
                AttrImpl attr;
                if (nsEnabled) {
                    String namespaceURI = null;
                    // DOM Level 2 wants all namespace declaration attributes
                    // to be bound to "http://www.w3.org/2000/xmlns/"
                    // So as long as the XML parser doesn't do it, it needs to
                    // done here.
                    if (attributeName.startsWith ("xmlns:") ||
                    attributeName.equals ("xmlns")) {
                        namespaceURI = NamespaceContext.XMLNS_URI;
                    }
                    attr = (AttrImpl)fDocumentImpl.createAttributeNS (namespaceURI,
                    attributeName);
                }
                else {
                    attr = (AttrImpl)fDocumentImpl.createAttribute (attributeName);
                }
                attr.setValue (defaultValue.toString ());
                attr.setSpecified (false);
                attr.setIdAttribute ("ID".equals (type));

                // add default attribute to element definition
                if (nsEnabled){
                    elementDef.getAttributes ().setNamedItemNS (attr);
                }
                else {
                    elementDef.getAttributes ().setNamedItem (attr);
                }
            }

        } // if NOT defer-node-expansion

    
public voidcharacters(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
Character content.

param
text The content.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        if (DEBUG_EVENTS) {
            System.out.println ("==>characters(): "+text.toString ());
        }

        if (!fDeferNodeExpansion) {

            if (fFilterReject) {
                return;
            }
            if (fInCDATASection && fCreateCDATANodes) {
                if (fCurrentCDATASection == null) {
                    fCurrentCDATASection =
                    fDocument.createCDATASection (text.toString ());
                    fCurrentNode.appendChild (fCurrentCDATASection);
                    fCurrentNode = fCurrentCDATASection;
                }
                else {
                    fCurrentCDATASection.appendData (text.toString ());
                }
            }
            else if (!fInDTD) {
                // if type is union (XML Schema) it is possible that we receive
                // character call with empty data
                if (text.length == 0) {
                    return;
                }

                Node child = fCurrentNode.getLastChild ();
                if (child != null && child.getNodeType () == Node.TEXT_NODE) {
                    // collect all the data into the string buffer.
                    if (fFirstChunk) {
                        if (fDocumentImpl != null) {
                            fStringBuffer.append (((TextImpl)child).removeData ());
                        } else {
                            fStringBuffer.append (((Text)child).getData ());
                            ((Text)child).setNodeValue (null);
                        }
                        fFirstChunk = false;
                    }
                    if (text.length > 0) {
                        fStringBuffer.append (text.ch, text.offset, text.length);
                    }
                }
                else {
                    fFirstChunk = true;
                    Text textNode = fDocument.createTextNode (text.toString());
                    fCurrentNode.appendChild (textNode);
                }

            }
        }
        else {
            // The Text and CDATASection normalization is taken care of within
            // the DOM in the deferred case.
            if (fInCDATASection && fCreateCDATANodes) {
                if (fCurrentCDATASectionIndex == -1) {
                    int cs = fDeferredDocumentImpl.
                    createDeferredCDATASection (text.toString ());

                    fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, cs);
                    fCurrentCDATASectionIndex = cs;
                    fCurrentNodeIndex = cs;
                }
                else {
                    int txt = fDeferredDocumentImpl.
                    createDeferredTextNode (text.toString (), false);
                    fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, txt);
                }
            } else if (!fInDTD) {
                // if type is union (XML Schema) it is possible that we receive
                // character call with empty data
                if (text.length == 0) {
                    return;
                }

                String value = text.toString ();
                int txt = fDeferredDocumentImpl.
                createDeferredTextNode (value, false);
                fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, txt);

            }
        }
    
public voidcomment(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
A comment.

param
text The text in the comment.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by application to signal an error.

        if (fInDTD) {
            if (fInternalSubset != null && !fInDTDExternalSubset) {
                fInternalSubset.append ("<!--");
                if (text.length > 0) {
                    fInternalSubset.append (text.ch, text.offset, text.length);
                }
                fInternalSubset.append ("-->");
            }
            return;
        }
        if (!fIncludeComments || fFilterReject) {
            return;
        }
        if (!fDeferNodeExpansion) {
            Comment comment = fDocument.createComment (text.toString ());

            setCharacterData (false);
            fCurrentNode.appendChild (comment);
            if (fDOMFilter !=null && !fInEntityRef &&
            (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_COMMENT)!= 0) {
                short code = fDOMFilter.acceptNode (comment);
                switch (code) {
                    case LSParserFilter.FILTER_INTERRUPT:{
                        throw ABORT;
                    }
                    case LSParserFilter.FILTER_REJECT:{
                        // REVISIT: the constant FILTER_REJECT should be changed when new
                        // DOM LS specs gets published

                        // fall through to SKIP since comment has no children.
                    }
                    case LSParserFilter.FILTER_SKIP: {
                        // REVISIT: the constant FILTER_SKIP should be changed when new
                        // DOM LS specs gets published
                        fCurrentNode.removeChild (comment);
                        // make sure we don't loose chars if next event is characters()
                        fFirstChunk = true;
                        return;
                    }

                    default: {
                        // accept node
                    }
                }
            }

        }
        else {
            int comment =
            fDeferredDocumentImpl.createDeferredComment (text.toString ());
            fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, comment);
        }

    
protected org.w3c.dom.AttrcreateAttrNode(org.apache.xerces.xni.QName attrQName)

        Attr attr = null;

        if (fNamespaceAware) {
            if (fDocumentImpl != null) {
                // if we are using xerces DOM implementation, call our
                // own constructor to reuse the strings we have here.
                attr = fDocumentImpl.createAttributeNS (attrQName.uri,
                attrQName.rawname,
                attrQName.localpart);
            }
            else {
                attr = fDocument.createAttributeNS (attrQName.uri,
                attrQName.rawname);
            }
        }
        else {
            attr = fDocument.createAttribute (attrQName.rawname);
        }

        return attr;
    
protected org.w3c.dom.ElementcreateElementNode(org.apache.xerces.xni.QName element)

        Element el = null;

        if (fNamespaceAware) {
            // if we are using xerces DOM implementation, call our
            // own constructor to reuse the strings we have here.
            if (fDocumentImpl != null) {
                el = fDocumentImpl.createElementNS (element.uri, element.rawname,
                element.localpart);
            }
            else {
                el = fDocument.createElementNS (element.uri, element.rawname);
            }
        }
        else {
            el = fDocument.createElement (element.rawname);
        }

        return el;
    
public voiddoctypeDecl(java.lang.String rootElement, java.lang.String publicId, java.lang.String systemId, org.apache.xerces.xni.Augmentations augs)
Notifies of the presence of the DOCTYPE line in the document.

param
rootElement The name of the root element.
param
publicId The public identifier if an external DTD or null if the external DTD is specified using SYSTEM.
param
systemId The system identifier if an external DTD, null otherwise.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        if (!fDeferNodeExpansion) {
            if (fDocumentImpl != null) {
                fDocumentType = fDocumentImpl.createDocumentType (
                rootElement, publicId, systemId);
                fCurrentNode.appendChild (fDocumentType);
            }
        }
        else {
            fDocumentTypeIndex = fDeferredDocumentImpl.
            createDeferredDocumentType (rootElement, publicId, systemId);
            fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, fDocumentTypeIndex);
        }

    
public final voiddropDocumentReferences()
Drops all references to the last DOM which was built by this parser.

        fDocument = null;
        fDocumentImpl = null;
        fDeferredDocumentImpl = null;
        fDocumentType = null;
        fCurrentNode = null;
        fCurrentCDATASection = null;
        fCurrentEntityDecl = null;
    
public voidelementDecl(java.lang.String name, java.lang.String contentModel, org.apache.xerces.xni.Augmentations augs)
An element declaration.

param
name The name of the element.
param
contentModel The element content model.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.


        // internal subset string
        if (fInternalSubset != null && !fInDTDExternalSubset) {
            fInternalSubset.append ("<!ELEMENT ");
            fInternalSubset.append (name);
            fInternalSubset.append (' ");
            fInternalSubset.append (contentModel);
            fInternalSubset.append (">\n");
        }

    
public voidemptyElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.xni.Augmentations augs)
An empty element.

param
element The name of the element.
param
attributes The element attributes.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        startElement (element, attributes, augs);
        endElement (element, augs);

    
public voidendAttlist(org.apache.xerces.xni.Augmentations augs)
The end of an attribute list.

param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

    
public voidendCDATA(org.apache.xerces.xni.Augmentations augs)
The end of a CDATA section.

param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        fInCDATASection = false;
        if (!fDeferNodeExpansion) {

            if (fFilterReject) {
                return;
            }

            if (fCurrentCDATASection !=null) {

                if (fDOMFilter !=null && !fInEntityRef &&
                (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_CDATA_SECTION)!= 0) {
                    short code = fDOMFilter.acceptNode (fCurrentCDATASection);
                    switch (code) {
                        case LSParserFilter.FILTER_INTERRUPT:{
                            throw ABORT;
                        }
                        case LSParserFilter.FILTER_REJECT:{
                            // fall through to SKIP since CDATA section has no children.
                        }
                        case LSParserFilter.FILTER_SKIP: {
                            Node parent = fCurrentNode.getParentNode ();
                            parent.removeChild (fCurrentCDATASection);
                            fCurrentNode = parent;
                            return;
                        }

                        default: {
                            // accept node
                        }
                    }
                }

                fCurrentNode = fCurrentNode.getParentNode ();
                fCurrentCDATASection = null;
            }
        }
        else {
            if (fCurrentCDATASectionIndex !=-1) {
                fCurrentNodeIndex =
                fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex, false);
                fCurrentCDATASectionIndex = -1;
            }
        }

    
public voidendConditional(org.apache.xerces.xni.Augmentations augs)
The end of a conditional section.

param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

    
public voidendDTD(org.apache.xerces.xni.Augmentations augs)
The end of the DTD.

param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>endDTD()");
        }
        fInDTD = false;
        if (!fBaseURIStack.isEmpty ()) {
            fBaseURIStack.pop ();
        }
        String internalSubset = fInternalSubset != null && fInternalSubset.length () > 0
        ? fInternalSubset.toString () : null;
        if (fDeferNodeExpansion) {
            if (internalSubset != null) {
                fDeferredDocumentImpl.setInternalSubset (fDocumentTypeIndex, internalSubset);
            }
        }
        else if (fDocumentImpl != null) {
            if (internalSubset != null) {
                ((DocumentTypeImpl)fDocumentType).setInternalSubset (internalSubset);
            }
        }
    
public voidendDocument(org.apache.xerces.xni.Augmentations augs)
The end of the document.

param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        if (!fDeferNodeExpansion) {
            // REVISIT: when DOM Level 3 is REC rely on Document.support
            //          instead of specific class
            // set the actual encoding and set DOM error checking back on
            if (fDocumentImpl != null) {
                if (fLocator != null) {
                    fDocumentImpl.setInputEncoding (fLocator.getEncoding());
                }
                fDocumentImpl.setStrictErrorChecking (true);
            }
            fCurrentNode = null;
        }
        else {
            // set the actual encoding
            if (fLocator != null) {
                fDeferredDocumentImpl.setInputEncoding (fLocator.getEncoding());
            }
            fCurrentNodeIndex = -1;
        }

    
public voidendElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.Augmentations augs)
The end of an element.

param
element The name of the element.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>endElement ("+element.rawname+")");
        }
        if (!fDeferNodeExpansion) {

            // REVISIT: Should this happen after we call the filter?
            if (augs != null && fDocumentImpl != null && (fNamespaceAware || fStorePSVI)) {
                ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
                if (elementPSVI != null) {
                    // Updating TypeInfo. If the declared type is a union the
                    // [member type definition] will only be available at the
                    // end of an element.
                    if (fNamespaceAware) {
                        XSTypeDefinition type = elementPSVI.getMemberTypeDefinition();
                        if (type == null) {
                            type = elementPSVI.getTypeDefinition();
                        }
                        ((ElementNSImpl)fCurrentNode).setType(type);
                    }
                    if (fStorePSVI) {
                        ((PSVIElementNSImpl)fCurrentNode).setPSVI (elementPSVI);
                    }
                }
            }

            if (fDOMFilter != null) {
                if (fFilterReject) {
                    if (element.equals (fRejectedElement)) {
                        fFilterReject = false;
                    }
                    return;
                }
                if (!fSkippedElemStack.isEmpty ()) {
                    if (fSkippedElemStack.peek ().equals (element)) {
                        fSkippedElemStack.pop ();
                        return;
                    }
                }
                setCharacterData (false);
                if (!fRoot.equals(element) && !fInEntityRef && (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_ELEMENT)!=0) {
                    short code = fDOMFilter.acceptNode (fCurrentNode);
                    switch (code) {
                        case LSParserFilter.FILTER_INTERRUPT:{
                            throw ABORT;
                        }
                        case LSParserFilter.FILTER_REJECT:{
                            Node parent = fCurrentNode.getParentNode ();
                            parent.removeChild (fCurrentNode);
                            fCurrentNode = parent;
                            return;
                        }
                        case LSParserFilter.FILTER_SKIP: {
                            // make sure that if any char data is available
                            // the fFirstChunk is true, so that if the next event
                            // is characters(), and the last node is text, we will copy
                            // the value already in the text node to fStringBuffer
                            // (not to loose it).
                            fFirstChunk = true;

                            // replace children
                            Node parent = fCurrentNode.getParentNode ();
                            NodeList ls = fCurrentNode.getChildNodes ();
                            int length = ls.getLength ();

                            for (int i=0;i<length;i++) {
                                parent.appendChild (ls.item (0));
                            }
                            parent.removeChild (fCurrentNode);
                            fCurrentNode = parent;

                            return;
                        }

                        default: { }
                    }
                }
                fCurrentNode = fCurrentNode.getParentNode ();

            } // end-if DOMFilter
            else {
                setCharacterData (false);
                fCurrentNode = fCurrentNode.getParentNode ();
            }

        }
        else {
            if (augs != null) {
                ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI);
                if (elementPSVI != null) {
                    // Setting TypeInfo. If the declared type is a union the
                    // [member type definition] will only be available at the
                    // end of an element.
                    XSTypeDefinition type = elementPSVI.getMemberTypeDefinition();
                    if (type == null) {
                        type = elementPSVI.getTypeDefinition();
                    }
                    fDeferredDocumentImpl.setTypeInfo(fCurrentNodeIndex, type);
                }
            }
            fCurrentNodeIndex =
                fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex, false);
        }


    
public voidendExternalSubset(org.apache.xerces.xni.Augmentations augs)
The end of the DTD external subset.

param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

        fInDTDExternalSubset = false;
        fBaseURIStack.pop ();
    
public voidendGeneralEntity(java.lang.String name, org.apache.xerces.xni.Augmentations augs)
This method notifies the end of a general entity.

Note: This method is not called for entity references appearing as part of attribute values.

param
name The name of the entity.
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>endGeneralEntity: ("+name+")");
        }
        if (!fDeferNodeExpansion) {

            if (fFilterReject) {
                return;
            }
            setCharacterData (true);

            if (fDocumentType != null) {
                // get current entity declaration
                NamedNodeMap entities = fDocumentType.getEntities ();
                fCurrentEntityDecl = (EntityImpl) entities.getNamedItem (name);
                if (fCurrentEntityDecl != null) {
                    if (fCurrentEntityDecl != null && fCurrentEntityDecl.getFirstChild () == null) {
                        fCurrentEntityDecl.setReadOnly (false, true);
                        Node child = fCurrentNode.getFirstChild ();
                        while (child != null) {
                            Node copy = child.cloneNode (true);
                            fCurrentEntityDecl.appendChild (copy);
                            child = child.getNextSibling ();
                        }
                        fCurrentEntityDecl.setReadOnly (true, true);

                        //entities.setNamedItem(fCurrentEntityDecl);
                    }
                    fCurrentEntityDecl = null;
                }

            }
            fInEntityRef = false;
            boolean removeEntityRef = false;
            if (fCreateEntityRefNodes) {
                if (fDocumentImpl != null) {
                    // Make entity ref node read only
                    ((NodeImpl)fCurrentNode).setReadOnly (true, true);
                }

                if (fDOMFilter !=null &&
                (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_ENTITY_REFERENCE)!= 0) {
                    short code = fDOMFilter.acceptNode (fCurrentNode);
                    switch (code) {
                        case LSParserFilter.FILTER_INTERRUPT:{
                            throw ABORT;
                        }
                        case LSParserFilter.FILTER_REJECT:{
                            Node parent = fCurrentNode.getParentNode ();
                            parent.removeChild (fCurrentNode);
                            fCurrentNode = parent;
                            return;

                        }
                        case LSParserFilter.FILTER_SKIP: {
                            // make sure we don't loose chars if next event is characters()
                            fFirstChunk = true;
                            removeEntityRef = true;
                            break;
                        }

                        default: {
                            fCurrentNode = fCurrentNode.getParentNode ();
                        }
                    }
                } else {
                    fCurrentNode = fCurrentNode.getParentNode ();
                }
            }

            if (!fCreateEntityRefNodes || removeEntityRef) {
                // move entity reference children to the list of
                // siblings of its parent and remove entity reference
                NodeList children = fCurrentNode.getChildNodes ();
                Node parent = fCurrentNode.getParentNode ();
                int length = children.getLength ();
                if (length > 0) {

                    // get previous sibling of the entity reference
                    Node node = fCurrentNode.getPreviousSibling ();
                    // normalize text nodes
                    Node child = children.item (0);
                    if (node != null && node.getNodeType () == Node.TEXT_NODE &&
                    child.getNodeType () == Node.TEXT_NODE) {
                        ((Text)node).appendData (child.getNodeValue ());
                        fCurrentNode.removeChild (child);

                    } else {
                        node = parent.insertBefore (child, fCurrentNode);
                        handleBaseURI (node);
                    }

                    for (int i=1;i <length;i++) {
                        node = parent.insertBefore (children.item (0), fCurrentNode);
                        handleBaseURI (node);
                    }
                } // length > 0
                parent.removeChild (fCurrentNode);
                fCurrentNode = parent;
            }
        }
        else {

            if (fDocumentTypeIndex != -1) {
                // find corresponding Entity decl
                int node = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false);
                while (node != -1) {
                    short nodeType = fDeferredDocumentImpl.getNodeType (node, false);
                    if (nodeType == Node.ENTITY_NODE) {
                        String nodeName =
                        fDeferredDocumentImpl.getNodeName (node, false);
                        if (nodeName.equals (name)) {
                            fDeferredEntityDecl = node;
                            break;
                        }
                    }
                    node = fDeferredDocumentImpl.getRealPrevSibling (node, false);
                }
            }

            if (fDeferredEntityDecl != -1 &&
            fDeferredDocumentImpl.getLastChild (fDeferredEntityDecl, false) == -1) {
                // entity definition exists and it does not have any children
                int prevIndex = -1;
                int childIndex = fDeferredDocumentImpl.getLastChild (fCurrentNodeIndex, false);
                while (childIndex != -1) {
                    int cloneIndex = fDeferredDocumentImpl.cloneNode (childIndex, true);
                    fDeferredDocumentImpl.insertBefore (fDeferredEntityDecl, cloneIndex, prevIndex);
                    prevIndex = cloneIndex;
                    childIndex = fDeferredDocumentImpl.getRealPrevSibling (childIndex, false);
                }
            }
            if (fCreateEntityRefNodes) {
                fCurrentNodeIndex =
                fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex,
                false);
            } else { //!fCreateEntityRefNodes
                // move children of entity ref before the entity ref.
                // remove entity ref.

                // holds a child of entity ref
                int childIndex = fDeferredDocumentImpl.getLastChild (fCurrentNodeIndex, false);
                int parentIndex =
                fDeferredDocumentImpl.getParentNode (fCurrentNodeIndex,
                false);

                int prevIndex = fCurrentNodeIndex;
                int lastChild = childIndex;
                int sibling = -1;
                while (childIndex != -1) {
                    handleBaseURI (childIndex);
                    sibling = fDeferredDocumentImpl.getRealPrevSibling (childIndex, false);
                    fDeferredDocumentImpl.insertBefore (parentIndex, childIndex, prevIndex);
                    prevIndex = childIndex;
                    childIndex = sibling;
                }
                if(lastChild != -1)
                    fDeferredDocumentImpl.setAsLastChild (parentIndex, lastChild);
                else{
                    sibling = fDeferredDocumentImpl.getRealPrevSibling (prevIndex, false);
                    fDeferredDocumentImpl.setAsLastChild (parentIndex, sibling);
                }
                fCurrentNodeIndex = parentIndex;
            }
            fDeferredEntityDecl = -1;
        }


    
public voidendParameterEntity(java.lang.String name, org.apache.xerces.xni.Augmentations augs)
This method notifies the end of a parameter entity. Parameter entity names begin with a '%' character.

param
name The name of the parameter entity.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.


        if (DEBUG_EVENTS) {
            System.out.println ("==>endParameterEntity: "+name);
        }
        fBaseURIStack.pop ();
    
public voidexternalEntityDecl(java.lang.String name, org.apache.xerces.xni.XMLResourceIdentifier identifier, org.apache.xerces.xni.Augmentations augs)
An external entity declaration.

param
name The name of the entity. Parameter entity names start with '%', whereas the name of a general entity is just the entity name.
param
identifier An object containing all location information pertinent to this notation.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.



        if (DEBUG_EVENTS) {
            System.out.println ("==>externalEntityDecl: "+name);
            if (DEBUG_BASEURI) {
                System.out.println ("   expandedSystemId:"+ identifier.getExpandedSystemId ());
                System.out.println ("   baseURI:"+ identifier.getBaseSystemId ());
            }
        }
        // internal subset string
        String publicId = identifier.getPublicId ();
        String literalSystemId = identifier.getLiteralSystemId ();
        if (fInternalSubset != null && !fInDTDExternalSubset) {
            fInternalSubset.append ("<!ENTITY ");
            if (name.startsWith ("%")) {
                fInternalSubset.append ("% ");
                fInternalSubset.append (name.substring (1));
            }
            else {
                fInternalSubset.append (name);
            }
            fInternalSubset.append (' ");
            if (publicId != null) {
                fInternalSubset.append ("PUBLIC '");
                fInternalSubset.append (publicId);
                fInternalSubset.append ("' '");
            }
            else {
                fInternalSubset.append ("SYSTEM '");
            }
            fInternalSubset.append (literalSystemId);
            fInternalSubset.append ("'>\n");
        }

        // NOTE: We only know how to create these nodes for the Xerces
        //       DOM implementation because DOM Level 2 does not specify
        //       that functionality. -Ac

        // create full node
        // don't add parameter entities!
        if(name.startsWith ("%"))
            return;
        if (fDocumentType != null) {
            NamedNodeMap entities = fDocumentType.getEntities ();
            EntityImpl entity = (EntityImpl)entities.getNamedItem (name);
            if (entity == null) {
                entity = (EntityImpl)fDocumentImpl.createEntity (name);
                entity.setPublicId (publicId);
                entity.setSystemId (literalSystemId);
                entity.setBaseURI (identifier.getBaseSystemId ());
                entities.setNamedItem (entity);
            }
        }

        // create deferred node
        if (fDocumentTypeIndex != -1) {
            boolean found = false;
            int nodeIndex = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false);
            while (nodeIndex != -1) {
                short nodeType = fDeferredDocumentImpl.getNodeType (nodeIndex, false);
                if (nodeType == Node.ENTITY_NODE) {
                    String nodeName = fDeferredDocumentImpl.getNodeName (nodeIndex, false);
                    if (nodeName.equals (name)) {
                        found = true;
                        break;
                    }
                }
                nodeIndex = fDeferredDocumentImpl.getRealPrevSibling (nodeIndex, false);
            }
            if (!found) {
                int entityIndex = fDeferredDocumentImpl.createDeferredEntity (
                name, publicId, literalSystemId, null, identifier.getBaseSystemId ());
                fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, entityIndex);
            }
        }

    
public org.w3c.dom.DocumentgetDocument()
Returns the DOM document object.

        return fDocument;
    
protected java.lang.StringgetDocumentClassName()
This method retreives the name of current document class.

        return fDocumentClassName;
    
protected final voidhandleBaseURI(org.w3c.dom.Node node)
Record baseURI information for the Element (by adding xml:base attribute) or for the ProcessingInstruction (by setting a baseURI field) Non deferred DOM.

param
node

        if (fDocumentImpl != null) {
            // REVISIT: remove dependency on our implementation when
            //          DOM L3 becomes REC

            String baseURI = null;
            short nodeType = node.getNodeType ();

            if (nodeType == Node.ELEMENT_NODE) {
                // if an element already has xml:base attribute
                // do nothing
                if (fNamespaceAware) {
                    if (((Element)node).getAttributeNodeNS ("http://www.w3.org/XML/1998/namespace","base")!=null) {
                        return;
                    }
                } else if (((Element)node).getAttributeNode ("xml:base") != null) {
                    return;
                }
                // retrive the baseURI from the entity reference
                baseURI = ((EntityReferenceImpl)fCurrentNode).getBaseURI ();
                if (baseURI !=null && !baseURI.equals (fDocumentImpl.getDocumentURI ())) {
                    if (fNamespaceAware) {
                        ((Element)node).setAttributeNS ("http://www.w3.org/XML/1998/namespace","base", baseURI);
                    } else {
                        ((Element)node).setAttribute ("xml:base", baseURI);
                    }
                }
            }
            else if (nodeType == Node.PROCESSING_INSTRUCTION_NODE) {

                baseURI = ((EntityReferenceImpl)fCurrentNode).getBaseURI ();
                if (baseURI !=null && fErrorHandler != null) {
                    DOMErrorImpl error = new DOMErrorImpl ();
                    error.fType = "pi-base-uri-not-preserved";
                    error.fRelatedData = baseURI;
                    error.fSeverity = DOMError.SEVERITY_WARNING;
                    fErrorHandler.getErrorHandler ().handleError (error);
                }
            }
        }
    
protected final voidhandleBaseURI(int node)
Record baseURI information for the Element (by adding xml:base attribute) or for the ProcessingInstruction (by setting a baseURI field) Deferred DOM.

param
node

        short nodeType = fDeferredDocumentImpl.getNodeType (node, false);

        if (nodeType == Node.ELEMENT_NODE) {
            String baseURI = fDeferredDocumentImpl.getNodeValueString (fCurrentNodeIndex, false);
            if (baseURI == null) {
                baseURI = fDeferredDocumentImpl.getDeferredEntityBaseURI (fDeferredEntityDecl);
            }
            if (baseURI !=null && !baseURI.equals (fDeferredDocumentImpl.getDocumentURI ())) {
                fDeferredDocumentImpl.setDeferredAttribute (node,
                "xml:base",
                "http://www.w3.org/XML/1998/namespace",
                baseURI,
                true);
            }
        }
        else if (nodeType == Node.PROCESSING_INSTRUCTION_NODE) {


            // retrieve baseURI from the entity reference
            String baseURI = fDeferredDocumentImpl.getNodeValueString (fCurrentNodeIndex, false);

            if (baseURI == null) {
                // try baseURI of the entity declaration
                baseURI = fDeferredDocumentImpl.getDeferredEntityBaseURI (fDeferredEntityDecl);
            }

            if (baseURI != null && fErrorHandler != null) {
                DOMErrorImpl error = new DOMErrorImpl ();
                error.fType = "pi-base-uri-not-preserved";
                error.fRelatedData = baseURI;
                error.fSeverity = DOMError.SEVERITY_WARNING;
                fErrorHandler.getErrorHandler ().handleError (error);
            }
        }
    
public voidignorableWhitespace(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
Ignorable whitespace. For this method to be called, the document source must have some way of determining that the text containing only whitespace characters should be considered ignorable. For example, the validator can determine if a length of whitespace characters in the document are ignorable based on the element content model.

param
text The ignorable whitespace.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        if (!fIncludeIgnorableWhitespace || fFilterReject) {
            return;
        }
        if (!fDeferNodeExpansion) {
            Node child = fCurrentNode.getLastChild ();
            if (child != null && child.getNodeType () == Node.TEXT_NODE) {
                Text textNode = (Text)child;
                textNode.appendData (text.toString ());
            }
            else {
                Text textNode = fDocument.createTextNode (text.toString ());
                if (fDocumentImpl != null) {
                    TextImpl textNodeImpl = (TextImpl)textNode;
                    textNodeImpl.setIgnorableWhitespace (true);
                }
                fCurrentNode.appendChild (textNode);
            }
        }
        else {
            // The Text normalization is taken care of within the DOM in the
            // deferred case.
            int txt = fDeferredDocumentImpl.
            createDeferredTextNode (text.toString (), true);
            fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, txt);
        }

    
public voidignoredCharacters(org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.Augmentations augs)
Characters within an IGNORE conditional section.

param
text The ignored text.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

    
public voidinternalEntityDecl(java.lang.String name, org.apache.xerces.xni.XMLString text, org.apache.xerces.xni.XMLString nonNormalizedText, org.apache.xerces.xni.Augmentations augs)
An internal entity declaration.

param
name The name of the entity. Parameter entity names start with '%', whereas the name of a general entity is just the entity name.
param
text The value of the entity.
param
nonNormalizedText The non-normalized value of the entity. This value contains the same sequence of characters that was in the internal entity declaration, without any entity references expanded.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.


        if (DEBUG_EVENTS) {
            System.out.println ("==>internalEntityDecl: "+name);
            if (DEBUG_BASEURI) {
                System.out.println ("   baseURI:"+ (String)fBaseURIStack.peek ());
            }
        }
        // internal subset string
        if (fInternalSubset != null && !fInDTDExternalSubset) {
            fInternalSubset.append ("<!ENTITY ");
            if (name.startsWith ("%")) {
                fInternalSubset.append ("% ");
                fInternalSubset.append (name.substring (1));
            }
            else {
                fInternalSubset.append (name);
            }
            fInternalSubset.append (' ");
            String value = nonNormalizedText.toString ();
            boolean singleQuote = value.indexOf ('\'") == -1;
            fInternalSubset.append (singleQuote ? '\'" : '"");
            fInternalSubset.append (value);
            fInternalSubset.append (singleQuote ? '\'" : '"");
            fInternalSubset.append (">\n");
        }

        // NOTE: We only know how to create these nodes for the Xerces
        //       DOM implementation because DOM Level 2 does not specify
        //       that functionality. -Ac

        // create full node
        // don't add parameter entities!
        if(name.startsWith ("%"))
            return;
        if (fDocumentType != null) {
            NamedNodeMap entities = fDocumentType.getEntities ();
            EntityImpl entity = (EntityImpl)entities.getNamedItem (name);
            if (entity == null) {
                entity = (EntityImpl)fDocumentImpl.createEntity (name);
                entity.setBaseURI ((String)fBaseURIStack.peek ());
                entities.setNamedItem (entity);
            }
        }

        // create deferred node
        if (fDocumentTypeIndex != -1) {
            boolean found = false;
            int node = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false);
            while (node != -1) {
                short nodeType = fDeferredDocumentImpl.getNodeType (node, false);
                if (nodeType == Node.ENTITY_NODE) {
                    String nodeName = fDeferredDocumentImpl.getNodeName (node, false);
                    if (nodeName.equals (name)) {
                        found = true;
                        break;
                    }
                }
                node = fDeferredDocumentImpl.getRealPrevSibling (node, false);
            }
            if (!found) {
                int entityIndex =
                fDeferredDocumentImpl.createDeferredEntity (name, null, null, null, (String)fBaseURIStack.peek ());
                fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, entityIndex);
            }
        }

    
public voidnotationDecl(java.lang.String name, org.apache.xerces.xni.XMLResourceIdentifier identifier, org.apache.xerces.xni.Augmentations augs)
A notation declaration

param
name The name of the notation.
param
identifier An object containing all location information pertinent to this notation.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.


        // internal subset string
        String publicId = identifier.getPublicId ();
        String literalSystemId = identifier.getLiteralSystemId ();
        if (fInternalSubset != null && !fInDTDExternalSubset) {
            fInternalSubset.append ("<!NOTATION ");
            fInternalSubset.append (name);
            if (publicId != null) {
                fInternalSubset.append (" PUBLIC '");
                fInternalSubset.append (publicId);
                if (literalSystemId != null) {
                    fInternalSubset.append ("' '");
                    fInternalSubset.append (literalSystemId);
                }
            }
            else {
                fInternalSubset.append (" SYSTEM '");
                fInternalSubset.append (literalSystemId);
            }
            fInternalSubset.append ("'>\n");
        }

        // NOTE: We only know how to create these nodes for the Xerces
        //       DOM implementation because DOM Level 2 does not specify
        //       that functionality. -Ac

        // create full node
        if (fDocumentImpl !=null && fDocumentType != null) {
            NamedNodeMap notations = fDocumentType.getNotations ();
            if (notations.getNamedItem (name) == null) {
                NotationImpl notation = (NotationImpl)fDocumentImpl.createNotation (name);
                notation.setPublicId (publicId);
                notation.setSystemId (literalSystemId);
                notation.setBaseURI (identifier.getBaseSystemId ());
                notations.setNamedItem (notation);
            }
        }

        // create deferred node
        if (fDocumentTypeIndex != -1) {
            boolean found = false;
            int nodeIndex = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false);
            while (nodeIndex != -1) {
                short nodeType = fDeferredDocumentImpl.getNodeType (nodeIndex, false);
                if (nodeType == Node.NOTATION_NODE) {
                    String nodeName = fDeferredDocumentImpl.getNodeName (nodeIndex, false);
                    if (nodeName.equals (name)) {
                        found = true;
                        break;
                    }
                }
                nodeIndex = fDeferredDocumentImpl.getPrevSibling (nodeIndex, false);
            }
            if (!found) {
                int notationIndex = fDeferredDocumentImpl.createDeferredNotation (
                name, publicId, literalSystemId, identifier.getBaseSystemId ());
                fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, notationIndex);
            }
        }

    
public voidprocessingInstruction(java.lang.String target, org.apache.xerces.xni.XMLString data, org.apache.xerces.xni.Augmentations augs)
A processing instruction. Processing instructions consist of a target name and, optionally, text data. The data is only meaningful to the application.

Typically, a processing instruction's data will contain a series of pseudo-attributes. These pseudo-attributes follow the form of element attributes but are not parsed or presented to the application as anything other than text. The application is responsible for parsing the data.

param
target The target.
param
data The data or null if none specified.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        if (fInDTD) {
            if (fInternalSubset != null && !fInDTDExternalSubset) {
                fInternalSubset.append ("<?");
                fInternalSubset.append (target);
                if (data.length > 0) {
                    fInternalSubset.append (' ").append (data.ch, data.offset, data.length);
                }
                fInternalSubset.append ("?>");
            }
            return;
        }

        if (DEBUG_EVENTS) {
            System.out.println ("==>processingInstruction ("+target+")");
        }
        if (!fDeferNodeExpansion) {
            if (fFilterReject) {
                return;
            }
            ProcessingInstruction pi =
            fDocument.createProcessingInstruction (target, data.toString ());


            setCharacterData (false);
            fCurrentNode.appendChild (pi);
            if (fDOMFilter !=null && !fInEntityRef &&
            (fDOMFilter.getWhatToShow () & NodeFilter.SHOW_PROCESSING_INSTRUCTION)!= 0) {
                short code = fDOMFilter.acceptNode (pi);
                switch (code) {
                    case LSParserFilter.FILTER_INTERRUPT:{
                        throw ABORT;
                    }
                    case LSParserFilter.FILTER_REJECT:{
                        // fall through to SKIP since PI has no children.
                    }
                    case LSParserFilter.FILTER_SKIP: {
                        fCurrentNode.removeChild (pi);
                        // fFirstChunk must be set to true so that data
                        // won't be lost in the case where the child before PI is
                        // a text node and the next event is characters.
                        fFirstChunk = true;
                        return;
                    }
                    default: {
                    }
                }
            }
        }
        else {
            int pi = fDeferredDocumentImpl.
            createDeferredProcessingInstruction (target, data.toString ());
            fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, pi);
        }

    
public voidreset()
Resets the parser state.

throws
SAXException Thrown on initialization error.

        super.reset ();


        // get feature state
        fCreateEntityRefNodes =
        fConfiguration.getFeature (CREATE_ENTITY_REF_NODES);

        fIncludeIgnorableWhitespace =
        fConfiguration.getFeature (INCLUDE_IGNORABLE_WHITESPACE);

        fDeferNodeExpansion =
        fConfiguration.getFeature (DEFER_NODE_EXPANSION);

        fNamespaceAware = fConfiguration.getFeature (NAMESPACES);

        fIncludeComments = fConfiguration.getFeature (INCLUDE_COMMENTS_FEATURE);

        fCreateCDATANodes = fConfiguration.getFeature (CREATE_CDATA_NODES_FEATURE);

        // get property
        setDocumentClassName ((String)
        fConfiguration.getProperty (DOCUMENT_CLASS_NAME));

        // reset dom information
        fDocument = null;
        fDocumentImpl = null;
        fStorePSVI = false;
        fDocumentType = null;
        fDocumentTypeIndex = -1;
        fDeferredDocumentImpl = null;
        fCurrentNode = null;

        // reset string buffer
        fStringBuffer.setLength (0);

        // reset state information
        fRoot.clear();
        fInDTD = false;
        fInDTDExternalSubset = false;
        fInCDATASection = false;
        fFirstChunk = false;
        fCurrentCDATASection = null;
        fCurrentCDATASectionIndex = -1;

        fBaseURIStack.removeAllElements ();


    
protected voidsetCharacterData(boolean sawChars)


        // handle character data
        fFirstChunk = sawChars;


        // if we have data in the buffer we must have created
        // a text node already.

        Node child = fCurrentNode.getLastChild ();
        if (child != null) {
            if (fStringBuffer.length () > 0) {
                // REVISIT: should this check be performed?
                if (child.getNodeType () == Node.TEXT_NODE) {
                    if (fDocumentImpl != null) {
                        ((TextImpl)child).replaceData (fStringBuffer.toString ());
                    }
                    else {
                        ((Text)child).setData (fStringBuffer.toString ());
                    }
                }
                // reset string buffer
                fStringBuffer.setLength (0);
            }

            if (fDOMFilter !=null && !fInEntityRef) {
                if ( (child.getNodeType () == Node.TEXT_NODE ) &&
                ((fDOMFilter.getWhatToShow () & NodeFilter.SHOW_TEXT)!= 0) ) {
                    short code = fDOMFilter.acceptNode (child);
                    switch (code) {
                        case LSParserFilter.FILTER_INTERRUPT:{
                            throw ABORT;
                        }
                        case LSParserFilter.FILTER_REJECT:{
                            // fall through to SKIP since Comment has no children.
                        }
                        case LSParserFilter.FILTER_SKIP: {
                            fCurrentNode.removeChild (child);
                            return;
                        }
                        default: {
                            // accept node -- do nothing
                        }
                    }
                }
            }   // end-if fDOMFilter !=null

        } // end-if child !=null
    
protected voidsetDocumentClassName(java.lang.String documentClassName)
This method allows the programmer to decide which document factory to use when constructing the DOM tree. However, doing so will lose the functionality of the default factory. Also, a document class other than the default will lose the ability to defer node expansion on the DOM tree produced.

param
documentClassName The fully qualified class name of the document factory to use when constructing the DOM tree.
see
#getDocumentClassName
see
#DEFAULT_DOCUMENT_CLASS_NAME


        // normalize class name
        if (documentClassName == null) {
            documentClassName = DEFAULT_DOCUMENT_CLASS_NAME;
        }

        if (!documentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME) &&
            !documentClassName.equals(PSVI_DOCUMENT_CLASS_NAME)) {
            // verify that this class exists and is of the right type
            try {
                Class _class = ObjectFactory.findProviderClass (documentClassName,
                ObjectFactory.findClassLoader (), true);
                //if (!_class.isAssignableFrom(Document.class)) {
                if (!Document.class.isAssignableFrom (_class)) {
                    throw new IllegalArgumentException (
                        DOMMessageFormatter.formatMessage(
                        DOMMessageFormatter.DOM_DOMAIN,
                        "InvalidDocumentClassName", new Object [] {documentClassName}));
                }
            }
            catch (ClassNotFoundException e) {
                throw new IllegalArgumentException (
                    DOMMessageFormatter.formatMessage(
                    DOMMessageFormatter.DOM_DOMAIN,
                    "MissingDocumentClassName", new Object [] {documentClassName}));
            }
        }

        // set document class name
        fDocumentClassName = documentClassName;
        if (!documentClassName.equals (DEFAULT_DOCUMENT_CLASS_NAME)) {
            fDeferNodeExpansion = false;
        }

    
public voidsetLocale(java.util.Locale locale)
Set the locale to use for messages.

param
locale The locale object to use for localization of messages.

        fConfiguration.setLocale (locale);

    
public voidstartAttlist(java.lang.String elementName, org.apache.xerces.xni.Augmentations augs)
The start of an attribute list.

param
elementName The name of the element that this attribute list is associated with.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

    
public voidstartCDATA(org.apache.xerces.xni.Augmentations augs)
The start of a CDATA section.

param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        fInCDATASection = true;
        if (!fDeferNodeExpansion) {
            if (fFilterReject) {
                return;
            }
            if (fCreateCDATANodes) {
                setCharacterData (false);
            }
        }
    
public voidstartConditional(short type, org.apache.xerces.xni.Augmentations augs)
The start of a conditional section.

param
type The type of the conditional section. This value will either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.
see
#CONDITIONAL_INCLUDE
see
#CONDITIONAL_IGNORE

    
public voidstartDTD(org.apache.xerces.xni.XMLLocator locator, org.apache.xerces.xni.Augmentations augs)
The start of the DTD.

param
locator The document locator, or null if the document location cannot be reported during the parsing of the document DTD. However, it is strongly recommended that a locator be supplied that can at least report the base system identifier of the DTD.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>startDTD");
            if (DEBUG_BASEURI) {
                System.out.println ("   expandedSystemId: "+locator.getExpandedSystemId ());
                System.out.println ("   baseURI:"+ locator.getBaseSystemId ());
            }
        }

        fInDTD = true;
        if (locator != null) {
            fBaseURIStack.push (locator.getBaseSystemId ());
        }
        if (fDeferNodeExpansion || fDocumentImpl != null) {
            fInternalSubset = new StringBuffer (1024);
        }
    
public voidstartDocument(org.apache.xerces.xni.XMLLocator locator, java.lang.String encoding, org.apache.xerces.xni.NamespaceContext namespaceContext, org.apache.xerces.xni.Augmentations augs)
The start of the document.

param
locator The system identifier of the entity if the entity is external, null otherwise.
param
encoding The auto-detected IANA encoding name of the entity stream. This value will be null in those situations where the entity encoding is not auto-detected (e.g. internal entities or a document entity that is parsed from a java.io.Reader).
param
namespaceContext The namespace context in effect at the start of this document. This object represents the current context. Implementors of this class are responsible for copying the namespace bindings from the the current context (and its parent contexts) if that information is important.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.


        fLocator = locator;
        if (!fDeferNodeExpansion) {
            if (fDocumentClassName.equals (DEFAULT_DOCUMENT_CLASS_NAME)) {
                fDocument = new DocumentImpl ();
                fDocumentImpl = (CoreDocumentImpl)fDocument;
                // REVISIT: when DOM Level 3 is REC rely on Document.support
                //          instead of specific class
                // set DOM error checking off
                fDocumentImpl.setStrictErrorChecking (false);
                // set actual encoding
                fDocumentImpl.setInputEncoding (encoding);
                // set documentURI
                fDocumentImpl.setDocumentURI (locator.getExpandedSystemId ());
            }
            else if (fDocumentClassName.equals (PSVI_DOCUMENT_CLASS_NAME)) {
                fDocument = new PSVIDocumentImpl();
                fDocumentImpl = (CoreDocumentImpl)fDocument;
                fStorePSVI = true;
                // REVISIT: when DOM Level 3 is REC rely on Document.support
                //          instead of specific class
                // set DOM error checking off
                fDocumentImpl.setStrictErrorChecking (false);
                // set actual encoding
                fDocumentImpl.setInputEncoding (encoding);
                // set documentURI
                fDocumentImpl.setDocumentURI (locator.getExpandedSystemId ());
            }
            else {
                // use specified document class
                try {
                    ClassLoader cl = ObjectFactory.findClassLoader();
                    Class documentClass = ObjectFactory.findProviderClass (fDocumentClassName,
                        cl, true);
                    fDocument = (Document)documentClass.newInstance ();

                    // if subclass of our own class that's cool too
                    Class defaultDocClass =
                    ObjectFactory.findProviderClass (CORE_DOCUMENT_CLASS_NAME,
                        cl, true);
                    if (defaultDocClass.isAssignableFrom (documentClass)) {
                        fDocumentImpl = (CoreDocumentImpl)fDocument;

                        Class psviDocClass = ObjectFactory.findProviderClass (PSVI_DOCUMENT_CLASS_NAME,
                            cl, true);
                        if (psviDocClass.isAssignableFrom (documentClass)) {
                            fStorePSVI = true;
                        }

                        // REVISIT: when DOM Level 3 is REC rely on
                        //          Document.support instead of specific class
                        // set DOM error checking off
                        fDocumentImpl.setStrictErrorChecking (false);
                        // set actual encoding
                        fDocumentImpl.setInputEncoding (encoding);
                        // set documentURI
                        if (locator != null) {
                            fDocumentImpl.setDocumentURI (locator.getExpandedSystemId ());
                        }
                    }
                }
                catch (ClassNotFoundException e) {
                    // won't happen we already checked that earlier
                }
                catch (Exception e) {
                    throw new RuntimeException (
                        DOMMessageFormatter.formatMessage(
                        DOMMessageFormatter.DOM_DOMAIN,
                        "CannotCreateDocumentClass",
                        new Object [] {fDocumentClassName}));
                }
            }
            fCurrentNode = fDocument;
        }
        else {
            fDeferredDocumentImpl = new DeferredDocumentImpl (fNamespaceAware);
            fDocument = fDeferredDocumentImpl;
            fDocumentIndex = fDeferredDocumentImpl.createDeferredDocument ();
            // REVISIT: strict error checking is not implemented in deferred dom.
            //          Document.support instead of specific class

            // set actual encoding
            fDeferredDocumentImpl.setInputEncoding (encoding);
            // set documentURI
            fDeferredDocumentImpl.setDocumentURI (locator.getExpandedSystemId ());
            fCurrentNodeIndex = fDocumentIndex;

        }

    
public voidstartElement(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.xni.Augmentations augs)
The start of an element. If the document specifies the start element by using an empty tag, then the startElement method will immediately be followed by the endElement method, with no intervening methods.

param
element The name of the element.
param
attributes The element attributes.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>startElement ("+element.rawname+")");
        }
        if (!fDeferNodeExpansion) {
            if (fFilterReject) {
                return;
            }
            Element el = createElementNode (element);
            int attrCount = attributes.getLength ();
            boolean seenSchemaDefault = false;
            for (int i = 0; i < attrCount; i++) {
                attributes.getName (i, fAttrQName);
                Attr attr = createAttrNode (fAttrQName);

                String attrValue = attributes.getValue (i);

                AttributePSVI attrPSVI =(AttributePSVI) attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_PSVI);
                if (fStorePSVI && attrPSVI != null){
                    ((PSVIAttrNSImpl) attr).setPSVI (attrPSVI);
                }

                attr.setValue (attrValue);
                boolean specified = attributes.isSpecified(i);
                // Take special care of schema defaulted attributes. Calling the 
                // non-namespace aware setAttributeNode() method could overwrite
                // another attribute with the same local name.
                if (!specified && (seenSchemaDefault || (fAttrQName.uri != null && fAttrQName.prefix == null))) {
                    el.setAttributeNodeNS(attr);
                    seenSchemaDefault = true;
                }
                else {
                    el.setAttributeNode(attr);
                }
                // NOTE: The specified value MUST be set after you set
                //       the node value because that turns the "specified"
                //       flag to "true" which may overwrite a "false"
                //       value from the attribute list. -Ac
                if (fDocumentImpl != null) {
                    AttrImpl attrImpl = (AttrImpl) attr;
                    Object type = null;
                    boolean id = false;

                    // REVISIT: currently it is possible that someone turns off
                    // namespaces and turns on xml schema validation
                    // To avoid classcast exception in AttrImpl check for namespaces
                    // however the correct solution should probably disallow setting
                    // namespaces to false when schema processing is turned on.
                    if (attrPSVI != null && fNamespaceAware) {
                        // XML Schema
                        type = attrPSVI.getMemberTypeDefinition ();
                        if (type == null) {
                            type = attrPSVI.getTypeDefinition ();
                            if (type != null) {
                                id = ((XSSimpleType) type).isIDType ();
                                attrImpl.setType (type);
                            }
                        }
                        else {
                            id = ((XSSimpleType) type).isIDType ();
                            attrImpl.setType (type);
                        }
                    }
                    else {
                        // DTD
                        boolean isDeclared = Boolean.TRUE.equals (attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_DECLARED));
                        // For DOM Level 3 TypeInfo, the type name must
                        // be null if this attribute has not been declared
                        // in the DTD.
                        if (isDeclared) {
                            type = attributes.getType (i);
                            id = "ID".equals (type);
                        }
                        attrImpl.setType (type);
                    }

                    if (id) {
                        ((ElementImpl) el).setIdAttributeNode (attr, true);
                    }

                    attrImpl.setSpecified (specified);
                    // REVISIT: Handle entities in attribute value.
                }
            }
            setCharacterData (false);

            if (augs != null) {
                ElementPSVI elementPSVI = (ElementPSVI)augs.getItem (Constants.ELEMENT_PSVI);
                if (elementPSVI != null && fNamespaceAware) {
                    XSTypeDefinition type = elementPSVI.getMemberTypeDefinition ();
                    if (type == null) {
                        type = elementPSVI.getTypeDefinition ();
                    }
                    ((ElementNSImpl)el).setType (type);
                }
            }


            // filter nodes
            if (fDOMFilter != null && !fInEntityRef) {
                if (fRoot.rawname == null) {
                    // fill value of the root element
                    fRoot.setValues(element);
                } else {
                    short code = fDOMFilter.startElement(el);
                    switch (code) {
                        case LSParserFilter.FILTER_INTERRUPT :
                            {
                                throw ABORT;
                            }
                        case LSParserFilter.FILTER_REJECT :
                            {
                                fFilterReject = true;
                                fRejectedElement.setValues(element);
                                return;
                            }
                        case LSParserFilter.FILTER_SKIP :
                            {
                                fSkippedElemStack.push(element.clone());
                                return;
                            }
                        default : {}
                    }
                }
            }
            fCurrentNode.appendChild (el);
            fCurrentNode = el;
        }
        else {
            int el = fDeferredDocumentImpl.createDeferredElement (fNamespaceAware ?
                    element.uri : null, element.rawname);
            Object type = null;
            int attrCount = attributes.getLength ();
            // Need to loop in reverse order so that the attributes
            // are processed in document order when the DOM is expanded.
            for (int i = attrCount - 1; i >= 0; --i) {
                
                // set type information
                AttributePSVI attrPSVI = (AttributePSVI)attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_PSVI);
                boolean id = false;

                // REVISIT: currently it is possible that someone turns off
                // namespaces and turns on xml schema validation
                // To avoid classcast exception in AttrImpl check for namespaces
                // however the correct solution should probably disallow setting
                // namespaces to false when schema processing is turned on.
                if (attrPSVI != null && fNamespaceAware) {
                    // XML Schema
                    type = attrPSVI.getMemberTypeDefinition ();
                    if (type == null) {
                        type = attrPSVI.getTypeDefinition ();
                        if (type != null){
                            id = ((XSSimpleType) type).isIDType ();
                        }
                    }
                    else {
                        id = ((XSSimpleType) type).isIDType ();
                    }
                }
                else {
                    // DTD
                    boolean isDeclared = Boolean.TRUE.equals (attributes.getAugmentations (i).getItem (Constants.ATTRIBUTE_DECLARED));
                    // For DOM Level 3 TypeInfo, the type name must
                    // be null if this attribute has not been declared
                    // in the DTD.
                    if (isDeclared) {
                        type = attributes.getType (i);
                        id = "ID".equals (type);
                    }
                }

                // create attribute
                fDeferredDocumentImpl.setDeferredAttribute (
                el,
                attributes.getQName (i),
                attributes.getURI (i),
                attributes.getValue (i),
                attributes.isSpecified (i),
                id,
                type);
            }

            fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, el);
            fCurrentNodeIndex = el;
        }
    
public voidstartExternalSubset(org.apache.xerces.xni.XMLResourceIdentifier identifier, org.apache.xerces.xni.Augmentations augs)
The start of the DTD external subset.

param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>startExternalSubset");
            if (DEBUG_BASEURI) {
                System.out.println ("   expandedSystemId: "+identifier.getExpandedSystemId ());
                System.out.println ("   baseURI:"+ identifier.getBaseSystemId ());
            }
        }
        fBaseURIStack.push (identifier.getBaseSystemId ());
        fInDTDExternalSubset = true;
    
public voidstartGeneralEntity(java.lang.String name, org.apache.xerces.xni.XMLResourceIdentifier identifier, java.lang.String encoding, org.apache.xerces.xni.Augmentations augs)
This method notifies the start of a general entity.

Note: This method is not called for entity references appearing as part of attribute values.

param
name The name of the general entity.
param
identifier The resource identifier.
param
encoding The auto-detected IANA encoding name of the entity stream. This value will be null in those situations where the entity encoding is not auto-detected (e.g. internal entities or a document entity that is parsed from a java.io.Reader).
param
augs Additional information that may include infoset augmentations
exception
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>startGeneralEntity ("+name+")");
            if (DEBUG_BASEURI) {
                System.out.println ("   expandedSystemId( **baseURI): "+identifier.getExpandedSystemId ());
                System.out.println ("   baseURI:"+ identifier.getBaseSystemId ());
            }
        }

        // Always create entity reference nodes to be able to recreate
        // entity as a part of doctype
        if (!fDeferNodeExpansion) {
            if (fFilterReject) {
                return;
            }
            setCharacterData (true);
            EntityReference er = fDocument.createEntityReference (name);
            if (fDocumentImpl != null) {
                // REVISIT: baseURI/actualEncoding
                //         remove dependency on our implementation when DOM L3 is REC
                //

                EntityReferenceImpl erImpl =(EntityReferenceImpl)er;

                // set base uri
                erImpl.setBaseURI (identifier.getExpandedSystemId ());
                if (fDocumentType != null) {
                    // set actual encoding
                    NamedNodeMap entities = fDocumentType.getEntities ();
                    fCurrentEntityDecl = (EntityImpl) entities.getNamedItem (name);
                    if (fCurrentEntityDecl != null) {
                        fCurrentEntityDecl.setInputEncoding (encoding);
                    }

                }
                // we don't need synchronization now, because entity ref will be
                // expanded anyway. Synch only needed when user creates entityRef node
                erImpl.needsSyncChildren (false);
            }
            fInEntityRef = true;
            fCurrentNode.appendChild (er);
            fCurrentNode = er;
        }
        else {

            int er =
            fDeferredDocumentImpl.createDeferredEntityReference (name, identifier.getExpandedSystemId ());
            if (fDocumentTypeIndex != -1) {
                // find corresponding Entity decl
                int node = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false);
                while (node != -1) {
                    short nodeType = fDeferredDocumentImpl.getNodeType (node, false);
                    if (nodeType == Node.ENTITY_NODE) {
                        String nodeName =
                        fDeferredDocumentImpl.getNodeName (node, false);
                        if (nodeName.equals (name)) {
                            fDeferredEntityDecl = node;
                            fDeferredDocumentImpl.setInputEncoding (node, encoding);
                            break;
                        }
                    }
                    node = fDeferredDocumentImpl.getRealPrevSibling (node, false);
                }
            }
            fDeferredDocumentImpl.appendChild (fCurrentNodeIndex, er);
            fCurrentNodeIndex = er;
        }

    
public voidstartParameterEntity(java.lang.String name, org.apache.xerces.xni.XMLResourceIdentifier identifier, java.lang.String encoding, org.apache.xerces.xni.Augmentations augs)
This method notifies of the start of a parameter entity. The parameter entity name start with a '%' character.

param
name The name of the parameter entity.
param
identifier The resource identifier.
param
encoding The auto-detected IANA encoding name of the entity stream. This value will be null in those situations where the entity encoding is not auto-detected (e.g. internal parameter entities).
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.

        if (DEBUG_EVENTS) {
            System.out.println ("==>startParameterEntity: "+name);
            if (DEBUG_BASEURI) {
                System.out.println ("   expandedSystemId: "+identifier.getExpandedSystemId ());
                System.out.println ("   baseURI:"+ identifier.getBaseSystemId ());
            }
        }
        if (augs != null && fInternalSubset != null && 
            !fInDTDExternalSubset && 
            Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
            fInternalSubset.append(name).append(";\n");
        }
        fBaseURIStack.push (identifier.getExpandedSystemId ());
    
public voidtextDecl(java.lang.String version, java.lang.String encoding, org.apache.xerces.xni.Augmentations augs)
Notifies of the presence of a TextDecl line in an entity. If present, this method will be called immediately following the startEntity call.

Note: This method will never be called for the document entity; it is only called for external general entities referenced in document content.

Note: This method is not called for entity references appearing as part of attribute values.

param
version The XML version, or null if not specified.
param
encoding The IANA encoding name of the entity.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.

        if (fInDTD){
            return;
        }
        if (!fDeferNodeExpansion) {
            if (fCurrentEntityDecl != null && !fFilterReject) {
                fCurrentEntityDecl.setXmlEncoding (encoding);
                if (version != null)
                    fCurrentEntityDecl.setXmlVersion (version);
            }
        }
        else {
            if (fDeferredEntityDecl !=-1) {
                fDeferredDocumentImpl.setEntityInfo (fDeferredEntityDecl, version, encoding);
            }
        }
    
public voidunparsedEntityDecl(java.lang.String name, org.apache.xerces.xni.XMLResourceIdentifier identifier, java.lang.String notation, org.apache.xerces.xni.Augmentations augs)
An unparsed entity declaration.

param
name The name of the entity.
param
identifier An object containing all location information pertinent to this entity.
param
notation The name of the notation.
param
augs Additional information that may include infoset augmentations.
throws
XNIException Thrown by handler to signal an error.


        if (DEBUG_EVENTS) {
            System.out.println ("==>unparsedEntityDecl: "+name);
            if (DEBUG_BASEURI) {
                System.out.println ("   expandedSystemId:"+ identifier.getExpandedSystemId ());
                System.out.println ("   baseURI:"+ identifier.getBaseSystemId ());
            }
        }
        // internal subset string
        String publicId = identifier.getPublicId ();
        String literalSystemId = identifier.getLiteralSystemId ();
        if (fInternalSubset != null && !fInDTDExternalSubset) {
            fInternalSubset.append ("<!ENTITY ");
            fInternalSubset.append (name);
            fInternalSubset.append (' ");
            if (publicId != null) {
                fInternalSubset.append ("PUBLIC '");
                fInternalSubset.append (publicId);
                if (literalSystemId != null) {
                    fInternalSubset.append ("' '");
                    fInternalSubset.append (literalSystemId);
                }
            }
            else {
                fInternalSubset.append ("SYSTEM '");
                fInternalSubset.append (literalSystemId);
            }
            fInternalSubset.append ("' NDATA ");
            fInternalSubset.append (notation);
            fInternalSubset.append (">\n");
        }

        // NOTE: We only know how to create these nodes for the Xerces
        //       DOM implementation because DOM Level 2 does not specify
        //       that functionality. -Ac

        // create full node
        if (fDocumentType != null) {
            NamedNodeMap entities = fDocumentType.getEntities ();
            EntityImpl entity = (EntityImpl)entities.getNamedItem (name);
            if (entity == null) {
                entity = (EntityImpl)fDocumentImpl.createEntity (name);
                entity.setPublicId (publicId);
                entity.setSystemId (literalSystemId);
                entity.setNotationName (notation);
                entity.setBaseURI (identifier.getBaseSystemId ());
                entities.setNamedItem (entity);
            }
        }

        // create deferred node
        if (fDocumentTypeIndex != -1) {
            boolean found = false;
            int nodeIndex = fDeferredDocumentImpl.getLastChild (fDocumentTypeIndex, false);
            while (nodeIndex != -1) {
                short nodeType = fDeferredDocumentImpl.getNodeType (nodeIndex, false);
                if (nodeType == Node.ENTITY_NODE) {
                    String nodeName = fDeferredDocumentImpl.getNodeName (nodeIndex, false);
                    if (nodeName.equals (name)) {
                        found = true;
                        break;
                    }
                }
                nodeIndex = fDeferredDocumentImpl.getRealPrevSibling (nodeIndex, false);
            }
            if (!found) {
                int entityIndex = fDeferredDocumentImpl.createDeferredEntity (
                name, publicId, literalSystemId, notation, identifier.getBaseSystemId ());
                fDeferredDocumentImpl.appendChild (fDocumentTypeIndex, entityIndex);
            }
        }

    
public voidxmlDecl(java.lang.String version, java.lang.String encoding, java.lang.String standalone, org.apache.xerces.xni.Augmentations augs)
Notifies of the presence of an XMLDecl line in the document. If present, this method will be called immediately following the startDocument call.

param
version The XML version.
param
encoding The IANA encoding name of the document, or null if not specified.
param
standalone The standalone value, or null if not specified.
param
augs Additional information that may include infoset augmentations
throws
XNIException Thrown by handler to signal an error.

        if (!fDeferNodeExpansion) {
            // REVISIT: when DOM Level 3 is REC rely on Document.support
            //          instead of specific class
            if (fDocumentImpl != null) {
                if (version != null)
                    fDocumentImpl.setXmlVersion (version);
                fDocumentImpl.setXmlEncoding (encoding);
                fDocumentImpl.setXmlStandalone ("yes".equals (standalone));
            }
        }
        else {
            if (version != null)
                fDeferredDocumentImpl.setXmlVersion (version);
            fDeferredDocumentImpl.setXmlEncoding (encoding);
            fDeferredDocumentImpl.setXmlStandalone ("yes".equals (standalone));
        }