001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixxml.util.xsltimpl;
021:
022: import java.io.IOException;
023: import java.io.Writer;
024: import java.util.HashMap;
025: import java.util.Map;
026:
027: import org.apache.log4j.Logger;
028:
029: import com.icl.saxon.Context;
030: import com.icl.saxon.Mode;
031: import com.icl.saxon.NodeHandler;
032: import com.icl.saxon.om.Navigator;
033: import com.icl.saxon.om.NodeInfo;
034: import com.icl.saxon.trace.TraceListener;
035:
036: /**
037: * @author mleidig@schlund.de
038: */
039: public class Saxon1TraceListener implements TraceListener {
040:
041: private final static Logger LOG = Logger
042: .getLogger(Saxon1TraceListener.class);
043:
044: public enum Format {
045: VERBOSE, COMPRESSED
046: };
047:
048: private final static String FORMATNAME = "SaxonTraceDump";
049: private final static String FORMATVERSION = "1";
050:
051: private Format format = Format.VERBOSE;
052: private Writer writer;
053: private Map<String, Integer> namePool = new HashMap<String, Integer>();
054: private String currentIndent = "";
055: private String indent = " ";
056:
057: public Saxon1TraceListener(Format format, Writer writer) {
058: this .format = format;
059: this .writer = writer;
060: }
061:
062: public void enter(NodeInfo node, Context context) {
063: //Format: callback|systemid|line|path|mode
064: try {
065: if (node.getNodeType() == NodeInfo.ELEMENT) {
066: if (format == Format.VERBOSE) {
067: writer.write(currentIndent);
068: writer.write("(");
069: writer.write(getShortSystemId(node) + "|");
070: writer.write(node.getLineNumber() + "|");
071: writer.write(Navigator.getPath(node) + "|");
072: String mode = getShortMode(context);
073: writer.write((mode == null ? "" : mode) + "|\n");
074: currentIndent += indent;
075: } else {
076: writer.write("(");
077: writer.write(getShortSystemId(node) + "|");
078: writer.write(node.getLineNumber() + "|");
079: writer.write(getShortPath(Navigator.getPath(node))
080: + "|");
081: String mode = getShortMode(context);
082: writer.write((mode == null ? "" : mode) + "|\n");
083: }
084: }
085: } catch (IOException x) {
086: LOG.error("Can't write trace.", x);
087: }
088: }
089:
090: public void leave(NodeInfo node, Context context) {
091: //Format: callback
092: try {
093: if (node.getNodeType() == NodeInfo.ELEMENT) {
094: if (format == Format.VERBOSE) {
095: currentIndent = currentIndent.substring(0,
096: currentIndent.length() - indent.length());
097: writer.write(currentIndent);
098: writer.write(")\n");
099: } else {
100: writer.write(")\n");
101: }
102: }
103: } catch (IOException x) {
104: LOG.error("Can't write trace.", x);
105: }
106: }
107:
108: public void enterSource(NodeHandler handler, Context context) {
109: //Format: callback|systemid|path|line|mode
110: try {
111: NodeInfo node = context.getContextNodeInfo();
112: if (format == Format.VERBOSE) {
113: writer.write(currentIndent);
114: writer.write("[");
115: writer.write(getShortSystemId(node) + "|");
116: writer.write(node.getLineNumber() + "|");
117: writer.write(Navigator.getPath(node) + "|");
118: String mode = getShortMode(context);
119: writer.write((mode == null ? "" : mode) + "|\n");
120: currentIndent += indent;
121: } else {
122: writer.write("[");
123: writer.write(getShortSystemId(node) + "|");
124: writer.write(node.getLineNumber() + "|");
125: writer.write(getShortPath(Navigator.getPath(node))
126: + "|");
127: String mode = getShortMode(context);
128: writer.write((mode == null ? "" : mode) + "|\n");
129: }
130: } catch (IOException x) {
131: LOG.error("Can't write trace.", x);
132: }
133: }
134:
135: public void leaveSource(NodeHandler handler, Context context) {
136: //Format: callback
137: try {
138: if (format == Format.VERBOSE) {
139: currentIndent = currentIndent.substring(0,
140: currentIndent.length() - indent.length());
141: writer.write(currentIndent);
142: writer.write("]\n");
143: } else {
144: writer.write("]\n");
145: }
146: } catch (IOException x) {
147: LOG.error("Can't write trace.", x);
148: }
149: }
150:
151: public void open() {
152: try {
153: writer.write(FORMATNAME + FORMATVERSION + "\n");
154: writer.write(format.toString() + "\n");
155: } catch (IOException x) {
156: LOG.error("Can't write trace.", x);
157: }
158: }
159:
160: public void close() {
161: if (format == Format.COMPRESSED)
162: serializePool();
163: try {
164: writer.close();
165: } catch (IOException x) {
166: LOG.error("Can't write trace.", x);
167: }
168: }
169:
170: public void toplevel(NodeInfo arg0) {
171: }
172:
173: private String getShortMode(Context context) {
174: String modeName = "";
175: Mode mode = context.getMode();
176: if (mode != null && mode.getNameCode() != -1) {
177: modeName = context.getController().getNamePool()
178: .getDisplayName(mode.getNameCode());
179: if (format == Format.COMPRESSED) {
180: Integer value = namePool.get(modeName);
181: if (value == null) {
182: value = namePool.size();
183: namePool.put(modeName, value);
184: }
185: modeName = value.toString();
186: }
187: }
188: return modeName;
189: }
190:
191: private String getShortPath(String path) {
192: StringBuilder sb = new StringBuilder();
193: String[] components = path.split("/");
194: for (String component : components) {
195: if (component.length() > 0) {
196: int ind = component.indexOf('[');
197: String name = component.substring(0, ind);
198: String pred = component.substring(ind);
199: Integer value = namePool.get(name);
200: if (value == null) {
201: value = namePool.size();
202: namePool.put(name, value);
203: }
204: sb.append("/" + value.toString() + pred);
205: }
206: }
207: return sb.toString();
208: }
209:
210: private String getShortSystemId(NodeInfo node) {
211: String systemId = node.getSystemId();
212: if (format == Format.VERBOSE) {
213: int ind = systemId.lastIndexOf('/');
214: if (ind > 0)
215: systemId = systemId.substring(ind + 1);
216: } else {
217: Integer value = namePool.get(systemId);
218: if (value == null) {
219: value = namePool.size();
220: namePool.put(systemId, value);
221: }
222: systemId = value.toString();
223: }
224: return systemId;
225: }
226:
227: private void serializePool() {
228: try {
229: for (String key : namePool.keySet()) {
230: Integer value = namePool.get(key);
231: writer.write(value.toString() + ":" + key + "\n");
232: }
233: } catch (IOException x) {
234: LOG.error("Can't write trace.", x);
235: }
236: }
237:
238: }
|