• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id$
20  */
21 package org.apache.xalan.trace;
22 
23 import java.lang.reflect.Method;
24 import java.util.TooManyListenersException;
25 import java.util.Vector;
26 
27 import org.apache.xalan.templates.ElemTemplateElement;
28 import org.apache.xalan.transformer.TransformerImpl;
29 import org.apache.xpath.XPath;
30 import org.apache.xpath.objects.XObject;
31 import org.w3c.dom.Node;
32 
33 /**
34  * This class manages trace listeners, and acts as an
35  * interface for the tracing functionality in Xalan.
36  */
37 public class TraceManager
38 {
39 
40   /** A transformer instance */
41   private TransformerImpl m_transformer;
42 
43   /**
44    * Constructor for the trace manager.
45    *
46    * @param transformer a non-null instance of a transformer
47    */
TraceManager(TransformerImpl transformer)48   public TraceManager(TransformerImpl transformer)
49   {
50     m_transformer = transformer;
51   }
52 
53   /**
54    * List of listeners who are interested in tracing what's
55    * being generated.
56    */
57   private Vector m_traceListeners = null;
58 
59   /**
60    * Add a trace listener for the purposes of debugging and diagnosis.
61    * @param tl Trace listener to be added.
62    *
63    * @throws TooManyListenersException
64    */
addTraceListener(TraceListener tl)65   public void addTraceListener(TraceListener tl)
66           throws TooManyListenersException
67   {
68 
69     // Android-changed: TransformerImpl in 2.7.1 doesn't have setDebug() method.
70     // m_transformer.setDebug(true);
71 
72     if (null == m_traceListeners)
73       m_traceListeners = new Vector();
74 
75     m_traceListeners.addElement(tl);
76   }
77 
78   /**
79    * Remove a trace listener.
80    * @param tl Trace listener to be removed.
81    */
removeTraceListener(TraceListener tl)82   public void removeTraceListener(TraceListener tl)
83   {
84 
85     if (null != m_traceListeners)
86     {
87       m_traceListeners.removeElement(tl);
88 
89       // The following line added to fix the bug#5140: hasTraceListeners() returns true
90       // after adding and removing a listener.
91       // Check: if m_traceListeners is empty, then set it to NULL.
92       if (0 == m_traceListeners.size()) m_traceListeners = null;
93     }
94   }
95 
96   /**
97    * Fire a generate event.
98    *
99    * @param te Generate Event to fire
100    */
fireGenerateEvent(GenerateEvent te)101   public void fireGenerateEvent(GenerateEvent te)
102   {
103 
104     if (null != m_traceListeners)
105     {
106       int nListeners = m_traceListeners.size();
107 
108       for (int i = 0; i < nListeners; i++)
109       {
110         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
111 
112         tl.generated(te);
113       }
114     }
115   }
116 
117   /**
118    * Tell if trace listeners are present.
119    *
120    * @return True if there are trace listeners
121    */
hasTraceListeners()122   public boolean hasTraceListeners()
123   {
124     return (null != m_traceListeners);
125   }
126 
127   /**
128    * Fire a trace event.
129    *
130    * @param styleNode Stylesheet template node
131    */
fireTraceEvent(ElemTemplateElement styleNode)132   public void fireTraceEvent(ElemTemplateElement styleNode)
133   {
134 
135     if (hasTraceListeners())
136     {
137       int sourceNode = m_transformer.getXPathContext().getCurrentNode();
138       Node source = getDOMNodeFromDTM(sourceNode);
139 
140       fireTraceEvent(new TracerEvent(m_transformer, source,
141                      m_transformer.getMode(),  /*sourceNode, mode,*/
142                                      styleNode));
143     }
144   }
145 
146   /**
147    * Fire a end trace event, after all children of an element have been
148    * executed.
149    *
150    * @param styleNode Stylesheet template node
151    */
fireTraceEndEvent(ElemTemplateElement styleNode)152   public void fireTraceEndEvent(ElemTemplateElement styleNode)
153   {
154 
155     if (hasTraceListeners())
156     {
157       int sourceNode = m_transformer.getXPathContext().getCurrentNode();
158       Node source = getDOMNodeFromDTM(sourceNode);
159 
160       fireTraceEndEvent(new TracerEvent(m_transformer, source,
161                      m_transformer.getMode(),  /*sourceNode, mode,*/
162                                      styleNode));
163     }
164   }
165 
166   /**
167    * Fire a trace event.
168    *
169    * @param te Trace event to fire
170    */
fireTraceEndEvent(TracerEvent te)171   public void fireTraceEndEvent(TracerEvent te)
172   {
173 
174     if (hasTraceListeners())
175     {
176       int nListeners = m_traceListeners.size();
177 
178       for (int i = 0; i < nListeners; i++)
179       {
180         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
181         if(tl instanceof TraceListenerEx2)
182         {
183           ((TraceListenerEx2)tl).traceEnd(te);
184         }
185       }
186     }
187   }
188 
189 
190 
191   /**
192    * Fire a trace event.
193    *
194    * @param te Trace event to fire
195    */
fireTraceEvent(TracerEvent te)196   public void fireTraceEvent(TracerEvent te)
197   {
198 
199     if (hasTraceListeners())
200     {
201       int nListeners = m_traceListeners.size();
202 
203       for (int i = 0; i < nListeners; i++)
204       {
205         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
206 
207         tl.trace(te);
208       }
209     }
210   }
211 
212   /**
213    * Fire a selection event.
214    *
215    * @param sourceNode Current source node
216    * @param styleNode node in the style tree reference for the event.
217    * @param attributeName The attribute name from which the selection is made.
218    * @param xpath The XPath that executed the selection.
219    * @param selection The result of the selection.
220    *
221    * @throws javax.xml.transform.TransformerException
222    */
fireSelectedEvent( int sourceNode, ElemTemplateElement styleNode, String attributeName, XPath xpath, XObject selection)223   public void fireSelectedEvent(
224           int sourceNode, ElemTemplateElement styleNode, String attributeName,
225           XPath xpath, XObject selection)
226             throws javax.xml.transform.TransformerException
227   {
228 
229     if (hasTraceListeners())
230     {
231       Node source = getDOMNodeFromDTM(sourceNode);
232 
233       fireSelectedEvent(new SelectionEvent(m_transformer, source, styleNode,
234                                            attributeName, xpath, selection));
235     }
236   }
237 
238   /**
239    * Fire a selection event.
240    *
241    * @param sourceNode Current source node
242    * @param styleNode node in the style tree reference for the event.
243    * @param attributeName The attribute name from which the selection is made.
244    * @param xpath The XPath that executed the selection.
245    * @param selection The result of the selection.
246    *
247    * @throws javax.xml.transform.TransformerException
248    */
fireSelectedEndEvent( int sourceNode, ElemTemplateElement styleNode, String attributeName, XPath xpath, XObject selection)249   public void fireSelectedEndEvent(
250           int sourceNode, ElemTemplateElement styleNode, String attributeName,
251           XPath xpath, XObject selection)
252             throws javax.xml.transform.TransformerException
253   {
254 
255     if (hasTraceListeners())
256     {
257       Node source = getDOMNodeFromDTM(sourceNode);
258 
259       fireSelectedEndEvent(new EndSelectionEvent(m_transformer, source, styleNode,
260                                            attributeName, xpath, selection));
261     }
262   }
263 
264   /**
265    * Fire a selection event.
266    *
267    * @param se Selection event to fire
268    *
269    * @throws javax.xml.transform.TransformerException
270    */
fireSelectedEndEvent(EndSelectionEvent se)271   public void fireSelectedEndEvent(EndSelectionEvent se)
272           throws javax.xml.transform.TransformerException
273   {
274 
275     if (hasTraceListeners())
276     {
277       int nListeners = m_traceListeners.size();
278 
279       for (int i = 0; i < nListeners; i++)
280       {
281         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
282 
283         if(tl instanceof TraceListenerEx)
284           ((TraceListenerEx)tl).selectEnd(se);
285       }
286     }
287   }
288 
289   /**
290    * Fire a selection event.
291    *
292    * @param se Selection event to fire
293    *
294    * @throws javax.xml.transform.TransformerException
295    */
fireSelectedEvent(SelectionEvent se)296   public void fireSelectedEvent(SelectionEvent se)
297           throws javax.xml.transform.TransformerException
298   {
299 
300     if (hasTraceListeners())
301     {
302       int nListeners = m_traceListeners.size();
303 
304       for (int i = 0; i < nListeners; i++)
305       {
306         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
307 
308         tl.selected(se);
309       }
310     }
311   }
312 
313 
314   /**
315    * Fire an end extension event.
316    *
317    * @see java.lang.reflect.Method#invoke
318    *
319    * @param method The java method about to be executed
320    * @param instance The instance the method will be executed on
321    * @param arguments Parameters passed to the method.
322    */
fireExtensionEndEvent(Method method, Object instance, Object[] arguments)323   public void fireExtensionEndEvent(Method method, Object instance, Object[] arguments)
324   {
325       ExtensionEvent ee = new ExtensionEvent(m_transformer, method, instance, arguments);
326 
327     if (hasTraceListeners())
328     {
329       int nListeners = m_traceListeners.size();
330 
331       for (int i = 0; i < nListeners; i++)
332       {
333         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
334         if(tl instanceof TraceListenerEx3)
335         {
336           ((TraceListenerEx3)tl).extensionEnd(ee);
337         }
338       }
339     }
340   }
341 
342   /**
343    * Fire an end extension event.
344    *
345    * @see java.lang.reflect.Method#invoke
346    *
347    * @param method The java method about to be executed
348    * @param instance The instance the method will be executed on
349    * @param arguments Parameters passed to the method.
350    */
fireExtensionEvent(Method method, Object instance, Object[] arguments)351   public void fireExtensionEvent(Method method, Object instance, Object[] arguments)
352   {
353     ExtensionEvent ee = new ExtensionEvent(m_transformer, method, instance, arguments);
354 
355     if (hasTraceListeners())
356     {
357       int nListeners = m_traceListeners.size();
358 
359       for (int i = 0; i < nListeners; i++)
360       {
361         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
362         if(tl instanceof TraceListenerEx3)
363         {
364           ((TraceListenerEx3)tl).extension(ee);
365         }
366       }
367     }
368   }
369 
370   /**
371    * Fire an end extension event.
372    *
373    * @see java.lang.reflect.Method#invoke
374    *
375    * @param ee the ExtensionEvent to fire
376    */
fireExtensionEndEvent(ExtensionEvent ee)377   public void fireExtensionEndEvent(ExtensionEvent ee)
378   {
379     if (hasTraceListeners())
380     {
381       int nListeners = m_traceListeners.size();
382 
383       for (int i = 0; i < nListeners; i++)
384       {
385         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
386         if(tl instanceof TraceListenerEx3)
387         {
388           ((TraceListenerEx3)tl).extensionEnd(ee);
389         }
390       }
391     }
392   }
393 
394   /**
395    * Fire an end extension event.
396    *
397    * @see java.lang.reflect.Method#invoke
398    *
399    * @param ee the ExtensionEvent to fire
400    */
fireExtensionEvent(ExtensionEvent ee)401   public void fireExtensionEvent(ExtensionEvent ee)
402   {
403 
404     if (hasTraceListeners())
405     {
406       int nListeners = m_traceListeners.size();
407 
408       for (int i = 0; i < nListeners; i++)
409       {
410         TraceListener tl = (TraceListener) m_traceListeners.elementAt(i);
411         if(tl instanceof TraceListenerEx3)
412         {
413           ((TraceListenerEx3)tl).extension(ee);
414         }
415       }
416     }
417   }
418 
419   /**
420    * Get the DOM Node of the current XPath context, which is possibly null.
421    * @param sourceNode the handle on the node used by a DTM.
422    */
getDOMNodeFromDTM(int sourceNode)423   private Node getDOMNodeFromDTM(int sourceNode) {
424     org.apache.xml.dtm.DTM dtm = m_transformer.getXPathContext().getDTM(sourceNode);
425     final Node source = (dtm == null) ? null : dtm.getNode(sourceNode);
426     return source;
427   }
428 }
429