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 ; 12 import java.util.Iterator ; 13 14 19 20 public abstract class AbstractTraceListener implements TraceListener { 21 private int indent = 0; 22 private NamePool pool; 23 private PrintStream out = System.err; 24 private static StringBuffer spaceBuffer = new StringBuffer (" "); 25 26 29 30 public void open() { 31 out.println("<trace " + 32 "saxon-version=\"" + Version.getProductVersion()+ "\" " + 33 getOpeningAttributes() + '>'); 34 indent++; 35 } 36 37 protected abstract String getOpeningAttributes(); 38 39 42 43 public void close() { 44 indent--; 45 out.println("</trace>"); 46 } 47 48 51 52 public void enter(InstructionInfo info, XPathContext context) { 53 int infotype = info.getConstructType(); 54 int objectNameCode = info.getObjectNameCode(); 55 String tag = tag(infotype); 56 if (tag==null) { 57 return; 59 } 60 String file = AbstractTraceListener.truncateURI(info.getSystemId()); 61 pool = context.getController().getNamePool(); 62 String msg = AbstractTraceListener.spaces(indent) + '<' + tag; 63 String name = (String )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 props = info.getProperties(); 70 while (props.hasNext()) { 71 String prop = (String )props.next(); 72 Object val = info.getProperty(prop); 73 if (prop.startsWith("{")) { 74 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 102 103 public String escape(String in) { 104 if (in==null) { 105 return ""; 106 } 107 CharSequence collapsed = Value.collapseWhitespace(in); 108 StringBuffer sb = new StringBuffer (collapsed.length() + 10); 109 for (int i=0; i<collapsed.length(); i++) { 110 char c = collapsed.charAt(i); 111 if (c=='<') { 112 sb.append("<"); 113 } else if (c=='>') { 114 sb.append(">"); 115 } else if (c=='&') { 116 sb.append("&"); 117 } else if (c=='\"') { 118 sb.append("""); 119 } else if (c=='\n') { 120 sb.append("
"); 121 } else if (c=='\r') { 122 sb.append("
"); 123 } else if (c=='\t') { 124 sb.append("	"); 125 } else { 126 sb.append(c); 127 } 128 } 129 return sb.toString(); 130 } 131 132 135 136 public void leave(InstructionInfo info) { 137 int infotype = info.getConstructType(); 138 String tag = tag(infotype); 139 if (tag==null) { 140 return; 142 } 143 indent--; 144 out.println(AbstractTraceListener.spaces(indent) + "</" + tag + '>'); 145 } 146 147 protected abstract String tag(int construct); 148 149 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 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 180 181 private static String truncateURI(String uri) { 182 String 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 198 199 private static String spaces(int n) { 200 while (spaceBuffer.length() < n) { 201 spaceBuffer.append(AbstractTraceListener.spaceBuffer); 202 } 203 return AbstractTraceListener.spaceBuffer.substring(0, n); 204 } 205 206 210 211 public void setOutputDestination(PrintStream stream) { 212 out = stream; 213 } 214 215 218 219 public PrintStream getOutputDestination() { 220 return out; 221 } 222 } 223 224 | Popular Tags |