blob: 362286f56fc1551de0fd1ac1d23b23bf6093d458 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}