KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > trace > AbstractTraceListener


1 package net.sf.saxon.trace;
2
3 import net.sf.saxon.Version;
4 import net.sf.saxon.value.Value;
5 import net.sf.saxon.expr.XPathContext;
6 import net.sf.saxon.om.Item;
7 import net.sf.saxon.om.NamePool;
8 import net.sf.saxon.om.Navigator;
9 import net.sf.saxon.om.NodeInfo;
10
11 import java.io.PrintStream JavaDoc;
12 import java.util.Iterator JavaDoc;
13
14 /**
15  * This is the standard trace listener used when the -T option is specified on the command line.
16  * There are two variants, represented by subclasses: one for XSLT, and one for XQuery. The two variants
17  * differ in that they present the trace output in terms of constructs used in the relevant host language.
18  */

19
20 public abstract class AbstractTraceListener implements TraceListener {
21     private int indent = 0;
22     private NamePool pool;
23     private PrintStream JavaDoc out = System.err;
24     private static StringBuffer JavaDoc spaceBuffer = new StringBuffer JavaDoc(" ");
25
26     /**
27      * Called at start
28      */

29
30     public void open() {
31         out.println("<trace " +
32                 "saxon-version=\"" + Version.getProductVersion()+ "\" " +
33                 getOpeningAttributes() + '>');
34         indent++;
35     }
36
37     protected abstract String JavaDoc getOpeningAttributes();
38
39     /**
40      * Called at end
41      */

42
43     public void close() {
44         indent--;
45         out.println("</trace>");
46     }
47
48     /**
49      * Called when an instruction in the stylesheet gets processed
50      */

51
52     public void enter(InstructionInfo info, XPathContext context) {
53         int infotype = info.getConstructType();
54         int objectNameCode = info.getObjectNameCode();
55         String JavaDoc tag = tag(infotype);
56         if (tag==null) {
57             // this TraceListener ignores some events to reduce the volume of output
58
return;
59         }
60         String JavaDoc file = AbstractTraceListener.truncateURI(info.getSystemId());
61         pool = context.getController().getNamePool();
62         String JavaDoc msg = AbstractTraceListener.spaces(indent) + '<' + tag;
63         String JavaDoc name = (String JavaDoc)info.getProperty("name");
64         if (name!=null) {
65             msg += " name=\"" + escape(name) + '"';
66         } else if (objectNameCode != -1) {
67             msg += " name=\"" + escape(pool.getDisplayName(objectNameCode)) + '"';
68         }
69         Iterator JavaDoc props = info.getProperties();
70         while (props.hasNext()) {
71             String JavaDoc prop = (String JavaDoc)props.next();
72             Object JavaDoc val = info.getProperty(prop);
73             if (prop.startsWith("{")) {
74                 // It's a QName in Clark notation: we'll strip off the namespace
75
int rcurly = prop.indexOf('}');
76                 if (rcurly > 0) {
77                     prop = prop.substring(rcurly+1);
78                 }
79             }
80             if (val != null && !prop.equals("name") && !prop.equals("expression")) {
81                 msg += ' ' + prop + "=\"" + escape(val.toString()) + '"';
82             }
83         }
84
85         msg += " line=\"" + info.getLineNumber() + '"';
86
87         int col = info.getColumnNumber();
88         if (col >= 0) {
89             msg += " column=\"" + info.getColumnNumber() + '"';
90         }
91
92         msg += " module=\"" + escape(file) + "\">";
93         out.println(msg);
94         indent++;
95     }
96
97     /**
98      * Escape a string for XML output (in an attribute delimited by double quotes).
99      * This method also collapses whitespace (since the value may be an XPath expression that
100      * was originally written over several lines).
101      */

102
103     public String JavaDoc escape(String JavaDoc in) {
104         if (in==null) {
105             return "";
106         }
107         CharSequence JavaDoc collapsed = Value.collapseWhitespace(in);
108         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(collapsed.length() + 10);
109         for (int i=0; i<collapsed.length(); i++) {
110             char c = collapsed.charAt(i);
111             if (c=='<') {
112                 sb.append("&lt;");
113             } else if (c=='>') {
114                 sb.append("&gt;");
115             } else if (c=='&') {
116                 sb.append("&amp;");
117             } else if (c=='\"') {
118                 sb.append("&#34;");
119             } else if (c=='\n') {
120                 sb.append("&#xA;");
121             } else if (c=='\r') {
122                 sb.append("&#xD;");
123             } else if (c=='\t') {
124                 sb.append("&#x9;");
125             } else {
126                 sb.append(c);
127             }
128         }
129         return sb.toString();
130     }
131
132     /**
133      * Called after an instruction of the stylesheet got processed
134      */

135
136     public void leave(InstructionInfo info) {
137         int infotype = info.getConstructType();
138         String JavaDoc tag = tag(infotype);
139         if (tag==null) {
140             // this TraceListener ignores some events to reduce the volume of output
141
return;
142         }
143         indent--;
144         out.println(AbstractTraceListener.spaces(indent) + "</" + tag + '>');
145     }
146
147     protected abstract String JavaDoc tag(int construct);
148
149     /**
150     * Called when an item becomes the context item
151     */

152
153    public void startCurrentItem(Item item) {
154        if (item instanceof NodeInfo) {
155            NodeInfo curr = (NodeInfo) item;
156            out.println(AbstractTraceListener.spaces(indent) + "<source node=\"" + Navigator.getPath(curr)
157                    + "\" line=\"" + curr.getLineNumber()
158                    + "\" file=\"" + AbstractTraceListener.truncateURI(curr.getSystemId())
159                    + "\">");
160        }
161        indent++;
162    }
163
164     /**
165      * Called after a node of the source tree got processed
166      */

167
168     public void endCurrentItem(Item item) {
169         indent--;
170         if (item instanceof NodeInfo) {
171             NodeInfo curr = (NodeInfo) item;
172             out.println(AbstractTraceListener.spaces(indent) + "</source><!-- " +
173                     Navigator.getPath(curr) + " -->");
174         }
175     }
176
177     /**
178      * Truncate a URI to its last component
179      */

180
181     private static String JavaDoc truncateURI(String JavaDoc uri) {
182         String JavaDoc file = uri;
183         if (file == null) file = "";
184         while (true) {
185             int i = file.indexOf('/');
186             if (i >= 0 && i < file.length() - 6) {
187                 file = file.substring(i + 1);
188             } else {
189                 break;
190             }
191         }
192         return file;
193     }
194
195     /**
196      * Get n spaces
197      */

198
199     private static String JavaDoc spaces(int n) {
200         while (spaceBuffer.length() < n) {
201             spaceBuffer.append(AbstractTraceListener.spaceBuffer);
202         }
203         return AbstractTraceListener.spaceBuffer.substring(0, n);
204     }
205
206     /**
207      * Set the output destination (default is System.err)
208      * @param stream the output destination for tracing output
209      */

210
211     public void setOutputDestination(PrintStream JavaDoc stream) {
212         out = stream;
213     }
214
215     /**
216      * Get the output destination
217      */

218
219     public PrintStream JavaDoc getOutputDestination() {
220         return out;
221     }
222 }
223
224 //
225
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
226
// you may not use this file except in compliance with the License. You may obtain a copy of the
227
// License at http://www.mozilla.org/MPL/
228
//
229
// Software distributed under the License is distributed on an "AS IS" basis,
230
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
231
// See the License for the specific language governing rights and limitations under the License.
232
//
233
// The Original Code is: all this file.
234
//
235
// The Initial Developer of the Original Code is Michael H. Kay
236
//
237
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
238
//
239
// Contributor(s): none
240
//
Popular Tags