/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
*  This file contains code to build the DOM tree. It registers a document
*  handler with the scanner. In these handler methods, appropriate DOM nodes
*  are created and added to the DOM tree.
*
* $Id: DOMParser.cpp 568078 2007-08-21 11:43:25Z amassari $
*
*/



// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/internal/XMLScannerResolver.hpp>
#include <xercesc/sax/EntityResolver.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/sax/ErrorHandler.hpp>
#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/framework/XMLNotationDecl.hpp>
#include <xercesc/util/IOException.hpp>
#include <xercesc/framework/XMLValidator.hpp>
#include <xercesc/validators/common/GrammarResolver.hpp>
#include <xercesc/framework/XMLGrammarPool.hpp>
#include <xercesc/framework/XMLSchemaDescription.hpp>
#include <xercesc/util/Janitor.hpp>

#include "DOMParser.hpp"
#include "ElementImpl.hpp"
#include "AttrImpl.hpp"
#include "AttrNSImpl.hpp"
#include "TextImpl.hpp"
#include "DocumentImpl.hpp"
#include "DocumentTypeImpl.hpp"
#include "EntityImpl.hpp"
#include "NotationImpl.hpp"
#include "NamedNodeMapImpl.hpp"
#include "NodeIDMap.hpp"


#include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/DTD/DTDAttDefList.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/util/XMLEntityResolver.hpp>

XERCES_CPP_NAMESPACE_BEGIN


// ---------------------------------------------------------------------------
//  DOMParser: Constructors and Destructor
// ---------------------------------------------------------------------------
DOMParser::DOMParser( XMLValidator* const   valToAdopt
                    , MemoryManager* const  manager
                    , XMLGrammarPool* const gramPool) :

    fToCreateXMLDeclTypeNode(false)
    , fCreateEntityReferenceNodes(true)
    , fIncludeIgnorableWhitespace(true)
    , fParseInProgress(false)
    , fWithinElement(false)
    , fEntityResolver(0)
    , fXMLEntityResolver(0)
    , fErrorHandler(0)
    , fPSVIHandler(0)
    , fNodeStack(0)
    , fScanner(0)
    , fDocumentType(0)
    , fGrammarResolver(0)
    , fURIStringPool(0)
    , fValidator(valToAdopt)
    , fMemoryManager(manager)
    , fGrammarPool(gramPool)
{
    try
    {
        initialize();
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch(...)
    {
        cleanUp();
        throw;
    }
}


DOMParser::~DOMParser()
{
    cleanUp();
}

// ---------------------------------------------------------------------------
//  DOMParser: Initialize/CleanUp methods
// ---------------------------------------------------------------------------
void DOMParser::initialize()
{
    // Create grammar resolver and URI string pool to pass to the scanner
    fGrammarResolver = new (fMemoryManager) GrammarResolver(fGrammarPool, fMemoryManager);
    fURIStringPool = fGrammarResolver->getStringPool();

    //  Create a scanner and tell it what validator to use. Then set us
    //  as the document event handler so we can fill the DOM document.
    fScanner = XMLScannerResolver::getDefaultScanner(fValidator, fGrammarResolver, fMemoryManager);
    fScanner->setDocHandler(this);
    fScanner->setDocTypeHandler(this);
    fScanner->setURIStringPool(fURIStringPool);

    fNodeStack = new (fMemoryManager) ValueStackOf<DOM_Node>(64, fMemoryManager, true);
    this->reset();
}

void DOMParser::cleanUp()
{
    delete fNodeStack;
    delete fScanner;
    delete fGrammarResolver;
    // grammar pool must do this
    //delete fURIStringPool;

    if (fValidator)
        delete fValidator;
}

void DOMParser::reset()
{
    //
    //  Note: DOM Documents are reference counted. Doing this assignment
    //  will cause the old one to go away unless application code is also
    //  holding a reference to it.
    //
    fDocument = DOM_Document::createDocument(fMemoryManager);
    resetDocType();

    fCurrentParent   = 0;
    fCurrentNode     = 0;
    fParseInProgress = false;
    fWithinElement   = false;
    fNodeStack->removeAllElements();
};



// ---------------------------------------------------------------------------
//  DOMParser: Getter methods
// ---------------------------------------------------------------------------
const XMLValidator& DOMParser::getValidator() const
{
    return *fScanner->getValidator();
}

bool DOMParser::getDoNamespaces() const
{
    return fScanner->getDoNamespaces();
}

bool DOMParser::getExitOnFirstFatalError() const
{
    return fScanner->getExitOnFirstFatal();
}

bool DOMParser::getValidationConstraintFatal() const
{
    return fScanner->getValidationConstraintFatal();
}

DOMParser::ValSchemes DOMParser::getValidationScheme() const
{
    const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();

    if (scheme == XMLScanner::Val_Always)
        return Val_Always;
    else if (scheme == XMLScanner::Val_Never)
        return Val_Never;

    return Val_Auto;
}

bool DOMParser::getDoSchema() const
{
    return fScanner->getDoSchema();
}

bool DOMParser::getValidationSchemaFullChecking() const
{
    return fScanner->getValidationSchemaFullChecking();
}

bool DOMParser::getIdentityConstraintChecking() const
{
    return fScanner->getIdentityConstraintChecking();
}

int DOMParser::getErrorCount() const
{
    return fScanner->getErrorCount();
}

XMLCh* DOMParser::getExternalSchemaLocation() const
{
    return fScanner->getExternalSchemaLocation();
}

XMLCh* DOMParser::getExternalNoNamespaceSchemaLocation() const
{
    return fScanner->getExternalNoNamespaceSchemaLocation();
}

bool DOMParser::isCachingGrammarFromParse() const
{
    return fScanner->isCachingGrammarFromParse();
}

bool DOMParser::isUsingCachedGrammarInParse() const
{
    return fScanner->isUsingCachedGrammarInParse();
}

Grammar* DOMParser::getGrammar(const XMLCh* const nameSpaceKey)
{
    return fGrammarResolver->getGrammar(nameSpaceKey);
}

Grammar* DOMParser::getRootGrammar()
{
    return fScanner->getRootGrammar();
}

const XMLCh* DOMParser::getURIText(unsigned int uriId) const
{
    return fScanner->getURIText(uriId);
}

bool DOMParser::getCalculateSrcOfs() const
{
    return fScanner->getCalculateSrcOfs();
}

bool DOMParser::getStandardUriConformant() const
{
    return fScanner->getStandardUriConformant();
}

unsigned int DOMParser::getSrcOffset() const
{
    return fScanner->getSrcOffset();
}

// ---------------------------------------------------------------------------
//  DOMParser: Setter methods
// ---------------------------------------------------------------------------
void DOMParser::setDoNamespaces(const bool newState)
{
    fScanner->setDoNamespaces(newState);
}

void DOMParser::setErrorHandler(ErrorHandler* const handler)
{
    fErrorHandler = handler;
    if (fErrorHandler) {
        fScanner->setErrorReporter(this);
        fScanner->setErrorHandler(fErrorHandler);
    }
    else {
        fScanner->setErrorReporter(0);
        fScanner->setErrorHandler(0);
    }
}

void DOMParser::setPSVIHandler(PSVIHandler* const handler)
{
    fPSVIHandler = handler;
    if (fPSVIHandler) {
        fScanner->setPSVIHandler(fPSVIHandler);        
    }
    else {
        fScanner->setPSVIHandler(0);       
    }
}

void DOMParser::setEntityResolver(EntityResolver* const handler)
{
    fEntityResolver = handler;
    if (fEntityResolver) {
        fScanner->setEntityHandler(this);
        fXMLEntityResolver = 0;
    }
    else {
        fScanner->setEntityHandler(0);
    }
}

void DOMParser::setXMLEntityResolver(XMLEntityResolver* const handler)
{
    fXMLEntityResolver = handler;
    if (fXMLEntityResolver) {
        fEntityResolver = 0;
        fScanner->setEntityHandler(this);
    }
    else {
        fScanner->setEntityHandler(0);
    }
}

void DOMParser::setExitOnFirstFatalError(const bool newState)
{
    fScanner->setExitOnFirstFatal(newState);
}

void DOMParser::setValidationConstraintFatal(const bool newState)
{
    fScanner->setValidationConstraintFatal(newState);
}

void DOMParser::setValidationScheme(const ValSchemes newScheme)
{
    if (newScheme == Val_Never)
        fScanner->setValidationScheme(XMLScanner::Val_Never);
    else if (newScheme == Val_Always)
        fScanner->setValidationScheme(XMLScanner::Val_Always);
    else
        fScanner->setValidationScheme(XMLScanner::Val_Auto);
}

void DOMParser::setDoSchema(const bool newState)
{
    fScanner->setDoSchema(newState);
}

void DOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
{
    fScanner->setValidationSchemaFullChecking(schemaFullChecking);
}

void DOMParser::setIdentityConstraintChecking(const bool identityConstraintChecking)
{
    fScanner->setIdentityConstraintChecking(identityConstraintChecking);
}

void DOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
{
    fScanner->setExternalSchemaLocation(schemaLocation);
}
void DOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
{
    fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
}

void DOMParser::setExternalSchemaLocation(const char* const schemaLocation)
{
    fScanner->setExternalSchemaLocation(schemaLocation);
}
void DOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
{
    fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
}

void DOMParser::cacheGrammarFromParse(const bool newState)
{
    fScanner->cacheGrammarFromParse(newState);

    if (newState)
        fScanner->useCachedGrammarInParse(newState);
}

void DOMParser::useCachedGrammarInParse(const bool newState)
{
    if (newState || !fScanner->isCachingGrammarFromParse())
        fScanner->useCachedGrammarInParse(newState);
}

void DOMParser::setCalculateSrcOfs(const bool newState)
{
    fScanner->setCalculateSrcOfs(newState);
}

void DOMParser::setStandardUriConformant(const bool newState)
{
    fScanner->setStandardUriConformant(newState);
}

void DOMParser::useScanner(const XMLCh* const scannerName)
{
    XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
    (
        scannerName
        , fValidator
        , fGrammarResolver
        , fMemoryManager
    );

    if (tempScanner) {

        tempScanner->setParseSettings(fScanner);
        tempScanner->setURIStringPool(fURIStringPool);
        delete fScanner;
        fScanner = tempScanner;
    }
}

// ---------------------------------------------------------------------------
//  DOMParser: Parsing methods
// ---------------------------------------------------------------------------
void DOMParser::parse(const InputSource& source)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    try
    {
        fParseInProgress = true;
        fScanner->scanDocument(source);
        fParseInProgress = false;
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch(...)
    {
        fParseInProgress = false;
        throw;
    }
}

void DOMParser::parse(const XMLCh* const systemId)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    try
    {
        fParseInProgress = true;
        fScanner->scanDocument(systemId);
        fParseInProgress = false;
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch(...)
    {
        fParseInProgress = false;
        throw;
    }
}

void DOMParser::parse(const char* const systemId)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    try
    {
        fParseInProgress = true;
        fScanner->scanDocument(systemId);
        fParseInProgress = false;
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch(...)
    {
        fParseInProgress = false;
        throw;
    }
}



// ---------------------------------------------------------------------------
//  DOMParser: Progressive parse methods
// ---------------------------------------------------------------------------
bool DOMParser::parseFirst( const   XMLCh* const    systemId
                           ,       XMLPScanToken&  toFill)
{
    //
    //  Avoid multiple entrance. We cannot enter here while a regular parse
    //  is in progress.
    //
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    return fScanner->scanFirst(systemId, toFill);
}

bool DOMParser::parseFirst( const   char* const         systemId
                           ,       XMLPScanToken&      toFill)
{
    //
    //  Avoid multiple entrance. We cannot enter here while a regular parse
    //  is in progress.
    //
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    return fScanner->scanFirst(systemId, toFill);
}

bool DOMParser::parseFirst( const   InputSource&    source
                           ,       XMLPScanToken&  toFill)
{
    //
    //  Avoid multiple entrance. We cannot enter here while a regular parse
    //  is in progress.
    //
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    return fScanner->scanFirst(source, toFill);
}

bool DOMParser::parseNext(XMLPScanToken& token)
{
    return fScanner->scanNext(token);
}

void DOMParser::parseReset(XMLPScanToken& token)
{
    // Reset the scanner, and then reset the parser
    fScanner->scanReset(token);
    reset();
}


// ---------------------------------------------------------------------------
//  DOMParser: Implementation of the XMLErrorReporter interface
// ---------------------------------------------------------------------------
void DOMParser::error(  const   unsigned int              /*code*/
                      , const XMLCh* const                /*msgDomain*/
                      , const XMLErrorReporter::ErrTypes  errType
                      , const XMLCh* const                errorText
                      , const XMLCh* const                systemId
                      , const XMLCh* const                publicId
                      , const XMLSSize_t                  lineNum
                      , const XMLSSize_t                  colNum)
{
    SAXParseException toThrow = SAXParseException
        (
        errorText
        , publicId
        , systemId
        , lineNum
        , colNum
        , fMemoryManager
        );

    //
    //  If there is an error handler registered, call it, otherwise ignore
    //  all but the fatal errors.
    //
    if (!fErrorHandler)
    {
        if (errType == XMLErrorReporter::ErrType_Fatal)
            throw toThrow;
        return;
    }

    if (errType == XMLErrorReporter::ErrType_Warning)
        fErrorHandler->warning(toThrow);
    else if (errType >= XMLErrorReporter::ErrType_Fatal)
        fErrorHandler->fatalError(toThrow);
    else
        fErrorHandler->error(toThrow);
}

void DOMParser::resetErrors()
{
}


// ---------------------------------------------------------------------------
//  DOMParser: Implementation of XMLEntityHandler interface
// ---------------------------------------------------------------------------
InputSource*
DOMParser::resolveEntity(const XMLCh* const publicId,
                         const XMLCh* const systemId,
                         const XMLCh* const /*baseURI*/)
{
    //
    //  Just map it to the SAX entity resolver. If there is not one installed,
    //  return a null pointer to cause the default resolution.
    //
    if (fEntityResolver)
        return fEntityResolver->resolveEntity(publicId, systemId);
    return 0;
}

InputSource* DOMParser::resolveEntity(XMLResourceIdentifier* resourceIdentifier) 
{
    //
    //  Just map it to the SAX entity resolver. If there is not one installed,
    //  return a null pointer to cause the default resolution.
    //
    if (fEntityResolver)
        return fEntityResolver->resolveEntity(resourceIdentifier->getPublicId(), 
                                                resourceIdentifier->getSystemId());
    if (fXMLEntityResolver)
        return fXMLEntityResolver->resolveEntity(resourceIdentifier);
    return 0;
}

// ---------------------------------------------------------------------------
//  DOMParser: Implementation of XMLDocumentHandler interface
// ---------------------------------------------------------------------------
void DOMParser::docCharacters(  const   XMLCh* const    chars
                              , const unsigned int    length
                              , const bool            cdataSection)
{
    // Ignore chars outside of content
    if (!fWithinElement)
        return;

    if (cdataSection == true)
    {
        DOM_CDATASection node = fDocument.createCDATASection
            (
            DOMString(chars, length)
            );
        fCurrentParent.appendChild(node);
        fCurrentNode = node;
    }
    else
    {
        if (fCurrentNode.getNodeType() == DOM_Node::TEXT_NODE)
        {
            DOM_Text node = (DOM_Text&)fCurrentNode;
            node.appendData(DOMString(chars, length));
        }
        else
        {
            DOM_Text node = fDocument.createTextNode(DOMString(chars, length));
            fCurrentParent.appendChild(node);

            fCurrentNode = node;

        }
    }
}


void DOMParser::docComment(const XMLCh* const comment)
{
    DOM_Comment dcom = fDocument.createComment(comment);
    fCurrentParent.appendChild(dcom);
    fCurrentNode = dcom;
}


void DOMParser::docPI(  const   XMLCh* const    target
                      , const XMLCh* const    data)
{
    DOM_ProcessingInstruction pi = fDocument.createProcessingInstruction
        (
        target
        , data
        );
    fCurrentParent.appendChild(pi);
    fCurrentNode = pi;
}


void DOMParser::endEntityReference(const XMLEntityDecl& entDecl)
{
    if (fCreateEntityReferenceNodes == true)
    {
        if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) {
		    // stick the parsed content of this entity reference into the entity definition node
		    EntityImpl* entity = (EntityImpl*)fDocumentType->entities->getNamedItem(entDecl.getName());
		    entity->setEntityRef((EntityReferenceImpl*)fCurrentParent.fImpl);

            ((DOM_EntityReference&)fCurrentParent).fImpl->setReadOnly(true, true);
        }
        fCurrentParent = fNodeStack->pop();
        fCurrentNode   = fCurrentParent;
    }
}


void DOMParser::endElement( const   XMLElementDecl&    /*elemDecl*/
                           , const unsigned int        /*urlId*/
                           , const bool                /*isRoot*/
                           , const XMLCh* const        /*elemPrefix*/)
{
    fCurrentNode   = fCurrentParent;
    fCurrentParent = fNodeStack->pop();

    // If we've hit the end of content, clear the flag
    if (fNodeStack->empty())
        fWithinElement = false;
}


void DOMParser::ignorableWhitespace(const   XMLCh* const    chars
                                    , const unsigned int    length
                                    , const bool            /*cdataSection*/)
{
    // Ignore chars before the root element
    if (!fWithinElement || !fIncludeIgnorableWhitespace)
        return;

    if (fCurrentNode.getNodeType() == DOM_Node::TEXT_NODE)
    {
        DOM_Text node = (DOM_Text&)fCurrentNode;
        node.appendData(DOMString(chars, length));
    }
    else
    {
        DOM_Text node = fDocument.createTextNode(DOMString(chars, length));
        TextImpl *text = (TextImpl *) node.fImpl;
        text -> setIgnorableWhitespace(true);
        fCurrentParent.appendChild(node);

        fCurrentNode = node;
    }
}


void DOMParser::resetDocument()
{
    //
    //  The reset methods are called before a new parse event occurs.
    //  Reset this parsers state to clear out anything that may be left
    //  from a previous use, in particular the DOM document itself.
    //
    this->reset();
}


void DOMParser::startDocument()
{
    // Just set the document as the current parent and current node
    fCurrentParent = fDocument;
    fCurrentNode   = fDocument;
    // set DOM error checking off
    fDocument.setErrorChecking(false);
}


void DOMParser::endDocument()
{
    // set DOM error checking back on
    fDocument.setErrorChecking(true);
}


void DOMParser::startElement(const  XMLElementDecl&         elemDecl
                             , const unsigned int            urlId
                             , const XMLCh* const            elemPrefix
                             , const RefVectorOf<XMLAttr>&   attrList
                             , const unsigned int            attrCount
                             , const bool                    isEmpty
                             , const bool                    isRoot)
{
    DOM_Element     elem;
    DocumentImpl    *docImpl = (DocumentImpl *)fDocument.fImpl;

    if (fScanner -> getDoNamespaces()) {    //DOM Level 2, doNamespaces on
        XMLBuffer buf(1023, fMemoryManager);
        DOMString namespaceURI = 0;
        DOMString elemQName = 0;
        if (urlId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
            fScanner->getURIText(urlId, buf);   //get namespaceURI
            namespaceURI = DOMString(buf.getRawBuffer());

            if (elemPrefix && *elemPrefix) {
                elemQName.appendData(elemPrefix);
                elemQName.appendData(chColon);
            }
        }
        elemQName.appendData(elemDecl.getBaseName());

        elem = fDocument.createElementNS(namespaceURI, elemQName);
        ElementImpl *elemImpl = (ElementImpl *) elem.fImpl;
        for (unsigned int index = 0; index < attrCount; ++index) {
            static const XMLCh XMLNS[] = {
            chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull
            };
            const XMLAttr* oneAttrib = attrList.elementAt(index);
            unsigned int attrURIId = oneAttrib -> getURIId();
            namespaceURI = 0;
            if (!XMLString::compareString(oneAttrib -> getName(), XMLNS))    //for xmlns=...
                attrURIId = fScanner->getXMLNSNamespaceId();
            if (attrURIId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
                fScanner->getURIText(attrURIId, buf);   //get namespaceURI
                namespaceURI = DOMString(buf.getRawBuffer());
            }
            AttrImpl *attr = elemImpl->setAttributeNS(namespaceURI, oneAttrib -> getQName(),
            oneAttrib -> getValue());

            // Attributes of type ID.  If this is one, add it to the hashtable of IDs
            //   that is constructed for use by GetElementByID().
            //
            if (oneAttrib->getType()==XMLAttDef::ID)
            {
                if (docImpl->fNodeIDMap == 0)
                    docImpl->fNodeIDMap = new (fMemoryManager) NodeIDMap(500, fMemoryManager);
                docImpl->fNodeIDMap->add(attr);
                attr->isIdAttr(true);
            }

            attr->setSpecified(oneAttrib->getSpecified());
        }
    }
    else {    //DOM Level 1
        elem = fDocument.createElement(elemDecl.getFullName());
        ElementImpl *elemImpl = (ElementImpl *) elem.fImpl;
        for (unsigned int index = 0; index < attrCount; ++index) {
            const XMLAttr* oneAttrib = attrList.elementAt(index);
            AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue());
            attr->setSpecified(oneAttrib->getSpecified());

            // Attributes of type ID.  If this is one, add it to the hashtable of IDs
            //   that is constructed for use by GetElementByID().
            //
            if (oneAttrib->getType()==XMLAttDef::ID)
            {
                if (docImpl->fNodeIDMap == 0)
                    docImpl->fNodeIDMap = new (fMemoryManager) NodeIDMap(500, fMemoryManager);
                docImpl->fNodeIDMap->add(attr);
                attr->isIdAttr(true);
            }
        }
    }

    fCurrentParent.appendChild(elem);

    fNodeStack->push(fCurrentParent);
    fCurrentParent = elem;
    fCurrentNode = elem;
    fWithinElement = true;

    // If an empty element, do end right now (no endElement() will be called)
    if (isEmpty)
        endElement(elemDecl, urlId, isRoot, elemPrefix);
}


void DOMParser::startEntityReference(const XMLEntityDecl& entDecl)
{
    if (fCreateEntityReferenceNodes == true)
    {
		DOMString entName(entDecl.getName());
        DOM_EntityReference er = fDocument.createEntityReference(entName);

        //set the readOnly flag to false before appending node, will be reset in endEntityReference
        er.fImpl->setReadOnly(false, true);

        fCurrentParent.appendChild(er);
        fNodeStack->push(fCurrentParent);
        fCurrentParent = er;
        fCurrentNode = er;

    }
}


void DOMParser::XMLDecl(const   XMLCh* const version
                        , const XMLCh* const encoding
                        , const XMLCh* const standalone
                        , const XMLCh* const /*actualEncStr*/)
{
    //This is a non-standard extension to creating XMLDecl type nodes and attching to DOM Tree
    // currently this flag it set to false unless user explicitly asks for it
    // Needs to be revisited after W3C specs are laid out on this issue.

    if (fToCreateXMLDeclTypeNode) {

        DOMString ver(version);
        DOMString enc(encoding);
        DOMString isStd(standalone);
        DOM_XMLDecl xmlDecl = fDocument.createXMLDecl(ver, enc, isStd);

        fCurrentParent.appendChild(xmlDecl);
    }
}



// ---------------------------------------------------------------------------
//  DOMParser: Deprecated methods
// ---------------------------------------------------------------------------
bool DOMParser::getDoValidation() const
{
    //
    //  We don't want to tie the public parser classes to the enum used
    //  by the scanner, so we use a separate one and map.
    //
    //  DON'T mix the new and old methods!!
    //
    const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
    if (scheme == XMLScanner::Val_Always)
        return true;
    return false;
}

void DOMParser::setDoValidation(const bool newState)
{
    fScanner->setDoValidation
    (
        newState ? XMLScanner::Val_Always : XMLScanner::Val_Never
    );
}

//doctypehandler interfaces
void DOMParser::attDef
(
    const   DTDElementDecl&     elemDecl
    , const DTDAttDef&          attDef
    , const bool                /*ignoring*/
	)
{	
    if (fDocumentType->isIntSubsetReading())
    {
        DOMString attString;
        if (elemDecl.hasAttDefs())
        {
            attString.appendData(chOpenAngle);
            attString.appendData(chBang);
            attString.appendData(XMLUni::fgAttListString);
            attString.appendData(chSpace);
            attString.appendData(elemDecl.getFullName());

            attString.appendData(chSpace);
            attString.appendData(attDef.getFullName());

            // Get the type and display it
            const XMLAttDef::AttTypes type = attDef.getType();
            switch(type)
            {
            case XMLAttDef::CData :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgCDATAString);
                break;
            case XMLAttDef::ID :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgIDString);
                break;
            case XMLAttDef::IDRef :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgIDRefString);
                break;
            case XMLAttDef::IDRefs :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgIDRefsString);
                break;
            case XMLAttDef::Entity :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgEntityString);
                break;
            case XMLAttDef::Entities :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgEntitiesString);
                break;
            case XMLAttDef::NmToken :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgNmTokenString);
                break;
            case XMLAttDef::NmTokens :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgNmTokensString);
                break;

            case XMLAttDef::Notation :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgNotationString);
                break;

            case XMLAttDef::Enumeration :
                {
                    attString.appendData(chSpace);
                    //  attString.appendData(XMLUni::fgEnumerationString);
                    const XMLCh* enumString = attDef.getEnumeration();
                    int length = XMLString::stringLen(enumString);
                    if (length > 0) {

                        DOMString anotherEnumString;

                        anotherEnumString.appendData(chOpenParen );
                        for(int i=0; i<length; i++) {
                            if (enumString[i] == chSpace)
                                anotherEnumString.appendData(chPipe);
                            else
                                anotherEnumString.appendData(enumString[i]);
                        }
                        anotherEnumString.appendData(chCloseParen);
                        attString.appendData(anotherEnumString);
                    }
                }
                break;
            default:
                // remaining types don't belong to a DTD
                break;
            }
            //get te default types of the attlist
            const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
            switch(def)
            {
            case XMLAttDef::Required :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgRequiredString);
                break;
            case XMLAttDef::Implied :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgImpliedString);
                break;
            case XMLAttDef::Fixed :
                attString.appendData(chSpace);
                attString.appendData(XMLUni::fgFixedString);
                break;
            default:
                // remaining types don't belong to a DTD
                break;
            }

            const XMLCh* defaultValue = attDef.getValue();
            if (defaultValue != 0) {
                attString.appendData(chSpace);
                attString.appendData(chDoubleQuote);
                attString.appendData(defaultValue);
                attString.appendData(chDoubleQuote);
            }

            attString.appendData(chCloseAngle);
            fDocumentType->internalSubset.appendData(attString);
        }
    }
}

void DOMParser::doctypeComment
(
    const   XMLCh* const    comment
)
{
    if (fDocumentType->isIntSubsetReading())
    {
        if (comment != 0)
        {
            DOMString comString;
            comString.appendData(XMLUni::fgCommentString);
            comString.appendData(chSpace);
            comString.appendData(comment);
            comString.appendData(chSpace);
            comString.appendData(chDash);
            comString.appendData(chDash);
            comString.appendData(chCloseAngle);
            fDocumentType->internalSubset.appendData(comString);
        }
    }
}

void DOMParser::doctypeDecl
(
    const   DTDElementDecl& elemDecl
    , const XMLCh* const    publicId
    , const XMLCh* const    systemId
    , const bool            /*hasIntSubset*/
    , const bool            /*hasExtSubset*/
)
{
	DOM_DocumentType dt;
	dt = fDocument.getImplementation().createDocumentType(elemDecl.getFullName(), publicId, systemId);
    fDocumentType = (DocumentTypeImpl*)dt.fImpl;
	((DocumentImpl*)fDocument.fImpl)->setDocumentType(fDocumentType);

}

void DOMParser::doctypePI
(
    const   XMLCh* const    target
    , const XMLCh* const    data
)
{
    if (fDocumentType->isIntSubsetReading())
	{
		//add these chars to internalSubset variable
        DOMString pi;
        pi.appendData(chOpenAngle);
        pi.appendData(chQuestion);
        pi.appendData(target);
        pi.appendData(chSpace);
        pi.appendData(data);
        pi.appendData(chQuestion);
        pi.appendData(chCloseAngle);

		fDocumentType->internalSubset.appendData(pi);
	}
	
}


void DOMParser::doctypeWhitespace
(
    const   XMLCh* const    chars
    , const unsigned int    /*length*/
)
{
    if (fDocumentType->isIntSubsetReading())
		fDocumentType->internalSubset.appendData(chars);
}

void DOMParser::elementDecl
(
    const   DTDElementDecl& decl
    , const bool            /*isIgnored*/
)
{
    if (fDocumentType->isIntSubsetReading())
	{
        DOMString elemDecl;

        elemDecl.appendData(chOpenAngle);
        elemDecl.appendData(chBang);
        elemDecl.appendData(XMLUni::fgElemString);
        elemDecl.appendData(chSpace);
        elemDecl.appendData(decl.getFullName());

        //get the ContentSpec information
        const XMLCh* contentModel = decl.getFormattedContentModel();
        if (contentModel != 0) {
            elemDecl.appendData(chSpace);
            elemDecl.appendData(contentModel);
        }

        elemDecl.appendData(chCloseAngle);
		fDocumentType->internalSubset.appendData(elemDecl);
	}
}

void DOMParser::endAttList
(
    const   DTDElementDecl& elemDecl
)
{
	// this section sets up default attributes.
	// default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
	// default attribute data attached to the document is used to conform to the
	// DOM spec regarding creating element nodes & removing attributes with default values
	// see DocumentTypeImpl
	if (elemDecl.hasAttDefs())
	{		
		XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
		XMLAttDef* attr = 0;
		AttrImpl* insertAttr = 0;
		DOM_Element dom_elem = fDocument.createElement(elemDecl.getFullName());
		ElementImpl* elem = (ElementImpl*)(dom_elem.fImpl);

        for(unsigned int i=0; i<defAttrs->getAttDefCount(); i++)
        {
            attr = &defAttrs->getAttDef(i);
            if (attr->getValue() != null)
            {
                if (fScanner->getDoNamespaces())
                {
                    // 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.
                    DOMString qualifiedName = attr->getFullName();
                    int index = DocumentImpl::indexofQualifiedName(qualifiedName);

                    XMLBuffer buf(1023, fMemoryManager);
                    static const XMLCh XMLNS[] = {
                        chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};

                    if (index > 0) {
                        // there is prefix
                        // map to XML URI for all cases except when prefix == "xmlns"
                        DOMString prefix = qualifiedName.substringData(0, index);

                        if (prefix.equals(XMLNS))
                            buf.append(XMLUni::fgXMLNSURIName);
                        else
                            buf.append(XMLUni::fgXMLURIName);
                    }
                    else {
                        //   No prefix
                        if (qualifiedName.equals(XMLNS))
                            buf.append(XMLUni::fgXMLNSURIName);
                    }

                    insertAttr = new (fMemoryManager) AttrNSImpl((DocumentImpl*)fDocument.fImpl,
                       DOMString(buf.getRawBuffer()),     // NameSpaceURI
                       qualifiedName);   // qualified name

                }
                else
                {
                    // Namespaces is turned off...
                    insertAttr = new (fMemoryManager) AttrImpl((DocumentImpl*)fDocument.fImpl, attr->getFullName());
                }
                insertAttr->setValue(attr->getValue());
                // memory leak here
                AttrImpl * previousAttr = elem->setAttributeNode(insertAttr);
				if ( previousAttr != 0 && previousAttr->nodeRefCount ==0)
					NodeImpl::deleteIf(previousAttr);

                insertAttr->setSpecified(false);
            }
        }
        ElementImpl *previousElem = (ElementImpl *)
                fDocumentType->getElements()->setNamedItem( elem );

        //
        //  If this new element is replacing an element node that was already
        //    in the element named node map, we need to delete the original
        //    element node, assuming no-one else was referencing it.
        //
        if (previousElem != 0 && previousElem->nodeRefCount == 0)
            NodeImpl::deleteIf(previousElem);
    }
}

void DOMParser::endIntSubset()
{
	fDocumentType->intSubsetReading = false;
}

void DOMParser::endExtSubset()
{
}

void DOMParser::entityDecl
(
    const   DTDEntityDecl&  entityDecl
    , const bool            /*isPEDecl*/
    , const bool            /*isIgnored*/
)
{
	EntityImpl* entity = ((DocumentImpl*)fDocument.fImpl)->createEntity(entityDecl.getName());

	entity->setPublicId(entityDecl.getPublicId());
	entity->setSystemId(entityDecl.getSystemId());
	entity->setNotationName(entityDecl.getNotationName());

    EntityImpl *previousDef = (EntityImpl *)
	    fDocumentType->entities->setNamedItem( entity );

    //
    //  If this new entity node is replacing an entity node that was already
    //    in the entities named node map (happens if documents redefine the
    //    predefined entited such as lt), we need to delete the original
    //    entitiy node, assuming no-one else was referencing it.
    //
    if (previousDef != 0 && previousDef->nodeRefCount == 0)
    	        NodeImpl::deleteIf(previousDef);


	if (fDocumentType->isIntSubsetReading())
	{
		//add thes chars to internalSubset variable
		DOMString entityName;
		entityName.appendData(chOpenAngle);
        entityName.appendData(chBang);
		entityName.appendData(XMLUni::fgEntityString);
        entityName.appendData(chSpace);

        entityName.appendData(entityDecl.getName());
        DOMString id = entity->getPublicId();
        if (id != 0) {
            entityName.appendData(chSpace);
            entityName.appendData(XMLUni::fgPubIDString);
            entityName.appendData(chSpace);
            entityName.appendData(chDoubleQuote);
            entityName.appendData(id);
            entityName.appendData(chDoubleQuote);
        }
        id = entity->getSystemId();
        if (id != 0) {
            entityName.appendData(chSpace);
            entityName.appendData(XMLUni::fgSysIDString);
            entityName.appendData(chSpace);
            entityName.appendData(chDoubleQuote);
            entityName.appendData(id);
            entityName.appendData(chDoubleQuote);

        }
        id = entity->getNotationName();
        if (id != 0) {
            entityName.appendData(chSpace);
            entityName.appendData(XMLUni::fgNDATAString);
            entityName.appendData(chSpace);
            entityName.appendData(chDoubleQuote);
            entityName.appendData(id);
            entityName.appendData(chDoubleQuote);
        }
        id = entityDecl.getValue();
        if (id !=0) {
            entityName.appendData(chSpace);
            entityName.appendData(chDoubleQuote);
            entityName.appendData(id);
            entityName.appendData(chDoubleQuote);
        }

        entityName.appendData(chCloseAngle);
        fDocumentType->internalSubset.appendData(entityName);
    }

}

void DOMParser::resetDocType()
{
	fDocumentType = null;
}

void DOMParser::notationDecl
(
    const   XMLNotationDecl&    notDecl
    , const bool                /*isIgnored*/
)
{
	NotationImpl* notation = ((DocumentImpl*)fDocument.fImpl)->createNotation(notDecl.getName());
	notation->setPublicId(notDecl.getPublicId());
	notation->setSystemId(notDecl.getSystemId());

    NotationImpl *previousNot = (NotationImpl *)
       fDocumentType->notations->setNamedItem( notation );

    //
    //  If this new notation is replacing a notation node that was already
    //    in the notation named node map, we need to delete the original
    //    notation node, assuming no-one else was referencing it.
    //
    if (previousNot != 0 && previousNot->nodeRefCount == 0)
        NodeImpl::deleteIf(previousNot);

}

void DOMParser::startAttList
(
    const   DTDElementDecl& /*elemDecl*/
)
{
}

void DOMParser::startIntSubset()
{
	fDocumentType->intSubsetReading = true;
}

void DOMParser::startExtSubset()
{
}

void DOMParser::TextDecl
(
    const   XMLCh* const    /*versionStr*/
    , const XMLCh* const    /*encodingStr*/
)
{
}


// ---------------------------------------------------------------------------
//  DOMParser: Grammar preparsing methods
// ---------------------------------------------------------------------------
Grammar* DOMParser::loadGrammar(const char* const systemId,
                                const short grammarType,
                                const bool toCache)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    Grammar* grammar = 0;
    try
    {
        fParseInProgress = true;
        grammar = fScanner->loadGrammar(systemId, grammarType, toCache);
        fParseInProgress = false;
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }    catch(...)
    {
        fParseInProgress = false;
        throw;
    }

    return grammar;
}

Grammar* DOMParser::loadGrammar(const XMLCh* const systemId,
                                const short grammarType,
                                const bool toCache)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    Grammar* grammar = 0;
    try
    {
        fParseInProgress = true;
        grammar = fScanner->loadGrammar(systemId, grammarType, toCache);
        fParseInProgress = false;
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch(...)
    {
        fParseInProgress = false;
        throw;
    }

    return grammar;
}

Grammar* DOMParser::loadGrammar(const InputSource& source,
                                const short grammarType,
                                const bool toCache)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

   Grammar* grammar = 0;
    try
    {
        fParseInProgress = true;
        grammar = fScanner->loadGrammar(source, grammarType, toCache);
        fParseInProgress = false;
    }
    catch(const OutOfMemoryException&)
    {
        throw;
    }
    catch(...)
    {
        fParseInProgress = false;
        throw;
    }

    return grammar;
}

void DOMParser::resetCachedGrammarPool()
{
    fGrammarResolver->resetCachedGrammar();
}

XERCES_CPP_NAMESPACE_END

