Source code: com/jplanet/xsldb/Xsldb.java
1 /*
2 * (c) Copyright 2002 Christian Gehrke
3 * All Rights Reserved.
4 */
5 package com.jplanet.xsldb;
6
7 import javax.xml.transform.TransformerException;
8 import org.apache.xalan.templates.Constants;
9 import org.apache.xalan.templates.ElemTextLiteral;
10 import org.apache.xalan.trace.EndSelectionEvent;
11 import org.apache.xalan.trace.GenerateEvent;
12 import org.apache.xalan.trace.SelectionEvent;
13 import org.apache.xalan.trace.TraceListenerEx;
14 import org.apache.xalan.trace.TracerEvent;
15
16 import org.w3c.dom.Node;
17 import org.apache.xml.dtm.DTMIterator;
18 import org.apache.xml.dtm.DTM;
19 import org.apache.xpath.objects.XObject;
20 import org.apache.xalan.templates.ElemTemplate;
21 import org.apache.xalan.templates.ElemTemplateElement;
22 import org.apache.xalan.templates.ElemVariable;
23 import org.apache.xalan.templates.ElemValueOf;
24
25 import com.jplanet.xsldb.*;
26
27
28 /**
29 * @version 1.0
30 * @author Chris Gehrke
31 * @see org.apache.xalan.trace.TraceListenerEx
32 */
33 public class Xsldb implements TraceListenerEx {
34
35
36 public Xsldb() {
37 super();
38
39 initDecision = DecisionMaker.DO_IT_AGAIN;
40
41 while(initDecision == DecisionMaker.DO_IT_AGAIN) {
42
43 String in = IOIndiv.readln();
44 // During the initialization phase the DecisionMaker
45 // determines how to handle the user commands resp.
46 // calculates if the debugger should fall into the
47 // interactive mode.
48 initDecision = decMaker.init(in);
49 }
50
51 if(initDecision == DecisionMaker.EXIT_AT_ONCE)
52 System.exit(0);
53 }
54
55
56
57 /**
58 * This is a callback method.
59 * It is called before an XPath expression is executed (and before the 'selected' method).
60 * @see TraceListenerEx#trace(TracerEvent)
61 * @see TraceListenerEx#selected(SelectionEvent)
62 * @see TraceListenerEx#generated(GenerateEvent).
63 */
64 public void trace(TracerEvent te) {
65
66 if(!trace)
67 return;
68
69 try {
70
71
72 // The DecisionMaker rules.
73 int dec = decMaker.decide(te);
74
75 // Maybe we don't want to write output to the console.
76 if(dec == DecisionMaker.EXIT_AT_ONCE)
77 return;
78
79 if(dec == DecisionMaker.DO_PROMPT) {
80
81 String in = IOIndiv.readln();
82 dec = decMaker.decide(in);
83 }
84
85 // Maybe we don't want to write output to the console.
86 if(dec == DecisionMaker.EXIT_AT_ONCE)
87 return;
88
89 if(!display_variable && "variable".equalsIgnoreCase(ParaBean.getNodeName(te)))
90 return;
91
92 if(initDecision == DecisionMaker.INSPECT_VALUE_OF && !"value-of".equalsIgnoreCase(ParaBean.getNodeName(te)))
93 return;
94
95 if(!display_valueof && "value-of".equalsIgnoreCase(ParaBean.getNodeName(te)))
96 return;
97
98 if((!"value-of".equalsIgnoreCase(ParaBean.getNodeName(te))) && dec == DecisionMaker.INSPECT_VALUE_OF)
99 return;
100
101
102
103 ElemTemplateElement ete = ParaBean.getStyleNode(te);
104
105 switch (ParaBean.getXSLToken(te)) {
106
107 case Constants.ELEMNAME_TEXTLITERALRESULT:
108 IOIndiv.print ("trace [TEXTLITERALRESULT " + ParaBean.getLineNumber(te) + ", " + ParaBean.getColumnNumber(te) + "] ");
109 IOIndiv.print (ParaBean.getNodeName(te) + ": ");
110 ElemTextLiteral etl = (ElemTextLiteral)te.m_styleNode;
111 String chars = new String(etl.getChars(), 0, etl.getChars().length);
112 break;
113 case Constants.ELEMNAME_TEMPLATE:
114
115 IOIndiv.print ("trace [TEMPLATE " + ParaBean.getLineNumber(te) + ", " + ParaBean.getColumnNumber(te) + "] ");
116 IOIndiv.print (ete.getNodeName() + " ");
117
118 ElemTemplate et = (ElemTemplate)ete;
119 if(null != et.getMatch()) {
120
121 IOIndiv.print ("match='" + et.getMatch().getPatternString() + "' ");
122 }
123 if(null != et.getName()) {
124
125 IOIndiv.print ("name='" + et.getName() + "' ");
126 }
127 IOIndiv.println("");
128 break;
129 case Constants.ELEMNAME_VARIABLE: {
130
131 IOIndiv.print ("trace [VARIABLE " + ParaBean.getLineNumber(te) + ", " + ParaBean.getColumnNumber(te) + "] ");
132 ElemVariable ev = (ElemVariable)ete;
133 IOIndiv.print ( ete.getNodeName() + " " + ev.getName().getLocalName() + " = " + ev.getSelect().getPatternString());
134 IOIndiv.println("");
135 } break;
136
137 case Constants.ELEMNAME_VALUEOF: {
138
139 IOIndiv.print ("trace [VALUEOF " + ParaBean.getLineNumber(te) + ", " + ParaBean.getColumnNumber(te) + "] ");
140 ElemValueOf ev = (ElemValueOf)ete;
141 IOIndiv.print ( ete.getNodeName() + " " + ev.getSelect().getPatternString());
142 IOIndiv.println("");
143 } break;
144 default:
145
146 IOIndiv.print ("trace [DEFAULT " + ParaBean.getLineNumber(te) + ", " + ParaBean.getColumnNumber(te) + "] ");
147 IOIndiv.println(ParaBean.getNodeName(te));
148 //IOIndiv.println("XPATH[???, " + ParaBean.getLineNumber(te) +", " + ParaBean.getColumnNumber(te) + "]: " + ParaBean.getPatternString(te));
149 }
150
151 } catch (Exception ex) {
152
153 System.out.println("unexpected Exception in TRACE");
154 }
155 }
156
157
158
159
160
161 /**
162 * This method is called after execution of the selectionAttribute
163 * (and always after the trace method).
164 * @see TraceListenerEx#selected(SelectionEvent)
165 * @see TraceListenerEx#trace(TracerEvent)
166 * @see TraceListenerEx#generated(GenerateEvent).
167 */
168 public void selected(SelectionEvent se) throws TransformerException {
169
170 if (!selected)
171 return;
172
173 try {
174
175
176 // The DecisionMaker rules.
177 int dec = decMaker.decide(se);
178
179 // Maybe we don't want to write output to the console.
180 if(dec == DecisionMaker.EXIT_AT_ONCE)
181 return;
182
183 if(dec == DecisionMaker.DO_PROMPT) {
184
185 String in = IOIndiv.readln();
186 dec = decMaker.decide(in);
187 }
188
189 // Maybe we don't want to write output to the console.
190 if(dec == DecisionMaker.EXIT_AT_ONCE)
191 return;
192
193
194 /* if(dec == DecisionMaker.goOn)
195 return;*/
196
197
198 //if(dec != DecisionMaker.inspectEveryItem) {
199 if(!display_variable && "variable".equalsIgnoreCase(ParaBean.getNodeName(se)))
200 return;
201
202 //dec!=DecisionMaker.inspectValueOf)
203
204 if(initDecision == DecisionMaker.INSPECT_VALUE_OF && !"value-of".equalsIgnoreCase(ParaBean.getNodeName(se)))
205 return;
206
207 //if(dec != DecisionMaker.inspectValueOf)
208 if(!display_valueof && "value-of".equalsIgnoreCase(ParaBean.getNodeName(se)))
209 return;
210
211 if((!"value-of".equalsIgnoreCase(ParaBean.getNodeName(se))) && dec == DecisionMaker.INSPECT_VALUE_OF)
212 return;
213 //}
214
215
216 // Shows XPAth attribute (f.e. "select").
217 String attributeName = ParaBean.getAttributName(se);
218
219 //ElemTemplateElement ete = se.m_styleNode;
220 Node sourceNode = ParaBean.getSourceNode(se);
221
222 String pattern = ParaBean.getPatternString(se);
223
224 IOIndiv.print("selected [XPath" + attributeName + " " + ParaBean.getRow(se) + ", " + ParaBean.getCol(se) + "]: " + pattern);
225 //println(" NodeName: " + sourceNode.getNodeName());
226 IOIndiv.print(" => [" + ParaBean.getTypeString(se) + "] ");
227
228
229 switch (se.m_selection.getType()) {
230
231 case XObject.CLASS_NODESET:
232
233 DTMIterator nl = ParaBean.getDTMIterator(se);
234 try {
235
236 nl = nl.cloneWithReset();
237
238 } catch (CloneNotSupportedException cnse) {
239
240 IOIndiv.println("NodeSet not valid");
241 }
242 int pos = nl.nextNode();
243 if(DTM.NULL == pos) {
244
245 IOIndiv.println("Empty NodeSet");
246
247 } else {
248
249 /*while (DTM.NULL != pos) {
250
251 DTM dtm = ParaBean.getDTM(se, pos);
252 IOIndiv.println(" " + pos + ": " + dtm.getNodeName(pos));
253 pos = nl.nextNode();
254 }*/
255
256 // A NodeSet containing more than one single node should not be printed.
257 if( nl.getLength() == 1 ) {
258
259 // You can print the actual nodename here.
260
261 IOIndiv.print("Nodeset contains one single Node: ");
262 IOIndiv.println(ParaBean.str(se));
263
264 } else {
265
266 // You can print the nodenames of this nodeset here,
267
268 IOIndiv.println("Nodeset contains " + nl.getLength() + " nodes. No Output for this complex structure available");
269
270 }
271 }
272 break;
273
274 case XObject.CLASS_STRING:
275 case XObject.CLASS_BOOLEAN:
276 case XObject.CLASS_NUMBER:
277 case XObject.CLASS_NULL:
278 case XObject.CLASS_UNKNOWN:
279 case XObject.CLASS_RTREEFRAG:
280
281 IOIndiv.println(ParaBean.str(se));
282 break;
283 }
284 } catch (Exception ex) {
285
286 System.out.println("unexpected Exception in SELECTED");
287 }
288 }
289
290
291
292
293
294
295 /**
296 * This method is called back when something is written to the output stream.
297 * Lies in the calling back sequence behind the trace and selected methods.
298 * @see TraceListenerEx#generated(GenerateEvent)
299 * @see TraceListenerEx#trace(TracerEvent)
300 * @see TraceListenerEx#selected(SelectionEvent)
301 */
302 public void generated(GenerateEvent ge) {
303
304 if(!generated)
305 return;
306
307 try {
308
309 switch (ParaBean.getEventType(ge)) {
310
311 case GenerateEvent.EVENTTYPE_STARTDOCUMENT:
312 IOIndiv.println("generated [STARTDOCUMENT] --------------------------------");
313 break;
314 case GenerateEvent.EVENTTYPE_ENDDOCUMENT:
315 IOIndiv.println("generated [ENDDOCUMENT] --------------------------------");
316 break;
317 case GenerateEvent.EVENTTYPE_STARTELEMENT:
318 IOIndiv.println("generated [STARTELEMENT] " + ge.m_name);
319 break;
320 case GenerateEvent.EVENTTYPE_ENDELEMENT:
321 IOIndiv.println("generated [ENDELEMENT] " + ge.m_name);
322 break;
323 case GenerateEvent.EVENTTYPE_CHARACTERS: {
324 String chars = new String (ge.m_characters, ge.m_start, ge.m_length);
325 IOIndiv.println("generated [CHARACTERS] " + chars); }
326 break;
327 case GenerateEvent.EVENTTYPE_CDATA: {
328 String chars = new String (ge.m_characters, ge.m_start, ge.m_length);
329 IOIndiv.println("generated [CDATA] " + chars); }
330 break;
331 case GenerateEvent.EVENTTYPE_COMMENT:
332 IOIndiv.println("generated [COMMENT] " + ge.m_data);
333 break;
334 case GenerateEvent.EVENTTYPE_PI:
335 IOIndiv.println("generated [PI] " + ge.m_name + ", " + ge.m_data);
336 break;
337 case GenerateEvent.EVENTTYPE_ENTITYREF:
338 IOIndiv.println("generated ENTITYREF: " + ge.m_name);
339 break;
340 case GenerateEvent.EVENTTYPE_IGNORABLEWHITESPACE:
341 IOIndiv.println("generated [IGNORABLEWHITESPACE]");
342 break;
343 }
344
345 } catch (Exception ex) {
346
347 System.out.println("unexpected Exception in GENERATED");
348 }
349 }
350
351
352
353
354 /**
355 * Nothin to do here, uh?
356 * Seems we're not really using the extended class TraceListenerEx...
357 * @see TraceListenerEx#selectEnd(EndSelectionEvent)
358 */
359 public void selectEnd(EndSelectionEvent ese) throws TransformerException {}
360
361
362
363
364 // Public variables for controlling class behavior.
365 /**
366 * Show XSLT-Variable-Definitions. May be overwritten from outside.
367 * Beware to know what you're doing.
368 */
369 public boolean display_variable = true;
370 public boolean display_valueof = true;
371
372 /**
373 * This is for high level controlling.
374 * You can manipulate the state from outsite.
375 * If you know what your're doing.
376 */
377 public boolean trace = true;
378 public boolean selected = true;
379 public boolean generated = true;
380
381
382 DecisionMaker decMaker = new DecisionMaker ();
383
384 protected int initDecision;
385
386 }