/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author <a href="mailto:david_n_bertoni@lotus.com">David N. Bertoni</a>
 */
#if !defined(XPATHEXECUTIONCONTEXT_HEADER_GUARD_1357924680)
#define XPATHEXECUTIONCONTEXT_HEADER_GUARD_1357924680



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



#include <cassert>
#include <vector>



#include <XalanDOM/XalanDOMString.hpp>



// Base class header file...
#include <PlatformSupport/ExecutionContext.hpp>



#include <XPath/MutableNodeRefList.hpp>
#include <XPath/ResultTreeFragBase.hpp>



class XalanDecimalFormatSymbols;
class PrefixResolver;
class XalanQName;
class XLocator;
class XMLURL;
class XObject;
class XObjectPtr;
class XObjectFactory;
class XalanDocument;
class XalanElement;
class XalanNode;
class XalanText;



//
// An abstract class which provides support for executing XPath functions
// and extension functions.
//

class XALAN_XPATH_EXPORT XPathExecutionContext : public ExecutionContext
{
public:

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<XObjectPtr>			XObjectArgVectorType;
#else
	typedef std::vector<XObjectPtr>		XObjectArgVectorType;
#endif

	typedef NodeRefListBase::size_type	size_type;

	explicit
	XPathExecutionContext(XObjectFactory*	theXObjectFactory = 0);

	virtual
	~XPathExecutionContext();

	/**
	 * Reset the instance.  This must be called before another
	 * execution is attempted.
	 */
	virtual void
	reset() = 0;

	/**
	 * Retrieve the node currently being executed.
	 * 
	 * @return current node
	 */
	virtual XalanNode*
	getCurrentNode() const = 0;

	/**
	 * Change the node currently being executed.
	 * 
	 * @param theCurrentNode new current node
	 */
	virtual void
	setCurrentNode(XalanNode*	theCurrentNode) = 0;

	class CurrentNodeSetAndRestore
	{
	public:

		CurrentNodeSetAndRestore(
				XPathExecutionContext&	theExecutionContext,
				XalanNode*				theNode) :
			m_executionContext(theExecutionContext),
			m_savedNode(theExecutionContext.getCurrentNode())
		{
			m_executionContext.setCurrentNode(theNode);
		}

		~CurrentNodeSetAndRestore()
		{
			m_executionContext.setCurrentNode(m_savedNode);
		}

	private:

		XPathExecutionContext&	m_executionContext;
		XalanNode* const		m_savedNode;
	};

	/**
	 * Retrieve the factory object for creating XObjects.
	 * 
	 * @return factory object instance
	 */
	XObjectFactory&
	getXObjectFactory() const
	{
		assert(m_xobjectFactory != 0);

		return *m_xobjectFactory;
	}

	/**
	 * Convenience function for creating a node set with
	 * the supplied node as the only member.
	 *
	 * @param node	The  node queried
	 * @return a pointer to the XObject instance.
	 */
	virtual XObjectPtr
	createNodeSet(XalanNode&	theNode) = 0;

	/**
	 * Determine if a node is after another node, in document order.
	 *
	 * @param node1 The first node
	 * @param node2 The second node
	 * @return true if node1 one is after node2, or false if it is not.
	 */
	virtual bool
	isNodeAfter(
			const XalanNode&	node1,
			const XalanNode&	node2) const = 0;

	/**
	 * Retrieve node list for current context.
	 * 
	 * @return node list
	 */
	virtual const NodeRefListBase&
	getContextNodeList() const = 0;

	/**
	 * Set node list for current context.
	 * 
	 * @param theList new node list
	 */
	virtual void	
	setContextNodeList(const NodeRefListBase&	theList) = 0;

	class ContextNodeListSetAndRestore
	{
	public:

		ContextNodeListSetAndRestore(
				XPathExecutionContext&		theExecutionContext,
				const NodeRefListBase&		theNodeList) :
			m_executionContext(theExecutionContext),
			m_savedNodeList(theExecutionContext.getContextNodeList())
		{
			m_executionContext.setContextNodeList(theNodeList);
		}

		~ContextNodeListSetAndRestore()
		{
			m_executionContext.setContextNodeList(m_savedNodeList);
		}

	private:

		XPathExecutionContext&	m_executionContext;
		const NodeRefListBase&	m_savedNodeList;
	};

	/*
	 * Get the count of nodes in the current context node list.
	 *
	 * @return length of list
	 */
	virtual size_type
	getContextNodeListLength() const = 0;

	/*
	 * Get the position of the node in the current context node list.
	 * Note that this is 1-based indexing (XPath/XSLT-style), not 0-based.
	 * Thus, 0 will be returned if the node was not found.
	 *
	 * @return position in list
	 */
	virtual size_type
	getContextNodeListPosition(const XalanNode&		contextNode) const = 0;

	/**
	 * Determine if an external element is available.
	 *
	 * @param theNamespace  namespace for the element
	 * @param elementName name of extension element
	 * @return whether the given element is available or not
	 */
	virtual bool
	elementAvailable(
			const XalanDOMString&	theNamespace, 
			const XalanDOMString&	elementName) const = 0;

	/**
	 * Determine if a function is available.  For standard
	 * function availability, theNamespace should be an
	 * empty string.
	 *
	 * @param theNamespace  namespace for the function
	 * @param functionName name of the function
	 * @return whether the function is available or not
	 */
	virtual bool
	functionAvailable(
			const XalanDOMString&	theNamespace, 
			const XalanDOMString&	functionName) const = 0;

	/**
	 * Handle an extension function.
	 * 
	 * @param theNamespace  namespace of function    
	 * @param functionName extension function name
	 * @param context The context node
	 * @param argVec vector of arguments to function
	 * @param locator A Locator instance for error reporting
	 * @return pointer to XObject result
	 */
	virtual const XObjectPtr
	extFunction(
			const XalanDOMString&			theNamespace,
			const XalanDOMString&			functionName,
			XalanNode*						context,
			const XObjectArgVectorType&		argVec,
			const Locator*					locator) = 0;

	/**
	 * Provides support for XML parsing service.
	 *
	 * @param urlString location of the XML
	 * @param base base location for URI
	 * @return parsed document
	 */
	virtual XalanDocument*
	parseXML(
			const XalanDOMString&	urlString,
			const XalanDOMString&	base) const = 0;

	/**
	 * Borrow a cached MutableNodeRefList instance.
	 *
	 * @return A pointer to the instance.
	 */
	virtual MutableNodeRefList*
	borrowMutableNodeRefList() = 0;

	/**
	 * Return a previously borrowed MutableNodeRefList instance.
	 *
	 * @param theList A pointer the to previously borrowed instance.
	 * @return true if the list was borrowed (at therefore, destroyed), false if not.
	 */
	virtual bool
	returnMutableNodeRefList(MutableNodeRefList*	theList) = 0;

	class BorrowReturnMutableNodeRefList
	{
	public:

		BorrowReturnMutableNodeRefList(XPathExecutionContext&	executionContext) :
			m_xpathExecutionContext(&executionContext),
			m_mutableNodeRefList(executionContext.borrowMutableNodeRefList())
		{
			assert(m_mutableNodeRefList != 0);
		}

		// N.B. Non-const copy constructor semantics (like std::auto_ptr)
		BorrowReturnMutableNodeRefList(const BorrowReturnMutableNodeRefList&	theSource) :
			m_xpathExecutionContext(theSource.m_xpathExecutionContext),
			m_mutableNodeRefList(theSource.m_mutableNodeRefList)
		{
			assert(m_mutableNodeRefList != 0);

			((BorrowReturnMutableNodeRefList&)theSource).m_mutableNodeRefList = 0;
		}

		~BorrowReturnMutableNodeRefList()
		{
			release();
		}

		MutableNodeRefList&
		operator*() const
		{
			assert(m_mutableNodeRefList != 0);

			return *m_mutableNodeRefList;
		}

		MutableNodeRefList*
		get() const
		{
			return m_mutableNodeRefList;
		}

		MutableNodeRefList*
		operator->() const
		{
			return get();
		}

		void
		release()
		{
			assert(m_xpathExecutionContext != 0);

			if (m_mutableNodeRefList != 0)
			{
				m_xpathExecutionContext->returnMutableNodeRefList(m_mutableNodeRefList);

				m_mutableNodeRefList = 0;
			}
		}

		BorrowReturnMutableNodeRefList
		clone() const
		{
			assert(m_xpathExecutionContext != 0);

			BorrowReturnMutableNodeRefList	theResult(*m_xpathExecutionContext);

			*theResult = *m_mutableNodeRefList;

			return theResult;
		}

		// N.B. Non-const assignment operator semantics.
		BorrowReturnMutableNodeRefList&
		operator=(BorrowReturnMutableNodeRefList&	theRHS)
		{
			release();

			m_xpathExecutionContext = theRHS.m_xpathExecutionContext;

			m_mutableNodeRefList = theRHS.m_mutableNodeRefList;

			theRHS.m_mutableNodeRefList = 0;

			return *this;
		}

	private:

		XPathExecutionContext*	m_xpathExecutionContext;

		MutableNodeRefList*		m_mutableNodeRefList;
	};

	virtual XalanDOMString&
	getCachedString() = 0;

	virtual bool
	releaseCachedString(XalanDOMString&		theString) = 0;

	class GetAndReleaseCachedString
	{
	public:

		GetAndReleaseCachedString(XPathExecutionContext&	theExecutionContext) :
			m_executionContext(&theExecutionContext),
			m_string(&theExecutionContext.getCachedString())
		{
		}

		// Note non-const copy semantics...
		GetAndReleaseCachedString(GetAndReleaseCachedString&	theSource) :
			m_executionContext(theSource.m_executionContext),
			m_string(theSource.m_string)
		{
			theSource.m_string = 0;
		}

		~GetAndReleaseCachedString()
		{
			if (m_string != 0)
			{
				m_executionContext->releaseCachedString(*m_string);
			}
		}

		XalanDOMString&
		get() const
		{
			assert(m_string != 0);

			return *m_string;
		}

		XPathExecutionContext&
		getExecutionContext() const
		{
			return *m_executionContext;
		}

	private:

		// Not implemented...
		GetAndReleaseCachedString&
		operator=(const GetAndReleaseCachedString&);


		// Data members...
		XPathExecutionContext*	m_executionContext;

		XalanDOMString*			m_string;
	};

	/**
	 * Create a MutableNodeRefList with the appropriate context.
	 *
	 * @return pointer to node list created
	 */
	virtual MutableNodeRefList*
	createMutableNodeRefList() const = 0;

	/**
	 * Given a valid element key, return the corresponding node list.
	 *
	 * @param doc              source document
	 * @param name             name of the key, which must match the 'name'
	 *                         attribute on xsl:key
	 * @param ref              value that must match the value found by the
	 *                         'match' attribute on xsl:key
	 * @param resolver         resolver for namespace resolution
	 * @param nodelist         A node list to contain the nodes found
	 */
	virtual void
	getNodeSetByKey(
			XalanNode*				doc,
			const XalanDOMString&	name,
			const XalanDOMString&	ref,
			const PrefixResolver&	resolver,
			MutableNodeRefList&		nodelist) = 0;

	/**
	 * Given a name, locate a variable in the current context, and return 
	 * a pointer to the object.
	 *
	 * @param theName name of variable
	 * @return pointer to an XObject if the variable was found, 0 if it was not
	 */
	virtual const XObjectPtr
	getVariable(
			const XalanQName&	name,
			const Locator*		locator = 0) = 0;

	/**
	 * Retrieve the resolver for namespaces.
	 * 
	 * @return object for namespace resolution
	 */
	virtual const PrefixResolver*
	getPrefixResolver() const = 0;

	/**
	 * Change the resolver for namespaces.
	 * 
	 * @param thePrefixResolver new object for namespace resolution
	 */
	virtual void
	setPrefixResolver(const PrefixResolver*		thePrefixResolver) = 0;

	class PrefixResolverSetAndRestore
	{
	public:

		PrefixResolverSetAndRestore(
				XPathExecutionContext&	theExecutionContext,
				const PrefixResolver*	theResolver) :
			m_executionContext(theExecutionContext),
			m_savedResolver(theExecutionContext.getPrefixResolver())
		{
			m_executionContext.setPrefixResolver(theResolver);
		}

		PrefixResolverSetAndRestore(
				XPathExecutionContext&	theExecutionContext,
				const PrefixResolver*	theOldResolver,
				const PrefixResolver*	theNewResolver) :
			m_executionContext(theExecutionContext),
			m_savedResolver(theOldResolver)
		{
			m_executionContext.setPrefixResolver(theNewResolver);
		}

		~PrefixResolverSetAndRestore()
		{
			m_executionContext.setPrefixResolver(m_savedResolver);
		}

	private:

		XPathExecutionContext&			m_executionContext;
		const PrefixResolver* const		m_savedResolver;
	};

	/**
	 * Retrieve the URI corresponding to a namespace prefix
	 * 
	 * @param prefix prefix for a namespace
	 * @return URI corresponding to namespace
	 */
	virtual const XalanDOMString*
	getNamespaceForPrefix(const XalanDOMString&		prefix) const = 0;

	/**
	 * Given a DOM Document, tell what URI was used to parse it. Needed for
	 * relative resolution.
	 *
	 * @param owner source document
	 * @return document URI
	 */
	virtual XalanDOMString
	findURIFromDoc(const XalanDocument*		owner) const = 0;

	/**
	 * The getUnparsedEntityURI function returns the URI of the unparsed
	 * entity with the specified name in the same document as the context
	 * node (see [3.3 Unparsed Entities]). It returns the empty string if
	 * there is no such entity.
	 *
	 * @param theName     name of entity
	 * @param theDocument document containing entity
	 * @return URI for the entity
	 */
	virtual const XalanDOMString&
	getUnparsedEntityURI(
			const XalanDOMString&	theName,
			const XalanDocument&	theDocument) const = 0;

	/**
	 * Tells, through the combination of the default-space attribute
	 * on xsl:stylesheet, xsl:strip-space, xsl:preserve-space, and the
	 * xml:space attribute, whether or not extra whitespace should be stripped
	 * from the node.  Literal elements from template elements should
	 * <em>not</em> be tested with this function.
	 *
	 * @param textNode text node from the source tree
	 * @return true if the text node should be stripped of extra whitespace
	 */
	virtual bool
	shouldStripSourceNode(const XalanNode&	node) = 0;

	/**
	 * Tells if FoundIndex should be thrown if index is found. This is an
	 * optimization for match patterns, and is used internally by the XPath
	 * engine.
	 *
	 * @return true to throw FoundIndex
	 */
	virtual bool
	getThrowFoundIndex() const = 0;

	/**
	 * Changes whether FoundIndex should be thrown if index is found. This is an
	 * optimization for match patterns, and is used internally by the XPath
	 * engine.
	 *
	 * @param fThrow true to throw FoundIndex
	 */
	virtual void
	setThrowFoundIndex(bool 	fThrow) = 0;

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

	/**
	 * Associate a document with a given URI.
	 *
	 * @param theURI      document URI
	 * @param theDocument source document
	 */
	virtual void
	setSourceDocument(
			const XalanDOMString&	theURI,
			XalanDocument*			theDocument) = 0;


	/**
	 * Retrieve the XalanDecimalFormatSymbols instance associated with
	 * the name.
	 *
	 * @param qname the QName for the lookup
	 * @return a pointer to the matching instance, or 0 if none was found
	 */
	virtual const XalanDecimalFormatSymbols*
	getDecimalFormatSymbols(const XalanQName&	qname) = 0;

	// These interfaces are inherited from ExecutionContext...

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

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

	virtual void
	error(
			const char*			msg,
			const XalanNode* 	sourceNode = 0,
			const XalanNode* 	styleNode = 0) const = 0;

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

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

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

	virtual void
	warn(
			const char*			msg,
			const XalanNode* 	sourceNode = 0,
			const XalanNode* 	styleNode = 0) const = 0;

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

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

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

	virtual void
	message(
			const char*			msg,
			const XalanNode* 	sourceNode = 0,
			const XalanNode* 	styleNode = 0) const = 0;

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

protected:

	XObjectFactory*		m_xobjectFactory;
};



#endif	// XPATHEXECUTIONCONTEXT_HEADER_GUARD_1357924680
