/*******************************************************************************
 * Copyright (c) 2008 Standards for Technology in Automotive Retail
 * 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 - bug 224197 - initial API and implementation
 *                    based on work from Apache Xalan 2.7.0
 *******************************************************************************/
/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed 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.
 */
/*
 * $Id: TraceManager.java,v 1.3 2008/03/28 02:38:17 dacarver Exp $
 */
package org.eclipse.wst.xsl.core.internal.compiler.xslt10.trace;

import java.lang.reflect.Method;
import java.util.TooManyListenersException;
import java.util.Vector;

import org.eclipse.wst.xsl.core.internal.compiler.xslt10.templates.ElemTemplateElement;
import org.eclipse.wst.xsl.core.internal.compiler.xslt10.transformer.TransformerImpl;
import org.eclipse.wst.xsl.core.internal.compiler.xslt10.xpath.XPath;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Node;

/**
 * This class manages trace listeners, and acts as an interface for the tracing
 * functionality in Xalan.
 */
public class TraceManager {

	/** A transformer instance */
	private TransformerImpl m_transformer;

	/**
	 * Constructor for the trace manager.
	 * 
	 * @param transformer
	 *            a non-null instance of a transformer
	 */
	public TraceManager(TransformerImpl transformer) {
		m_transformer = transformer;
	}

	/**
	 * List of listeners who are interested in tracing what's being generated.
	 */
	private Vector m_traceListeners = null;

	/**
	 * Add a trace listener for the purposes of debugging and diagnosis.
	 * 
	 * @param tl
	 *            Trace listener to be added.
	 * 
	 * @throws TooManyListenersException
	 */
	public void addTraceListener(TraceListener tl)
			throws TooManyListenersException {

		m_transformer.setDebug(true);

		if (null == m_traceListeners)
			m_traceListeners = new Vector();

		m_traceListeners.addElement(tl);
	}

	/**
	 * Remove a trace listener.
	 * 
	 * @param tl
	 *            Trace listener to be removed.
	 */
	public void removeTraceListener(TraceListener tl) {

		if (null != m_traceListeners) {
			m_traceListeners.removeElement(tl);

			// The following line added to fix the bug#5140: hasTraceListeners()
			// returns true
			// after adding and removing a listener.
			// Check: if m_traceListeners is empty, then set it to NULL.
			if (0 == m_traceListeners.size())
				m_traceListeners = null;
		}
	}

	/**
	 * Fire a generate event.
	 * 
	 * @param te
	 *            Generate Event to fire
	 */
	public void fireGenerateEvent(GenerateEvent te) {

		if (null != m_traceListeners) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);

				tl.generated(te);
			}
		}
	}

	/**
	 * Tell if trace listeners are present.
	 * 
	 * @return True if there are trace listeners
	 */
	public boolean hasTraceListeners() {
		return (null != m_traceListeners);
	}

	/**
	 * Fire a trace event.
	 * 
	 * @param styleNode
	 *            Stylesheet template node
	 */
	public void fireTraceEvent(ElemTemplateElement styleNode) {

		if (hasTraceListeners()) {
			int sourceNode = m_transformer.getXPathContext().getCurrentNode();
			Node source = getDOMNodeFromDTM(sourceNode);

			fireTraceEvent(new TracerEvent(m_transformer, source, m_transformer
					.getMode(), /* sourceNode, mode, */
			styleNode));
		}
	}

	/**
	 * Fire a end trace event, after all children of an element have been
	 * executed.
	 * 
	 * @param styleNode
	 *            Stylesheet template node
	 */
	public void fireTraceEndEvent(ElemTemplateElement styleNode) {

		if (hasTraceListeners()) {
			int sourceNode = m_transformer.getXPathContext().getCurrentNode();
			Node source = getDOMNodeFromDTM(sourceNode);

			fireTraceEndEvent(new TracerEvent(m_transformer, source,
					m_transformer.getMode(), /* sourceNode, mode, */
					styleNode));
		}
	}

	/**
	 * Fire a trace event.
	 * 
	 * @param te
	 *            Trace event to fire
	 */
	public void fireTraceEndEvent(TracerEvent te) {

		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);
				if (tl instanceof TraceListenerEx2) {
					((TraceListenerEx2) tl).traceEnd(te);
				}
			}
		}
	}

	/**
	 * Fire a trace event.
	 * 
	 * @param te
	 *            Trace event to fire
	 */
	public void fireTraceEvent(TracerEvent te) {

		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);

				tl.trace(te);
			}
		}
	}

	/**
	 * Fire a selection event.
	 * 
	 * @param sourceNode
	 *            Current source node
	 * @param styleNode
	 *            node in the style tree reference for the event.
	 * @param attributeName
	 *            The attribute name from which the selection is made.
	 * @param xpath
	 *            The XPath that executed the selection.
	 * @param selection
	 *            The result of the selection.
	 * 
	 * @throws javax.xml.transform.TransformerException
	 */
	public void fireSelectedEvent(int sourceNode,
			ElemTemplateElement styleNode, String attributeName, XPath xpath,
			XObject selection) throws javax.xml.transform.TransformerException {

		if (hasTraceListeners()) {
			Node source = getDOMNodeFromDTM(sourceNode);

			fireSelectedEvent(new SelectionEvent(m_transformer, source,
					styleNode, attributeName, xpath, selection));
		}
	}

	/**
	 * Fire a selection event.
	 * 
	 * @param sourceNode
	 *            Current source node
	 * @param styleNode
	 *            node in the style tree reference for the event.
	 * @param attributeName
	 *            The attribute name from which the selection is made.
	 * @param xpath
	 *            The XPath that executed the selection.
	 * @param selection
	 *            The result of the selection.
	 * 
	 * @throws javax.xml.transform.TransformerException
	 */
	public void fireSelectedEndEvent(int sourceNode,
			ElemTemplateElement styleNode, String attributeName, XPath xpath,
			XObject selection) throws javax.xml.transform.TransformerException {

		if (hasTraceListeners()) {
			Node source = getDOMNodeFromDTM(sourceNode);

			fireSelectedEndEvent(new EndSelectionEvent(m_transformer, source,
					styleNode, attributeName, xpath, selection));
		}
	}

	/**
	 * Fire a selection event.
	 * 
	 * @param se
	 *            Selection event to fire
	 * 
	 * @throws javax.xml.transform.TransformerException
	 */
	public void fireSelectedEndEvent(EndSelectionEvent se)
			throws javax.xml.transform.TransformerException {

		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);

				if (tl instanceof TraceListenerEx)
					((TraceListenerEx) tl).selectEnd(se);
			}
		}
	}

	/**
	 * Fire a selection event.
	 * 
	 * @param se
	 *            Selection event to fire
	 * 
	 * @throws javax.xml.transform.TransformerException
	 */
	public void fireSelectedEvent(SelectionEvent se)
			throws javax.xml.transform.TransformerException {

		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);

				tl.selected(se);
			}
		}
	}

	/**
	 * Fire an end extension event.
	 * 
	 * @see java.lang.reflect.Method#invoke
	 * 
	 * @param method
	 *            The java method about to be executed
	 * @param instance
	 *            The instance the method will be executed on
	 * @param arguments
	 *            Parameters passed to the method.
	 */
	public void fireExtensionEndEvent(Method method, Object instance,
			Object[] arguments) {
		ExtensionEvent ee = new ExtensionEvent(m_transformer, method, instance,
				arguments);

		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);
				if (tl instanceof TraceListenerEx3) {
					((TraceListenerEx3) tl).extensionEnd(ee);
				}
			}
		}
	}

	/**
	 * Fire an end extension event.
	 * 
	 * @see java.lang.reflect.Method#invoke
	 * 
	 * @param method
	 *            The java method about to be executed
	 * @param instance
	 *            The instance the method will be executed on
	 * @param arguments
	 *            Parameters passed to the method.
	 */
	public void fireExtensionEvent(Method method, Object instance,
			Object[] arguments) {
		ExtensionEvent ee = new ExtensionEvent(m_transformer, method, instance,
				arguments);

		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);
				if (tl instanceof TraceListenerEx3) {
					((TraceListenerEx3) tl).extension(ee);
				}
			}
		}
	}

	/**
	 * Fire an end extension event.
	 * 
	 * @see java.lang.reflect.Method#invoke
	 * 
	 * @param ee
	 *            the ExtensionEvent to fire
	 */
	public void fireExtensionEndEvent(ExtensionEvent ee) {
		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);
				if (tl instanceof TraceListenerEx3) {
					((TraceListenerEx3) tl).extensionEnd(ee);
				}
			}
		}
	}

	/**
	 * Fire an end extension event.
	 * 
	 * @see java.lang.reflect.Method#invoke
	 * 
	 * @param ee
	 *            the ExtensionEvent to fire
	 */
	public void fireExtensionEvent(ExtensionEvent ee) {

		if (hasTraceListeners()) {
			int nListeners = m_traceListeners.size();

			for (int i = 0; i < nListeners; i++) {
				TraceListener tl = (TraceListener) m_traceListeners
						.elementAt(i);
				if (tl instanceof TraceListenerEx3) {
					((TraceListenerEx3) tl).extension(ee);
				}
			}
		}
	}

	/**
	 * Get the DOM Node of the current XPath context, which is possibly null.
	 * 
	 * @param sourceNode
	 *            the handle on the node used by a DTM.
	 */
	private Node getDOMNodeFromDTM(int sourceNode) {
		org.apache.xml.dtm.DTM dtm = m_transformer.getXPathContext().getDTM(
				sourceNode);
		final Node source = (dtm == null) ? null : dtm.getNode(sourceNode);
		return source;
	}
}
