/*
 * 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.
 */
#if !defined(XercesPARSERLIAISON_HEADER_GUARD_1357924680)
#define XercesPARSERLIAISON_HEADER_GUARD_1357924680


// Base include file.  Must be first.
#include <xalanc/XercesParserLiaison/XercesParserLiaisonDefinitions.hpp>



// Standard Library header files.
#include <xalanc/Include/XalanMap.hpp>



// Xerces DOM header files
#include <xercesc/sax/ErrorHandler.hpp>



// Base class header file.
#include <xalanc/XMLSupport/XMLParserLiaison.hpp>



#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
#include <xalanc/XercesParserLiaison/Deprecated/XercesBridgeTypes.hpp>
#endif
#include <xalanc/XercesParserLiaison/XercesWrapperTypes.hpp>



#if XERCES_VERSION_MAJOR >= 2
XALAN_DECLARE_XERCES_CLASS(XercesDOMParser)
#else
XALAN_DECLARE_XERCES_CLASS(DOMParser)
#endif
XALAN_DECLARE_XERCES_CLASS(SAXParser)



XALAN_CPP_NAMESPACE_BEGIN



class XercesDOMSupport;
#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
class XercesDocumentBridge;
#endif
class XercesDocumentWrapper;


typedef xercesc::SAXParseException    SAXParseExceptionType;


class XALAN_XERCESPARSERLIAISON_EXPORT XercesParserLiaison :
    public XMLParserLiaison,
    public ErrorHandler
{
    
public:

    typedef xercesc::SAXParser            SAXParserType;

    /**
     * Construct a XercesParserLiaison instance.
     *
     * @param theSupport instance of DOMSupport object
     *
     * @deprecated This constructor is deprecated.  Use the next constructor instead.
     */
    XercesParserLiaison(
        XercesDOMSupport&   theSupport,
        MemoryManager&      theManager XALAN_DEFAULT_MEMMGR);

    /**
     * Construct a XercesParserLiaison instance.
     */
    XercesParserLiaison(MemoryManager&  theManager XALAN_DEFAULT_MEMMGR);

    virtual
    ~XercesParserLiaison();



    // These interfaces are inherited from XMLParserLiaison...
    MemoryManager&
    getMemoryManager()
    {
        return m_externalSchemaLocation.getMemoryManager();
    }

    virtual void
    reset();

    virtual ExecutionContext*
    getExecutionContext() const;

    virtual void
    setExecutionContext(ExecutionContext&   theContext);

    virtual XalanDocument*
    parseXMLStream(
            const InputSource&      reader,
            const XalanDOMString&   identifier = XalanDOMString(XalanMemMgrs::getDummyMemMgr()));

    virtual void
    parseXMLStream(
            const InputSource&      urlInputSource,
            DocumentHandler&        handler,
            const XalanDOMString&   identifier = XalanDOMString(XalanMemMgrs::getDummyMemMgr()));

    virtual void
    destroyDocument(XalanDocument*  theDocument);

    virtual int
    getIndent() const;

    virtual void
    setIndent(int   i);

    virtual bool
    getUseValidation() const;

    virtual void
    setUseValidation(bool   b);

    virtual const XalanDOMString&
    getParserDescription(XalanDOMString&    theResult) const;

    virtual EntityResolver*
    getEntityResolver() const;

    virtual void
    setEntityResolver(EntityResolver*   resolver);

    virtual XMLEntityResolver*
    getXMLEntityResolver() const;

    virtual void
    setXMLEntityResolver(XMLEntityResolver*     resolver);

    virtual ErrorHandler*
    getErrorHandler() const;

    virtual void
    setErrorHandler(ErrorHandler*   handler);

    // These interfaces are new to XercesParserLiaison...

    /**
      * Create an instance of the Xerces default document that
      * is suitable as a raw document.  The new document instance
      * is owned by this instance and will be destroyed when this
      * instance goes out of scope, or by an explicit call to
      * destroyDocument()
      *
      * @return a pointer to the new instance
      */
    virtual DOMDocument_Type*
    createDOMFactory();

    /**
      * Destroy an instance created by a call to createDOMFactory().
      *
      * @theDocument a pointer to the instance to be destroyed
      */
    virtual void
    destroyDocument(DOMDocument_Type*   theDocument);

    /** Get the 'include ignorable whitespace' flag.
      *
      * This method returns the state of the parser's include ignorable
      * whitespace flag.
      *
      * @return 'true' if the include ignorable whitespace flag is set on
      *         the parser, 'false' otherwise.
      *
      * @see #setIncludeIgnorableWhitespace
      */
    virtual bool
    getIncludeIgnorableWhitespace() const;

    /** Set the 'include ignorable whitespace' flag
      *
      * This method allows the user to specify whether a validating parser
      * should include ignorable whitespaces as text nodes.  It has no effect
      * on non-validating parsers which always include non-markup text.
      * <p>When set to true (also the default), ignorable whitespaces will be
      * added to the DOM tree as text nodes.  The method
      * <code>DOMText::isWhitespace</code> will return true for those text
      * nodes only.
      * <p>When set to false, all ignorable whitespace will be discarded and
      * no text node is added to the DOM tree.  Note: applications intended
      * to process the "xml:space" attribute should not set this flag to false.
      *
      * @param include The new state of the include ignorable whitespace
      *                flag.
      *
      * @see #getIncludeIgnorableWhitespace
      */
    virtual void
    setIncludeIgnorableWhitespace(bool  include);

    /**
      * This method returns the state of the parser's namespace
      * handling capability.
      *
      * @return true, if the parser is currently configured to
      *         understand namespaces, false otherwise.
      *
      * @see #setDoNamespaces
      */
    virtual bool
    getDoNamespaces() const;

    /**
      * This method allows users to enable or disable the parser's
      * namespace processing. When set to true, parser starts enforcing
      * all the constraints / rules specified by the NameSpace
      * specification.
      *
      * <p>The parser's default state is: false.</p>
      *
      * <p>This flag is ignored by the underlying scanner if the installed
      * validator indicates that namespace constraints should be
      * enforced.</p>
      *
      * @param newState The value specifying whether NameSpace rules should
      *                 be enforced or not.
      *
      * @see #getDoNamespaces
      */
    virtual void
    setDoNamespaces(bool    newState);

    /**
      * This method returns the state of the parser's
      * exit-on-First-Fatal-Error flag.
      *
      * @return true, if the parser is currently configured to
      *         exit on the first fatal error, false otherwise.
      *
      * @see #setExitOnFirstFatalError
      */
    virtual bool
    getExitOnFirstFatalError() const;

    /**
      * This method allows users to set the parser's behaviour when it
      * encounters the first fatal error. If set to true, the parser
      * will exit at the first fatal error. If false, then it will
      * report the error and continue processing.
      *
      * <p>The default value is 'true' and the parser exits on the
      * first fatal error.</p>
      *
      * @param newState The value specifying whether the parser should
      *                 continue or exit when it encounters the first
      *                 fatal error.
      *
      * @see #getExitOnFirstFatalError
      */
    virtual void
    setExitOnFirstFatalError(bool   newState);

    /**
      * This method returns the location for an external schema document
      * for parsing.
      *
      * @return A string representing the location of the external schema document
      */
    virtual const XalanDOMChar*
    getExternalSchemaLocation() const;

    /**
      * This method sets the location for an external schema document
      * for parsing.
      *
      * @param location A string representing the location of the external schema document
      */
    virtual void
    setExternalSchemaLocation(const XalanDOMChar*   location);

    /**
      * This method returns the location for an external schema document
      * for parsing.
      *
      * @return A string representing the location of the external schema document
      */
    virtual const XalanDOMChar*
    getExternalNoNamespaceSchemaLocation() const;

    /**
      * This method sets the location for an external schema document
      * for parsing.
      *
      * @param location A string representing the location of the external schema document
      */
    virtual void
    setExternalNoNamespaceSchemaLocation(const XalanDOMChar*    location);

#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
    /**
     * This API is deprecated.
     *
     * Create a XalanDocument proxy for an existing Xerces document.
     * The parser liaison owns the instance, and you must not delete
     * it.  The liaison will delete it when reset() is called, or the
     * liaison is destroyed.
     *
     * @deprecated The Xerces DOM bridge is deprecated.
     * @param theXercesDocument The Xerces document.
     * @return a pointer to a new XalanDocument-derived instance.
     */
    XalanDocument*
    createDocument(const DOM_Document_Type&     theXercesDocument)
    {
        return createDocument(theXercesDocument, m_threadSafe, m_buildBridge);
    }

    /**
     * This API is deprecated.
     *
     * Create a XalanDocument proxy for an existing Xerces document.
     * The parser liaison owns the instance, and you must not delete
     * it.  The liaison will delete it when reset() is called, or the
     * liaison is destroyed.
     *
     * @deprecated The Xerces DOM bridge is deprecated.
     * @param theXercesDocument The Xerces document.
     * @param threadSafe If true, read access to the tree will be thread-safe (implies buildBridge == true).
     * @param buildBridge If true, the entire bridge structure is built.
     * @return a pointer to a new XalanDocument-derived instance.
     */
    XalanDocument*
    createDocument(
            const DOM_Document_Type&    theXercesDocument,
            bool                        threadSafe,
            bool                        buildBridge);
#endif

    /**
     * Create a XalanDocument proxy for an existing Xerces document.
     * The parser liaison owns the instance, and you must not delete
     * it.  The liaison will delete it when reset() is called, or the
     * liaison is destroyed.
     *
     * @param theXercesDocument The Xerces document.
     * @return a pointer to a new XalanDocument-derived instance.
     */
    XalanDocument*
    createDocument(const DOMDocument_Type*  theXercesDocument)
    {
        return createDocument(theXercesDocument, m_threadSafe, m_buildWrapper, m_buildMaps);
    }

    /**
     * Create a XalanDocument proxy for an existing Xerces document.
     * The parser liaison owns the instance, and you must not delete
     * it.  The liaison will delete it when reset() is called, or the
     * liaison is destroyed.
     *
     * @param theXercesDocument The Xerces document.
     * @param threadSafe If true, read access to the tree will be thread-safe (implies buildWrapper == true).
     * @param buildWrapper If true, the entire wrapper structure is built.
     * @param buildMaps If true, the map of Xerces to Xalan nodes is always built.
     * @return a pointer to a new XalanDocument-derived instance.
     */
    XalanDocument*
    createDocument(
            const DOMDocument_Type*     theXercesDocument,
            bool                        threadSafe,
            bool                        buildWrapper,
            bool                        buildMaps = false);

#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
    /**
     * This API is deprecated.
     *
     * Map a pointer to a XalanDocument instance to its implementation
     * class pointer.  Normally, you should have no reason for doing
     * this.  The liaison will return a null pointer if it did not
     * create the instance passed.
     *
     * @deprecated The Xerces DOM bridge has been deprecated.
     * @param theDocument A pointer to a XalanDocument instance.
     * @return A pointer to the XercesDocumentBridge instance.
     */
    XercesDocumentBridge*
    mapDocument(const XalanDocument*    theDocument) const;
#endif

    /**
     * Map a pointer to a XalanDocument instance to its implementation
     * class pointer.  Normally, you should have no reason for doing
     * this.  The liaison will return a null pointer if it did not
     * create the instance passed.
     *
     * @param theDocument A pointer to a XalanDocument instance.
     * @return A pointer to the XercesDocumentWrapper instance.
     */
    XercesDocumentWrapper*
    mapDocumentToWrapper(const XalanDocument*   theDocument) const;

#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
    /** 
     * This API is deprecated.
     *
     * Map a pointer to a XalanDocument instance to its corresponding
     * class pointer.  Normally, you should have no reason for doing
     * this.  The liaison will return a null pointer if it did not
     * create the instance passed.
     *
     * @deprecated The Xerces DOM bridge has been deprecated.
     * @param theDocument A pointer to a XalanDocument instance.
     * @return A pointer to the XercesDocumentBridge instance.
     */
    DOM_Document_Type
    mapXercesDocument(const XalanDocument*  theDocument) const;
#endif

    /** 
     * Map a pointer to a XalanDocument instance to its corresponding
     * class pointer.  Normally, you should have no reason for doing
     * this.  The liaison will return a null pointer if it did not
     * create the instance passed.
     *
     * @param theDocument A pointer to a XalanDocument instance.
     * @return A pointer to the XercesDocumentBridge instance.
     */
    const DOMDocument_Type*
    mapToXercesDocument(const XalanDocument*    theDocument) const;

    // Implementations for SAX ErrorHandler

    virtual void
    warning(const SAXParseExceptionType&    exception);

    virtual void
    error(const SAXParseExceptionType&  exception);
   
    virtual void
    fatalError(const SAXParseExceptionType&     exception);

    virtual void
    resetErrors();

    struct DocumentEntry
    {
#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
        bool    m_isDeprecated;

        bool
        isDeprecated() const
        {
            return m_isDeprecated;
        }
#else
        bool
        isDeprecated() const
        {
            return false;
        }
#endif

        bool    m_isOwned;

        bool
        isOwned() const
        {
            return m_isOwned;
        }

#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
        union
        {
            XercesDocumentBridge*   m_bridge;
            XercesDocumentWrapper*  m_wrapper;
        };

        DocumentEntry&
        operator=(XercesDocumentBridge*     theBridge)
        {
            m_isDeprecated = true;

            m_bridge = theBridge;

            m_isOwned = true;

            return *this;
        }

        DocumentEntry&
        operator=(XercesDocumentWrapper*    theWrapper)
        {
            m_isDeprecated = false;

            m_wrapper = theWrapper;

            m_isOwned = true;

            return *this;
        }
#else
        XercesDocumentWrapper*  m_wrapper;

        DocumentEntry&
        operator=(XercesDocumentWrapper*    theWrapper)
        {
            m_wrapper = theWrapper;

            m_isOwned = true;

            return *this;
        }
#endif
    };

    typedef XalanMap<const XalanDocument*, DocumentEntry>   DocumentMapType;

    /**
     * This API is deprecated.
     * 
     * This functions returns the state of the liaison's build-bridge-nodes flag.
     *
     * @deprecated The Xerces DOM bridge is deprecated.
     * @return true, if the bridge nodes are automatically built, false otherwise.
     */
    bool
    getBuildBridgeNodes() const
    
    {
        return m_buildBridge;
    }

    /**
     * This API is deprecated.
     *
     * This functions sets the state of the liaison's build-bridge-nodes flag.
     * This flag must be set for the document to be thread safe.  It can also be
     * set to true to increase performance.  If this flag is set to false, then
     * the thread-safe flag will also be set to false.
     *
     * @deprecated The Xerces DOM bridge is deprecated.
     * @param newState The new state for the flag.
     *
     */
    void
    setBuildBridgeNodes(bool    newState)
    {
        m_buildBridge = newState;

        if (newState == false)
        {
            m_threadSafe = false;
        }
    }

    /**
     * This functions returns the state of the liaison's build-wrapper-nodes flag.
     *
     * @return true, if the wrapper nodes are automatically built, false otherwise.
     */
    bool
    getBuildWrapperNodes() const
    
    {
        return m_buildWrapper;
    }

    /**
     * This functions sets the state of the liaison's build-wrapper-nodes flag.
     * This flag must be set for the document to be thread safe.  It can also be
     * set to true to increase performance.  If this flag is set to false, then
     * the thread-safe flag will also be set to false.
     *
     * @param newState The new state for the flag.
     *
     */
    void
    setBuildWrapperNodes(bool   newState)
    {
        m_buildWrapper = newState;

        if (newState == false)
        {
            m_threadSafe = false;
        }
    }

    /**
     * This functions returns the state of the liaison's thread-safe flag.
     * If true, documents created will be safe when data is read.  By default,
     * documents are _not_ thread-safe.
     *
     * Note -- modifications are _never_ synchronized.
     *
     * @return true, if the new documents will be thread safe, false otherwise.
     */
    bool
    getThreadSafe() const
    
    {
        return m_threadSafe;
    }

    /**
     * This functions sets the state of the liaison's thread-safe flag.
     * This flag must be set for the document to be thread safe.  If this
     * flag is set to true, then the build-bridge-nodes flag will also be
     * set to true.
     *
     * @param newState The new state for the flag.
     *
     */
    void
    setThreadSafe(bool  newState)
    {
        m_threadSafe = newState;

        if (m_threadSafe == true)
        {
            m_buildWrapper = true;
            m_buildBridge = true;
        }
    }

    /**
     * This functions returns the state of the liaison's buildMaps flag.
     * If true, maps will be created to allow mapping of Xalan<->Xerces mapping
     * in both directions for XercesWrapper classes.
     *
     * @return true, if the new documents will be built with Maps
     */
    bool
    getBuildMaps() const
    
    {
        return m_buildMaps;
    }
 
    /**
     * This functions sets the state of the liaison's buildMaps flag.
     * When this flag is true, maps will be built providing Xerces<->Xalan
     * mapping in Wrapper classes.
     *
     * @note The maps created use a large amount of memory.  If only
     * Xalan->Xerces node mapping is required, do not set this to true.
     *
     * @param newState The new state for the flag.
     *
     */
    void
    setBuildMaps(bool   newState)
    {
        m_buildMaps = newState;
    }

    typedef xercesc::XercesDOMParser  DOMParserType;

protected:

    static void
    formatErrorMessage(
            const SAXParseExceptionType&    e,
            XalanDOMString&                 theMessage);

#if defined(XALAN_BUILD_DEPRECATED_DOM_BRIDGE)
    /**
     * Create a XalanDocument proxy for an existing Xerces document.
     *
     * This API is deprecated.
     *
     * @param theXercesDocument The Xerces document.
     * @param threadSafe If true, read access to the tree will be thread-safe (implies buildBridge == true).
     * @param buildBridge If true, the entire bridge structure is built.
     * @return a pointer to a new XercesDocumentBridge instance.
     */
    XercesDocumentBridge*
    doCreateDocument(
            const DOM_Document_Type&    theXercesDocument,
            bool                        threadSafe,
            bool                        buildBridge);
#endif

    /**
     * Create a XalanDocument proxy for an existing Xerces document.
     *
     * @param theXercesDocument The Xerces document.
     * @param threadSafe If true, read access to the tree will be thread-safe (implies buildBridge == true).
     * @param buildWrapper If true, the entire bridge structure is built.
     * @param buildMaps If true, the map of Xerces to Xalan nodes is always built.
     * @return a pointer to a new XercesDocumentWrapper instance.
     */
    XercesDocumentWrapper*
    doCreateDocument(
            const DOMDocument_Type*     theXercesDocument,
            bool                        threadSafe,
            bool                        buildWrapper,
            bool                        buildMaps,
            bool                        isOwned);

private:

    void
    ensureDOMParser();

    DOMParserType*
    createDOMParser();

    SAXParserType*
    createSAXParser();



    // Data members...
    int                 m_indent;

    bool                m_useValidation;

    bool                m_includeIgnorableWhitespace;

    bool                m_doNamespaces;

    bool                m_exitOnFirstFatalError;

    EntityResolver*     m_entityResolver;

    XMLEntityResolver*  m_xmlEntityResolver;

    ErrorHandler*       m_errorHandler;

    XalanDOMString      m_externalSchemaLocation;

    XalanDOMString      m_externalNoNamespaceSchemaLocation;

    DocumentMapType     m_documentMap;

    bool                m_buildWrapper;

    bool                m_buildBridge;

    bool                m_threadSafe;

    bool                m_buildMaps;

    ExecutionContext*   m_executionContext;

    DOMParserType*      m_domParser;
};



XALAN_CPP_NAMESPACE_END



#endif  // XercesPARSERLIAISON_HEADER_GUARD_1357924680
