/*
 * 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(XPATHEXECUTIONCONTEXTDEFAULT_HEADER_GUARD_1357924680)
#define XPATHEXECUTIONCONTEXTDEFAULT_HEADER_GUARD_1357924680



// Base include file.  Must be first.
#include <xalanc/XPath/XPathDefinitions.hpp>



#include <xalanc/Include/XalanObjectCache.hpp>
#include <xalanc/Include/XalanVector.hpp>



#include <xalanc/XalanDOM/XalanDOMString.hpp>



// Base class include file.
#include <xalanc/XPath/XPathExecutionContext.hpp>



#include <xalanc/PlatformSupport/XalanDOMStringCache.hpp>



#include <xalanc/XPath/MutableNodeRefList.hpp>
#include <xalanc/XPath/XalanQNameByValue.hpp>



namespace XALAN_CPP_NAMESPACE {



class DOMSupport;
class XPathEnvSupport;
class XalanQName;



/**
 * A basic implementation of the class XPathExecutionContext.
 */
class XALAN_XPATH_EXPORT XPathExecutionContextDefault : public XPathExecutionContext
{
public:

    typedef XalanVector<XalanNode*>             CurrentNodeStackType;
    typedef XalanVector<const NodeRefListBase*> ContextNodeListStackType;

    /**
     * Construct an XPathExecutionContextDefault object
     *
     * @param theXPathEnvSupport XPathEnvSupport class instance
     * @param theDOMSupport      DOMSupport class instance
     * @param theXobjectFactory  factory class instance for XObjects
     * @param theCurrentNode     current node in the source tree
     * @param theContextNodeList node list for current context
     * @param thePrefixResolver  pointer to prefix resolver to use
     */ 
    XPathExecutionContextDefault(
            XPathEnvSupport&        theXPathEnvSupport,
            DOMSupport&             theDOMSupport,
            XObjectFactory&         theXObjectFactory,
            XalanNode*              theCurrentNode = 0,
            const NodeRefListBase*  theContextNodeList = 0,
            const PrefixResolver*   thePrefixResolver = 0);

    /**
     * Construct an XPathExecutionContextDefault object
     *
     * @param theXPathEnvSupport XPathEnvSupport class instance
     * @param theXObjectFactory  factory class instance for XObjects
     * @param theCurrentNode     current node in the source tree
     * @param theContextNodeList node list for current context
     * @param thePrefixResolver  pointer to prefix resolver to use
     */
    explicit
    XPathExecutionContextDefault(
            MemoryManager&      theManager,
            XalanNode*              theCurrentNode = 0,
            const NodeRefListBase*  theContextNodeList = 0,
            const PrefixResolver*   thePrefixResolver = 0);

    static XPathExecutionContextDefault*
    create(
            MemoryManager&      theManager,
            XalanNode*              theCurrentNode = 0,
            const NodeRefListBase*  theContextNodeList = 0,
            const PrefixResolver*   thePrefixResolver = 0);

    virtual
    ~XPathExecutionContextDefault();


    /**
     * Get the XPathEnvSupport instance.
     *
     * @return a pointer to the instance.
     */
    XPathEnvSupport*
    getXPathEnvSupport() const
    {
        return m_xpathEnvSupport;
    }

    /**
     * Set the XPathEnvSupport instance.
     *
     * @param theSupport a reference to the instance to use.
     */
    void
    setXPathEnvSupport(XPathEnvSupport*     theSupport)
    {
        m_xpathEnvSupport = theSupport;
    }

    /**
     * Set the DOMSupport instance.
     *
     * @param theDOMSupport a reference to the instance to use.
     */
    void
    setDOMSupport(DOMSupport*   theDOMSupport)
    {
        m_domSupport = theDOMSupport;
    }

    /**
     * Set the XObjectFactory instance.
     *
     * @param theFactory a reference to the instance to use.
     */
    void
    setXObjectFactory(XObjectFactory*   theXObjectFactory)
    {
        m_xobjectFactory = theXObjectFactory;
    }

    /**
     * Get a reference to the scratch QNameByValue instance.
     *
     * @return A reference to a QNameByValue instance.
     */
    XalanQNameByValue&
    getScratchQName() const
    {
        return m_scratchQName;
    }

    virtual void doFormatNumber(
            double                              number,
            const XalanDOMString&               pattern,
            const XalanDecimalFormatSymbols*    theDFS,
            XalanDOMString&                     theResult,
            const XalanNode*                    context = 0,
            const Locator*                      locator = 0);

    // These interfaces are inherited from XPathExecutionContext...

    virtual void
    reset();

    virtual XalanNode*
    getCurrentNode() const;

    virtual void
    pushCurrentNode(XalanNode*      theCurrentNode);

    virtual void
    popCurrentNode();

    virtual bool
    isNodeAfter(
            const XalanNode&    node1,
            const XalanNode&    node2) const;

    virtual void
    pushContextNodeList(const NodeRefListBase&  theList);

    virtual void    
    popContextNodeList();

    virtual const NodeRefListBase&
    getContextNodeList() const;

    virtual size_type
    getContextNodeListLength() const;

    virtual size_type
    getContextNodeListPosition(const XalanNode&     contextNode) const;

    virtual bool
    elementAvailable(const XalanQName&  theQName) const;

    virtual bool
    elementAvailable(
            const XalanDOMString&   theName,
            const Locator*          locator) const;

    virtual bool
    functionAvailable(const XalanQName&     theQName) const;

    virtual bool
    functionAvailable(
            const XalanDOMString&   theName,
            const Locator*          locator) const;

    virtual const XObjectPtr
    extFunction(
            const XalanDOMString&           theNamespace,
            const XalanDOMString&           functionName,
            XalanNode*                      context,
            const XObjectArgVectorType&     argVec,
            const Locator*                  locator);

    virtual XalanDocument*
    parseXML(
            MemoryManager&      theManager,
            const XalanDOMString&   urlString,
            const XalanDOMString&   base,
            ErrorHandler*           theErrorHandler = 0) const;

    virtual MutableNodeRefList*
    borrowMutableNodeRefList();

    virtual bool
    returnMutableNodeRefList(MutableNodeRefList*    theList);

    virtual MutableNodeRefList*
    createMutableNodeRefList(MemoryManager& theManager) const;

    virtual XalanDOMString&
    getCachedString();

    virtual bool
    releaseCachedString(XalanDOMString&     theString);

    virtual void
    getNodeSetByKey(
            XalanNode*              context,
            const XalanQName&       qname,
            const XalanDOMString&   ref,
            const Locator*          locator,
            MutableNodeRefList&     nodelist);

    virtual void
    getNodeSetByKey(
            XalanNode*              context,
            const XalanDOMString&   name,
            const XalanDOMString&   ref,
            const Locator*          locator,
            MutableNodeRefList&     nodelist);

    virtual const XObjectPtr
    getVariable(
            const XalanQName&   name,
            const Locator*      locator = 0);

    virtual const PrefixResolver*
    getPrefixResolver() const;

    virtual void
    setPrefixResolver(const PrefixResolver*     thePrefixResolver);

    virtual const XalanDOMString*
    getNamespaceForPrefix(const XalanDOMString&     prefix) const;

    virtual const XalanDOMString&
    findURIFromDoc(const XalanDocument*     owner) const;

    virtual const XalanDOMString&
    getUnparsedEntityURI(
            const XalanDOMString&   theName,
            const XalanDocument&    theDocument) const;

    virtual XalanDocument*
    getSourceDocument(const XalanDOMString&     theURI) const;

    virtual void
    setSourceDocument(
            const XalanDOMString&   theURI,
            XalanDocument*          theDocument);

    virtual void formatNumber(
            double                              number,
            const XalanDOMString&               pattern,
            XalanDOMString&                     theResult,
            const XalanNode*                    context = 0,
            const Locator*                      locator = 0);

    virtual void formatNumber(
            double                              number,
            const XalanDOMString&               pattern,
            const XalanDOMString&               dfsName,
            XalanDOMString&                     theResult,
            const XalanNode*                    context = 0,
            const Locator*                      locator = 0);


    // These interfaces are inherited from ExecutionContext...

    virtual void
    problem(
            eSource                 source,
            eClassification         classification,
            const XalanDOMString&   msg,
            const Locator*          locator,
            const XalanNode*        sourceNode);

    virtual void
    problem(
            eSource                 source,
            eClassification         classification,
            const XalanDOMString&   msg,
            const XalanNode*        sourceNode);

    virtual void
    error(
            const XalanDOMString&   msg,
            const XalanNode*        sourceNode = 0,
            const Locator*          locator = 0) const;

    virtual void
    warn(
            const XalanDOMString&   msg,
            const XalanNode*        sourceNode = 0,
            const Locator*          locator = 0) const;

    virtual void
    message(
            const XalanDOMString&   msg,
            const XalanNode*        sourceNode = 0,
            const Locator*          locator = 0) const;

    virtual bool
    shouldStripSourceNode(const XalanText&  node);

protected:

    typedef XalanObjectCache<
                MutableNodeRefList,
                DefaultCacheCreateFunctorMemMgr<MutableNodeRefList>,
                DeleteFunctor<MutableNodeRefList>,
                ClearCacheResetFunctor<MutableNodeRefList> >    NodeListCacheType;

    enum { eNodeListCacheListSize = 50 };

    struct ContextNodeListPositionCache
    {
        ContextNodeListPositionCache() :
            m_node(0),
            m_index(0)
        {
        }

        void
        clear()
        {
            if (m_node != 0)
            {
                m_node = 0;
            }
        }

        const XalanNode*    m_node;

        size_type           m_index;
    };

    XPathEnvSupport*                        m_xpathEnvSupport;

    DOMSupport*                             m_domSupport;

    CurrentNodeStackType                    m_currentNodeStack;

    ContextNodeListStackType                m_contextNodeListStack;

    const PrefixResolver*                   m_prefixResolver;

    XalanDOMString                          m_currentPattern;

    NodeListCacheType                       m_nodeListCache;

    XalanDOMStringCache                     m_stringCache;

    mutable ContextNodeListPositionCache    m_cachedPosition;

    mutable XalanQNameByValue               m_scratchQName;

    static const NodeRefList                s_dummyList;
};



}



#endif  // XPATHEXECUTIONCONTEXTDEFAULT_HEADER_GUARD_1357924680
