/*******************************************************************************
 * Copyright (c) 2008 Standards for Technology in Automotive Retail and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     David Carver (STAR) - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.xml.xpath.core.util;

import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;

import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.PrefixResolverDefault;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
import org.apache.xpath.compiler.FunctionTable;
import org.apache.xpath.jaxp.JAXPPrefixResolver;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.NodeIterator;

public class XSLTXPathHelper {

	/**
	 * Use an XPath string to select a single node. XPath namespace prefixes are
	 * resolved from the context node, which may not be what you want (see the
	 * next method).
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @return The first node found that matches the XPath, or null.
	 * 
	 * @throws TransformerException
	 */
	public static Node selectSingleNode(Node contextNode, String str)
			throws TransformerException {
		return selectSingleNode(contextNode, str, contextNode);
	}

	/**
	 * Use an XPath string to select a single node. XPath namespace prefixes are
	 * resolved from the namespaceNode.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @param namespaceNode
	 *            The node from which prefixes in the XPath will be resolved to
	 *            namespaces.
	 * @return The first node found that matches the XPath, or null.
	 * 
	 * @throws TransformerException
	 */
	public static Node selectSingleNode(Node contextNode, String str,
			Node namespaceNode) throws TransformerException {

		// Have the XObject return its result as a NodeSetDTM.
		NodeIterator nl = selectNodeIterator(contextNode, str, namespaceNode);

		// Return the first node, or null
		return nl.nextNode();
	}

	/**
	 * Use an XPath string to select a nodelist. XPath namespace prefixes are
	 * resolved from the contextNode.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @return A NodeIterator, should never be null.
	 * 
	 * @throws TransformerException
	 */
	public static NodeIterator selectNodeIterator(Node contextNode, String str)
			throws TransformerException {
		return selectNodeIterator(contextNode, str, contextNode);
	}

	/**
	 * Use an XPath string to select a nodelist. XPath namespace prefixes are
	 * resolved from the namespaceNode.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @param namespaceNode
	 *            The node from which prefixes in the XPath will be resolved to
	 *            namespaces.
	 * @return A NodeIterator, should never be null.
	 * 
	 * @throws TransformerException
	 */
	public static NodeIterator selectNodeIterator(Node contextNode, String str,
			Node namespaceNode) throws TransformerException {

		// Execute the XPath, and have it return the result
		XObject list = eval(contextNode, str, namespaceNode);

		// Have the XObject return its result as a NodeSetDTM.
		return list.nodeset();
	}

	/**
	 * Use an XPath string to select a nodelist. XPath namespace prefixes are
	 * resolved from the contextNode.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @return A NodeIterator, should never be null.
	 * 
	 * @throws TransformerException
	 */
	public static NodeList selectNodeList(Node contextNode, String str)
			throws TransformerException {
		return selectNodeList(contextNode, str, contextNode);
	}

	/**
	 * Use an XPath string to select a nodelist. XPath namespace prefixes are
	 * resolved from the namespaceNode.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @param namespaceNode
	 *            The node from which prefixes in the XPath will be resolved to
	 *            namespaces.
	 * @return A NodeIterator, should never be null.
	 * 
	 * @throws TransformerException
	 */
	public static NodeList selectNodeList(Node contextNode, String str,
			Node namespaceNode) throws TransformerException {

		// Execute the XPath, and have it return the result
		XObject list = eval(contextNode, str, namespaceNode);

		// Return a NodeList.
		return list.nodelist();
	}

	/**
	 * Evaluate XPath string to an XObject. Using this method, XPath namespace
	 * prefixes will be resolved from the namespaceNode.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @return An XObject, which can be used to obtain a string, number,
	 *         nodelist, etc, should never be null.
	 * @see org.apache.xpath.objects.XObject
	 * @see org.apache.xpath.objects.XNull
	 * @see org.apache.xpath.objects.XBoolean
	 * @see org.apache.xpath.objects.XNumber
	 * @see org.apache.xpath.objects.XString
	 * @see org.apache.xpath.objects.XRTreeFrag
	 * 
	 * @throws TransformerException
	 */
	public static XObject eval(Node contextNode, String str)
			throws TransformerException {
		return eval(contextNode, str, contextNode);
	}

	/**
	 * Evaluate XPath string to an XObject. XPath namespace prefixes are
	 * resolved from the namespaceNode. The implementation of this is a little
	 * slow, since it creates a number of objects each time it is called. This
	 * could be optimized to keep the same objects around, but then
	 * thread-safety issues would arise.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @param namespaceNode
	 *            The node from which prefixes in the XPath will be resolved to
	 *            namespaces.
	 * @return An XObject, which can be used to obtain a string, number,
	 *         nodelist, etc, should never be null.
	 * @see org.apache.xpath.objects.XObject
	 * @see org.apache.xpath.objects.XNull
	 * @see org.apache.xpath.objects.XBoolean
	 * @see org.apache.xpath.objects.XNumber
	 * @see org.apache.xpath.objects.XString
	 * @see org.apache.xpath.objects.XRTreeFrag
	 * 
	 * @throws TransformerException
	 * 
	 */
	public static XObject eval(Node contextNode, String str, Node namespaceNode)
			throws TransformerException {

		// Since we don't have a XML Parser involved here, install some default
		// support
		// for things like namespaces, etc.
		// (Changed from: XPathContext xpathSupport = new XPathContext();
		// because XPathContext is weak in a number of areas... perhaps
		// XPathContext should be done away with.)
		XPathContext xpathSupport = new XPathContext();

		// Create an object to resolve namespace prefixes.
		// XPath namespaces are resolved from the input context node's document
		// element
		// if it is a root node, or else the current context node (for lack of a
		// better
		// resolution space, given the simplicity of this sample code).		
		PrefixResolverDefault prefixResolver = new PrefixResolverDefault(
				(namespaceNode.getNodeType() == Node.DOCUMENT_NODE) ? ((Document) namespaceNode)
						.getDocumentElement()
						: namespaceNode);

		// Create the XPath object.
		XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null,
				getFunctionTable());

		// Execute the XPath, and have it return the result
		// return xpath.execute(xpathSupport, contextNode, prefixResolver);
		int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);

		return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
	}

	/**
	 * Evaluate XPath string to an XObject. XPath namespace prefixes are
	 * resolved from the namespaceNode. The implementation of this is a little
	 * slow, since it creates a number of objects each time it is called. This
	 * could be optimized to keep the same objects around, but then
	 * thread-safety issues would arise.
	 * 
	 * @param contextNode
	 *            The node to start searching from.
	 * @param str
	 *            A valid XPath string.
	 * @param prefixResolver
	 *            Will be called if the parser encounters namespace prefixes, to
	 *            resolve the prefixes to URLs.
	 * @return An XObject, which can be used to obtain a string, number,
	 *         nodelist, etc, should never be null.
	 * @see org.apache.xpath.objects.XObject
	 * @see org.apache.xpath.objects.XNull
	 * @see org.apache.xpath.objects.XBoolean
	 * @see org.apache.xpath.objects.XNumber
	 * @see org.apache.xpath.objects.XString
	 * @see org.apache.xpath.objects.XRTreeFrag
	 * 
	 * @throws TransformerException
	 */
	public static XObject eval(Node contextNode, String str,
			PrefixResolver prefixResolver) throws TransformerException {

		// Since we don't have a XML Parser involved here, install some default
		// support
		// for things like namespaces, etc.
		// (Changed from: XPathContext xpathSupport = new XPathContext();
		// because XPathContext is weak in a number of areas... perhaps
		// XPathContext should be done away with.)
		// Create the XPath object.
		XPath xpath = new XPath(str, null, prefixResolver, XPath.SELECT, null,
				getFunctionTable());

		// Execute the XPath, and have it return the result
		XPathContext xpathSupport = new XPathContext();
		int ctxtNode = xpathSupport.getDTMHandleFromNode(contextNode);

		return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
	}

	public static void compile(String expression)
			throws XPathExpressionException {
		try {
			new XPath(expression, null, null, org.apache.xpath.XPath.SELECT,
					null, getFunctionTable());
		} catch (javax.xml.transform.TransformerException te) {
			throw new XPathExpressionException(te);
		}

	}

	protected static FunctionTable getFunctionTable() {
		FunctionTable functionTable = new FunctionTable();
		functionTable.installFunction("key",
				org.apache.xalan.templates.FuncKey.class);
		functionTable.installFunction("format-number",
				org.apache.xalan.templates.FuncFormatNumb.class);
		functionTable.installFunction("document",
				org.apache.xalan.templates.FuncDocument.class);
		functionTable.installFunction("element-available",
				org.apache.xpath.functions.FuncExtElementAvailable.class);
		functionTable.installFunction("function-available",
				org.apache.xpath.functions.FuncExtFunctionAvailable.class);
		functionTable.installFunction("current",
				org.apache.xpath.functions.FuncCurrent.class);
		functionTable.installFunction("unparsed-entity-string",
				org.apache.xpath.functions.FuncUnparsedEntityURI.class);
		functionTable.installFunction("generate-id",
				org.apache.xpath.functions.FuncGenerateId.class);
		functionTable.installFunction("system-property",
				org.apache.xpath.functions.FuncSystemProperty.class);
		return functionTable;
	}

	/**
	 * Returns a XPath expression given a DOM Node.
	 * 
	 * @param node
	 *            The DOM Node to create the XPath expression.
	 * @since 1.0
	 */
	public static String calculateXPathToNode(Node node) {
		Node xpathNode = node;
		StringBuffer sb = new StringBuffer();
		while (xpathNode != null) {
			switch (xpathNode.getNodeType()) {
			case Node.ATTRIBUTE_NODE:
				sb.insert(0, xpathNode.getNodeName());
				sb.insert(0, "/@"); //$NON-NLS-1$
				xpathNode = ((Attr) xpathNode).getOwnerElement();
				break;
			case Node.ELEMENT_NODE:
				Node sibling = xpathNode;
				int position = 1;
				while ((sibling = sibling.getPreviousSibling()) != null) {
					if (sibling.getNodeType() == Node.ELEMENT_NODE
							&& sibling.getNodeName().equals(xpathNode.getNodeName())) {
						++position;
					}
				}
				if (position > 1) {
					sb.insert(0, "[" + position + "]"); //$NON-NLS-1$ //$NON-NLS-2$
				}
				else {
					sibling = xpathNode.getNextSibling();
					boolean following = false;
					while (sibling != null) {
						if (sibling.getNodeType() == Node.ELEMENT_NODE
								&& sibling.getNodeName().equals(
										xpathNode.getNodeName())) {
							following = true;
							break;
						}
						sibling = sibling.getNextSibling();
					}
					if (following) {
						sb.insert(0, "[1]"); //$NON-NLS-1$
					}
				}
				sb.insert(0, xpathNode.getNodeName());
				sb.insert(0, "/"); //$NON-NLS-1$
				xpathNode = xpathNode.getParentNode();
				break;
			default:
				xpathNode = xpathNode.getParentNode();
			}
		}
		return sb.toString();
	}

}
