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



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

#include <xalanc/Include/XalanMemoryManagement.hpp>

#include <cassert>
#include <functional>



namespace XALAN_CPP_NAMESPACE {



class XPath;



class XALAN_XPATH_EXPORT XPathFactory
{
public:

    explicit
    XPathFactory();

    virtual
    ~XPathFactory();

    /**
     * Return an XPath to the factory.
     * 
     * @param theXPath The XPath to be returned
     * @return true if the object belongs to the factory, false if not.
     */
    bool
    returnObject(const XPath*   theXPath)
    {
        return doReturnObject(theXPath);
    }

    /**
     * Reset the instance.  This invalidates all existing instances created
     * with this XPathFactory.
     */
    virtual void
    reset() = 0;

    /**
     * Create an XPath.  The XPath instance is owned by the factory, and should
     * not be deleted.  The factory will manage the lifetime.
     *
     */
    virtual XPath*
    create() = 0;

    /**
     *
     * A functor for use with stl algorithms.
     *
     */
    struct DeleteXPathFunctor
    {
    public:

        DeleteXPathFunctor(
            XPathFactory&       theFactoryInstance,
            bool                fInReset = false) :
            m_factoryInstance(theFactoryInstance),
            m_fInReset(fInReset)
        {
        }

        bool
        operator()(const XPath*    theXPath) const
        {
            if (m_fInReset == true)
            {
                return m_factoryInstance.doReturnObject(theXPath,
                                                        true);
            }
            else
            {
                return m_factoryInstance.returnObject(theXPath);
            }
        }

    private:

        XPathFactory&       m_factoryInstance;

        const bool          m_fInReset;
    };

    friend struct DeleteXPathFunctor;

protected:

    virtual bool
    doReturnObject(
            const XPath*    theXPath,
            bool            fInReset = false) = 0;
};



/**
 * Manages the lifetime of an XPath instance.
 */
class XPathGuard
{
public:

    /**
     * Construct an XPathGuard instance from a factory object and an XPath.
     * 
     * @param theFactory object that manages lifetime of XPaths
     * @param theXPath pointer to XPath managed
     */
    XPathGuard(
            XPathFactory&   theFactory,
            const XPath*    theXPath) :
        m_factory(&theFactory),
        m_object(theXPath)
    {
    }

    // Note that copy construction transfers ownership, just
    // as std::auto_ptr.
    XPathGuard(XPathGuard&  theRHS)
    {
        // Release the current object...
        release();

        // Copy the factory and object pointers...
        m_factory = theRHS.m_factory;
        m_object = theRHS.m_object;

        // The source object no longer points to
        // the object...
        theRHS.m_factory = 0;
        theRHS.m_object = 0;
    }

    ~XPathGuard()
    {
        reset();
    }

    /**
     * Retrieve the object pointer (must not be null)
     * 
     * @return pointer to XPath
     */
    const XPath*
    operator->() const
    {
        assert(m_object != 0);

        return m_object;
    }

    /**
     * Retrieve the object pointer (may be null)
     * 
     * @return pointer to XPath
     */
    const XPath*
    get() const
    {
        return m_object;
    }

    /**
     * Return the referenced object to the factory and set pointers to null.
     */
    void
    reset()
    {
        if (m_object != 0)
        {
            assert(m_factory != 0);

            m_factory->returnObject(m_object);

            m_object = 0;
        }

        m_factory = 0;
    }

    /**
     * Transfers ownership of XPath to caller
     * 
     * @return pointer to XPath
     */
    const XPath*
    release()
    {
        const XPath* const  theTemp = m_object;

        m_object = 0;

        return theTemp;
    }

private:

    XPathGuard&
    operator=(const XPathGuard&);

    bool
    operator==(const XPathGuard&) const;


    // Data members...
    XPathFactory*   m_factory;
    const XPath*    m_object;
};



}



#endif  // XPATHFACTORY_HEADER_GUARD_1357924680
