KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > util > ExceptionMapper


1 /* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24 package org.aspectj.util;
25
26 import java.io.File JavaDoc;
27 import java.io.IOException JavaDoc;
28 import java.io.PrintStream JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30 import java.io.StringWriter JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.StringTokenizer JavaDoc;
34
35 import org.aspectj.tools.ide.SymbolManager;
36 import org.aspectj.tools.ide.Declaration;
37 import org.aspectj.tools.ide.SourceLine;
38
39 /**
40  * A class to map <code>java.lang.Throwable</code> stack traces.
41  * <p>
42  * The methods offered are:
43  * <tr>
44  * <p><th><code>org.aspectj.util.ExceptionMapper#printStackTrace(Throwable)</code></th>
45  * <p><th><code>org.aspectj.util.ExceptionMapper#printStackTrace(Throwable,java.io.PrintStream)</code></th>
46  * <p><th><code>org.aspectj.util.ExceptionMapper#printStackTrace(Throwable,java.io.PrintWriter)</code></th>
47  * </tr>
48  * <p>
49  * These methods mimic those found in <code>java.lang.Throwable</code>:
50  * <tr>
51  * <p><th><code>java.lang.Throwable#printStackTrace()</code></th>
52  * <p><th><code>java.lang.Throwable#printStackTrace(java.io.PrintStream)</code></th>
53  * <p><th><code>java.lang.Throwable#printStackTrace(java.io.PrintWriter)</code></th>
54  * </tr>
55  *
56  * @see java.lang.Throwable
57  * @author <a HREF="mailto:palm@parc.xerox.com"Jeffrey Palm</a>
58  */

59 public class ExceptionMapper {
60
61     /** The <code>org.aspectj.tools.ide.SymbolManager</code> with which to map. */
62     private SymbolManager sm;
63
64     /** The <code>java.io.File</code> to use as the source path. */
65     private File JavaDoc sourcepath;
66
67     /** The <code>java.io.File</code> to use as the workingdir. */
68     private File JavaDoc workingdir;
69
70     /**
71      * Constructs a new mapper from the <code>sourcepath</code>.
72      * This ctor is private because as it stands SymbolManager sucks and
73      * we have to take steps to ensure that <code>sourcepath.getAbsolutPath()</code>
74      * returns something we can use with <code>SymbolManager</code>.
75      *
76      * @param sourcepath the java.io.File to use as <code>sourcepath</code>.
77      */

78     private ExceptionMapper(File JavaDoc sourcepath) {
79         this.sourcepath = sourcepath;
80         workingdir = new File JavaDoc(sourcepath, "ajworkingdir");
81         sm = SymbolManager.getSymbolManager();
82     }
83
84     /**
85      * Constructs a new mapper by taking the (possibly relative) <code>sourcepath</code>.
86      *
87      * @param sourcepath (possibly relative) path to source.
88      */

89     public ExceptionMapper(String JavaDoc sourcepath) {
90         this(validate(sourcepath));
91     }
92
93     /**
94      * Constructs a new mapper using the current directory for the source path.
95      */

96     public ExceptionMapper() {
97         this(".");
98     }
99
100     /**
101      * Maps the stack trace of <code>t</code>.
102      *
103      * @param t the <code>java.lang.Throwable</code> whose stack trace is mapped.
104      * @see java.lang.Throwable#printStackTrace()
105      */

106     public void printStackTrace(Throwable JavaDoc t) {
107         System.err.println(map(t));
108     }
109
110     /**
111      * Maps the stack trace of <code>t</code> onto <code>out</code>.
112      *
113      * @param t the <code>java.lang.Throwable</code> whose stack trace is mapped.
114      * @param out the <code>java.io.PrintStream</code> to which <code>t</code>'s stack
115      * will be put.
116      * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
117      */

118     public void printStackTrace(Throwable JavaDoc t,PrintStream JavaDoc out) {
119         out.println(map(t));
120     }
121
122     /* Maps the stack trace of <code>t</code> onto <code>out</code>.
123      *
124      * @param t the <code>java.lang.Throwable</code> whose stack trace is mapped.
125      * @param out the <code>java.io.PrintWriter</code> to which <code>t</code>'s stack
126      * will be put.
127      * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
128      */

129     public void printStackTrace(Throwable JavaDoc t, PrintWriter JavaDoc out) {
130         out.println(map(t));
131     }
132
133     private static File JavaDoc validate(String JavaDoc fileName) {
134         String JavaDoc path;
135         try {
136             path = new File JavaDoc(fileName).getCanonicalPath();
137         } catch (IOException JavaDoc ioe) {
138             path = new File JavaDoc(fileName).getAbsolutePath();
139         }
140         while (!Character.isLetterOrDigit(path.charAt(path.length()-1))) {
141             path = path.substring(0, path.length()-1);
142         }
143         return new File JavaDoc(path);
144     }
145
146     private String JavaDoc map(Throwable JavaDoc t) {
147         return map(collect(t));
148     }
149     
150     private String JavaDoc collect(Throwable JavaDoc t) {
151         StringWriter JavaDoc sout = new StringWriter JavaDoc();
152         PrintWriter JavaDoc out = new PrintWriter JavaDoc(sout);
153         t.printStackTrace(out);
154         return sout + "";
155     }
156     
157     private final static String JavaDoc newline = System.getProperty("line.separator");
158     private String JavaDoc map(String JavaDoc backtrace) {
159         String JavaDoc result = "";
160         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(backtrace, newline, false);
161         result += tok.nextToken() + newline;
162         while (tok.hasMoreTokens()) {
163             result += frame(tok.nextToken()) + newline;
164         }
165         return result;
166     }
167
168     private String JavaDoc frame(String JavaDoc frame) {
169         int i, iclass, ilastdot, ilparen, icolon, irparen;
170         char[] chars = frame.toCharArray();
171         for (i = 0; chars[i] != 'a'; i ++) {}
172         for (iclass = i; chars[iclass++] != ' '; ) {}
173         for (ilparen = iclass; chars[ilparen] != '('; ilparen ++) {}
174         for (ilastdot = ilparen; chars[ilastdot] != '.'; ilastdot--) {}
175         for (icolon = ilparen; chars[icolon] != ':'; icolon ++) {}
176         for (irparen = icolon; chars[irparen] != ')'; irparen ++) {}
177         return map(new String JavaDoc(chars, iclass, ilastdot-iclass),
178                    new String JavaDoc(chars, ilastdot+1, ilparen-ilastdot-1),
179                    new String JavaDoc(chars, ilparen+1, icolon-ilparen-1),
180                    new String JavaDoc(chars, icolon+1, irparen-icolon-1));
181     }
182
183     private String JavaDoc map(String JavaDoc s0, String JavaDoc s1, String JavaDoc s2, String JavaDoc num) {
184         return map(s0, s1, s2, Integer.parseInt(num));
185     }
186
187     private String JavaDoc map(String JavaDoc className, String JavaDoc method, String JavaDoc source, int line) {
188         SourceLine sl = mapToSourceLine(className, line);
189         return sl != null
190             ? frame(className, method, strip(sl.filename), sl.line)
191             : frame(className, method, source, line);
192     }
193
194     private String JavaDoc strip(String JavaDoc filename) {
195         int isep = filename.lastIndexOf(File.separator);
196         return isep != -1 ? filename.substring(isep+1) : filename;
197     }
198     
199     private String JavaDoc frame(String JavaDoc className, String JavaDoc method, String JavaDoc source, int line) {
200         return "\tat " + className + "." + method + "(" + source + ":" + line + ")";
201     }
202
203     private Map JavaDoc classToFile = new HashMap JavaDoc();
204     private File JavaDoc fileForClass(String JavaDoc className) {
205         return (File JavaDoc) classToFile.get(className);
206     }
207     private File JavaDoc resolve(String JavaDoc className) {
208         File JavaDoc result = fileForClass(className);
209         if (result != null) return result;
210         String JavaDoc resolvedName = className.replace('.', '/');
211         int idollar = resolvedName.indexOf('$');
212         if (idollar != -1) {
213             resolvedName = resolvedName.substring(0, idollar);
214         }
215         result = new File JavaDoc(workingdir + File.separator + resolvedName + ".java");
216         classToFile.put(className, result);
217         return result;
218     }
219
220     private SourceLine mapToSourceLine(String JavaDoc className, int line) {
221         return sm.mapToSourceLine(resolve(className).getAbsolutePath(), line-1);
222     }
223 }
224
Popular Tags