1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.trace;
  58. import java.io.*;
  59. import org.w3c.dom.*;
  60. import org.w3c.dom.traversal.NodeIterator;
  61. import org.apache.xalan.templates.ElemTemplate;
  62. import org.apache.xalan.templates.ElemTemplateElement;
  63. import org.apache.xalan.templates.ElemTextLiteral;
  64. import org.apache.xalan.templates.Constants;
  65. import org.apache.xpath.axes.ContextNodeList;
  66. import javax.xml.transform.SourceLocator;
  67. import org.apache.xml.dtm.DTM;
  68. import org.apache.xml.dtm.ref.DTMNodeProxy;
  69. /**
  70. * <meta name="usage" content="advanced"/>
  71. * Implementation of the TraceListener interface that
  72. * prints each event to standard out as it occurs.
  73. *
  74. * @see org.apache.xalan.trace.TracerEvent
  75. */
  76. public class PrintTraceListener implements TraceListenerEx2
  77. {
  78. /**
  79. * Construct a trace listener.
  80. *
  81. * @param pw PrintWriter to use for tracing events
  82. */
  83. public PrintTraceListener(java.io.PrintWriter pw)
  84. {
  85. m_pw = pw;
  86. }
  87. /**
  88. * The print writer where the events should be written.
  89. */
  90. java.io.PrintWriter m_pw;
  91. /**
  92. * This needs to be set to true if the listener is to print an event whenever a template is invoked.
  93. */
  94. public boolean m_traceTemplates = false;
  95. /**
  96. * Set to true if the listener is to print events that occur as each node is 'executed' in the stylesheet.
  97. */
  98. public boolean m_traceElements = false;
  99. /**
  100. * Set to true if the listener is to print information after each result-tree generation event.
  101. */
  102. public boolean m_traceGeneration = false;
  103. /**
  104. * Set to true if the listener is to print information after each selection event.
  105. */
  106. public boolean m_traceSelection = false;
  107. /**
  108. * Print information about a TracerEvent.
  109. *
  110. * @param ev the trace event.
  111. */
  112. public void _trace(TracerEvent ev)
  113. {
  114. switch (ev.m_styleNode.getXSLToken())
  115. {
  116. case Constants.ELEMNAME_TEXTLITERALRESULT :
  117. if (m_traceElements)
  118. {
  119. m_pw.print(ev.m_styleNode.getSystemId()+ " Line #" + ev.m_styleNode.getLineNumber() + ", "
  120. + "Column #" + ev.m_styleNode.getColumnNumber() + " -- "
  121. + ev.m_styleNode.getNodeName() + ": ");
  122. ElemTextLiteral etl = (ElemTextLiteral) ev.m_styleNode;
  123. String chars = new String(etl.getChars(), 0, etl.getChars().length);
  124. m_pw.println(" " + chars.trim());
  125. }
  126. break;
  127. case Constants.ELEMNAME_TEMPLATE :
  128. if (m_traceTemplates || m_traceElements)
  129. {
  130. ElemTemplate et = (ElemTemplate) ev.m_styleNode;
  131. m_pw.print(et.getSystemId()+ " Line #" + et.getLineNumber() + ", " + "Column #"
  132. + et.getColumnNumber() + ": " + et.getNodeName() + " ");
  133. if (null != et.getMatch())
  134. {
  135. m_pw.print("match='" + et.getMatch().getPatternString() + "' ");
  136. }
  137. if (null != et.getName())
  138. {
  139. m_pw.print("name='" + et.getName() + "' ");
  140. }
  141. m_pw.println();
  142. }
  143. break;
  144. default :
  145. if (m_traceElements)
  146. {
  147. m_pw.println(ev.m_styleNode.getSystemId()+ " Line #" + ev.m_styleNode.getLineNumber() + ", "
  148. + "Column #" + ev.m_styleNode.getColumnNumber() + ": "
  149. + ev.m_styleNode.getNodeName());
  150. }
  151. }
  152. }
  153. int m_indent = 0;
  154. /**
  155. * Print information about a TracerEvent.
  156. *
  157. * @param ev the trace event.
  158. */
  159. public void trace(TracerEvent ev)
  160. {
  161. // m_traceElements = true;
  162. // m_traceTemplates = true;
  163. //
  164. // for(int i = 0; i < m_indent; i++)
  165. // m_pw.print(" ");
  166. // m_indent = m_indent+2;
  167. // m_pw.print("trace: ");
  168. _trace(ev);
  169. }
  170. /**
  171. * Method that is called when the end of a trace event occurs.
  172. * The method is blocking. It must return before processing continues.
  173. *
  174. * @param ev the trace event.
  175. */
  176. public void traceEnd(TracerEvent ev)
  177. {
  178. // m_traceElements = true;
  179. // m_traceTemplates = true;
  180. //
  181. // m_indent = m_indent-2;
  182. // for(int i = 0; i < m_indent; i++)
  183. // m_pw.print(" ");
  184. // m_pw.print("etrac: ");
  185. // _trace(ev);
  186. }
  187. /**
  188. * Method that is called just after a select attribute has been evaluated.
  189. *
  190. * @param ev the generate event.
  191. *
  192. * @throws javax.xml.transform.TransformerException
  193. */
  194. public void selected(SelectionEvent ev) throws javax.xml.transform.TransformerException
  195. {
  196. if (m_traceSelection)
  197. {
  198. ElemTemplateElement ete = (ElemTemplateElement) ev.m_styleNode;
  199. Node sourceNode = ev.m_sourceNode;
  200. SourceLocator locator = null;
  201. if (sourceNode instanceof DTMNodeProxy)
  202. {
  203. int nodeHandler = ((DTMNodeProxy)sourceNode).getDTMNodeNumber();
  204. locator = ((DTMNodeProxy)sourceNode).getDTM().getSourceLocatorFor(nodeHandler);
  205. }
  206. if (locator != null)
  207. m_pw.println("Selected source node '" + sourceNode.getNodeName()
  208. + "', at " + locator);
  209. else
  210. m_pw.println("Selected source node '" + sourceNode.getNodeName() +"'");
  211. if (ev.m_styleNode.getLineNumber() == 0)
  212. {
  213. // You may not have line numbers if the selection is occuring from a
  214. // default template.
  215. ElemTemplateElement parent =
  216. (ElemTemplateElement) ete.getParentElem();
  217. if (parent == ete.getStylesheetRoot().getDefaultRootRule())
  218. {
  219. m_pw.print("(default root rule) ");
  220. }
  221. else if (parent == ete.getStylesheetRoot().getDefaultTextRule())
  222. {
  223. m_pw.print("(default text rule) ");
  224. }
  225. else if (parent == ete.getStylesheetRoot().getDefaultRule())
  226. {
  227. m_pw.print("(default rule) ");
  228. }
  229. m_pw.print(ete.getNodeName() + ", " + ev.m_attributeName + "='"
  230. + ev.m_xpath.getPatternString() + "': ");
  231. }
  232. else
  233. {
  234. m_pw.print(ev.m_styleNode.getSystemId()+ " Line #" + ev.m_styleNode.getLineNumber() + ", "
  235. + "Column #" + ev.m_styleNode.getColumnNumber() + ": "
  236. + ete.getNodeName() + ", " + ev.m_attributeName + "='"
  237. + ev.m_xpath.getPatternString() + "': ");
  238. }
  239. if (ev.m_selection.getType() == ev.m_selection.CLASS_NODESET)
  240. {
  241. m_pw.println();
  242. org.apache.xml.dtm.DTMIterator nl = ev.m_selection.iter();
  243. try
  244. {
  245. nl = nl.cloneWithReset();
  246. }
  247. catch(CloneNotSupportedException cnse)
  248. {
  249. m_pw.println(" [Can't trace nodelist because it it threw a CloneNotSupportedException]");
  250. return;
  251. }
  252. int pos = nl.nextNode();
  253. if (DTM.NULL == pos)
  254. {
  255. m_pw.println(" [empty node list]");
  256. }
  257. else
  258. {
  259. while (DTM.NULL != pos)
  260. {
  261. // m_pw.println(" " + ev.m_processor.getXPathContext().getDTM(pos).getNode(pos));
  262. DTM dtm = ev.m_processor.getXPathContext().getDTM(pos);
  263. m_pw.print(" ");
  264. m_pw.print(Integer.toHexString(pos));
  265. m_pw.print(": ");
  266. m_pw.println(dtm.getNodeName(pos));
  267. pos = nl.nextNode();
  268. }
  269. }
  270. }
  271. else
  272. {
  273. m_pw.println(ev.m_selection.str());
  274. }
  275. }
  276. }
  277. /**
  278. * Method that is called after an xsl:apply-templates or xsl:for-each
  279. * selection occurs.
  280. *
  281. * @param ev the generate event.
  282. *
  283. * @throws javax.xml.transform.TransformerException
  284. */
  285. public void selectEnd(EndSelectionEvent ev)
  286. throws javax.xml.transform.TransformerException
  287. {
  288. // Nothing for right now.
  289. }
  290. /**
  291. * Print information about a Generate event.
  292. *
  293. * @param ev the trace event.
  294. */
  295. public void generated(GenerateEvent ev)
  296. {
  297. if (m_traceGeneration)
  298. {
  299. switch (ev.m_eventtype)
  300. {
  301. case GenerateEvent.EVENTTYPE_STARTDOCUMENT :
  302. m_pw.println("STARTDOCUMENT");
  303. break;
  304. case GenerateEvent.EVENTTYPE_ENDDOCUMENT :
  305. m_pw.println("ENDDOCUMENT");
  306. break;
  307. case GenerateEvent.EVENTTYPE_STARTELEMENT :
  308. m_pw.println("STARTELEMENT: " + ev.m_name);
  309. break;
  310. case GenerateEvent.EVENTTYPE_ENDELEMENT :
  311. m_pw.println("ENDELEMENT: " + ev.m_name);
  312. break;
  313. case GenerateEvent.EVENTTYPE_CHARACTERS :
  314. {
  315. String chars = new String(ev.m_characters, ev.m_start, ev.m_length);
  316. m_pw.println("CHARACTERS: " + chars);
  317. }
  318. break;
  319. case GenerateEvent.EVENTTYPE_CDATA :
  320. {
  321. String chars = new String(ev.m_characters, ev.m_start, ev.m_length);
  322. m_pw.println("CDATA: " + chars);
  323. }
  324. break;
  325. case GenerateEvent.EVENTTYPE_COMMENT :
  326. m_pw.println("COMMENT: " + ev.m_data);
  327. break;
  328. case GenerateEvent.EVENTTYPE_PI :
  329. m_pw.println("PI: " + ev.m_name + ", " + ev.m_data);
  330. break;
  331. case GenerateEvent.EVENTTYPE_ENTITYREF :
  332. m_pw.println("ENTITYREF: " + ev.m_name);
  333. break;
  334. case GenerateEvent.EVENTTYPE_IGNORABLEWHITESPACE :
  335. m_pw.println("IGNORABLEWHITESPACE");
  336. break;
  337. }
  338. }
  339. }
  340. }