/*
 * 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/>.
 */
// Class header file
#include "KeyTable.hpp"



#include <memory>



#include <XalanDOM/XalanElement.hpp>
#include <XalanDOM/XalanNamedNodeMap.hpp>
#include <XalanDOM/XalanNode.hpp>
#include <XalanDOM/XalanNodeList.hpp>



#include <DOMSupport/DOMServices.hpp>



#include <XPath/XPath.hpp>



#include "KeyDeclaration.hpp"
#include "StylesheetExecutionContext.hpp"
#include "XSLTProcessorException.hpp"



const MutableNodeRefList	KeyTable::s_dummyList;



KeyTable::KeyTable(
			XalanNode*							doc,
			XalanNode*							startNode,
			const PrefixResolver&				resolver,
			const KeyDeclarationVectorType&		keyDeclarations,
			StylesheetExecutionContext&			executionContext) :
	m_docKey(doc),
	m_keys()
{
    XalanNode*	pos = startNode;

	const KeyDeclarationVectorType::size_type	nDeclarations =
			keyDeclarations.size();

    // Do a non-recursive pre-walk over the tree.
    while(0 != pos)
    {
		// We're going to have to walk the attribute list 
		// if it's an element, so get the attributes.
		const XalanNamedNodeMap*	attrs = 0;

		int							nNodes = 0;

		if(XalanNode::ELEMENT_NODE == pos->getNodeType())
		{
			attrs = pos->getAttributes();

			nNodes = attrs->getLength();
        
			if(0 == nNodes)
			{
				attrs = 0;
			}
		}

		// Walk the primary node, and each of the attributes.
		// This loop is a little strange... it is meant to always 
		// execute once, then execute for each of the attributes.
		XalanNode*	testNode = pos;

		for(int nodeIndex = -1; nodeIndex < nNodes;)
		{
			// Walk through each of the declarations made with xsl:key
			for(unsigned int i = 0; i < nDeclarations; ++i)
			{
				const KeyDeclaration&	kd = keyDeclarations[i];

				if (executionContext.getInConstruction(kd) == true)			
				{
					throw XSLTProcessorException(
							TranscodeFromLocalCodePage("The use of the key() function in the \"match\" or \"use\" attribute of xsl:key is illegal!"),
							TranscodeFromLocalCodePage("XSLTKeyIllegalKeyFunctionException"));
				}
				else
				{
					executionContext.beginConstruction(kd);

					// See if our node matches the given key declaration according to 
					// the match attribute on xsl:key.
					assert(kd.getMatchPattern() != 0);

					const XPath::eMatchScore	score =
							kd.getMatchPattern()->getMatchScore(testNode,
																resolver,
																executionContext);

					if(score != XPath::eMatchScoreNone)
					{
						processKeyDeclaration(
							m_keys,
							kd,
							testNode,
							resolver,
							executionContext);
					}

					executionContext.endConstruction(kd);
				} // if (kd.getInConstruction() == true)
			} // end for(int i = 0; i < nDeclarations; ++i)

			++nodeIndex;

			if(0 != attrs)
			{
				testNode = attrs->item(nodeIndex);
			}
		} // for(int nodeIndex = -1; nodeIndex < nNodes;)

		// The rest of this is getting the next prewalk position in 
		// the tree.
		XalanNode*	nextNode = pos->getFirstChild();

		while(0 == nextNode)
		{
			if(startNode == pos)
			{
				break;
			}
			else
			{
				nextNode = pos->getNextSibling();

				if(0 == nextNode)
				{
					pos = pos->getParentNode();

					if((startNode == pos) || (0 == pos))
					{
						nextNode = 0;
						break;
					}
				}
			}
		}

		pos = nextNode;
    } // while(0 != pos)
} // end constructor



KeyTable::~KeyTable()
{
}



const NodeRefListBase&
KeyTable::getNodeSetByKey(
					  const XalanQName&			qname, 
					  const XalanDOMString&		ref) const
{
	const KeysMapType::const_iterator	i = m_keys.find(qname);

	if (i != m_keys.end())
	{
		const NodeListMapType&	theMap = (*i).second;

		const NodeListMapType::const_iterator	j = theMap.find(ref);

		if (j != theMap.end())
		{
			return (*j).second;
		}
	}

	// It makes things much easier if we always return
	// a list of nodes.  So this is just an empty one
	// to return when the ref is not found.
	return s_dummyList;
}



inline void
KeyTable::addIfNotFound(
			MutableNodeRefList&		theNodeList,
			XalanNode*				theNode)
{
	if (theNodeList.indexOf(theNode) == MutableNodeRefList::npos)
	{
		theNodeList.addNode(theNode);
	}
}



void
KeyTable::processKeyDeclaration(
			KeysMapType&					theKeys,
			const KeyDeclaration&			kd,
			XalanNode*						testNode,
			const PrefixResolver&			resolver,
			StylesheetExecutionContext&		executionContext)
{
	// Query from the node, according the the select pattern in the
	// use attribute in xsl:key.
	assert(kd.getUse() != 0);

	const XObjectPtr	xuse(kd.getUse()->execute(testNode, resolver, NodeRefList(), executionContext));

	if(xuse->getType() != XObject::eTypeNodeSet)
	{
		addIfNotFound(
			theKeys[kd.getQName()][xuse->str()],
			testNode);
	}
	else
	{
		const NodeRefListBase&	nl = xuse->nodeset();

		// Use each node in the node list as a key value that we'll be 
		// able to use to look up the given node.
		const NodeRefListBase::size_type	nUseValues = nl.getLength();

		StylesheetExecutionContext::GetAndReleaseCachedString	theGuard(executionContext);

		XalanDOMString&		nodeData = theGuard.get();

		// Use each node in the node list as a key value that we'll be 
		// able to use to look up the given node.
		for(unsigned int i = 0; i < nUseValues; ++i)
		{
			// Get the string value of the node to use as the result of the
			// expression.
			assert(nl.item(i) != 0);

			DOMServices::getNodeData(*nl.item(i), nodeData);

			addIfNotFound(
				theKeys[kd.getQName()][nodeData],
				testNode);

			clear(nodeData);
		}
	}  
}
