KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > groboutils > util > throwable > v1 > StackTraceLineParser


1 /*
2  * @(#)StackTraceLineParser.java
3  *
4  * Copyright (C) 2002-2003 Matt Albrecht
5  * groboclown@users.sourceforge.net
6  * http://groboutils.sourceforge.net
7  *
8  * Part of the GroboUtils package at:
9  * http://groboutils.sourceforge.net
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  */

29 package net.sourceforge.groboutils.util.throwable.v1;
30
31
32 import java.lang.reflect.Method JavaDoc;
33
34 //import org.apache.log4j.Logger;
35

36
37 /**
38  * Encompasses the line on which a Stack Trace occurs. Should not call
39  * this "StackTraceElement", since that's a JDK 1.4 class in the java.lang
40  * package.
41  *
42  * @author Matt Albrecht <a HREF="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
43  * @since March 17, 2002
44  * @version $Date: 2003/09/29 21:10:36 $
45  */

46 public class StackTraceLineParser
47 {
48     //private static final Logger LOG = Logger.getLogger(
49
// StackTraceLineParser.class.getName() );
50

51     private String JavaDoc className;
52     private String JavaDoc methodName;
53     private int lineNumber;
54     
55     private static final String JavaDoc JDK14_STE_CLASS = "java.lang.StackTraceElement";
56     private static final String JavaDoc JDK14_STE_GCN = "getClassName";
57     private static final Class JavaDoc[] JDK14_STE_GCN_ARGS = new Class JavaDoc[0];
58     private static final String JavaDoc JDK14_STE_GLN = "getLineNumber";
59     private static final Class JavaDoc[] JDK14_STE_GLN_ARGS = new Class JavaDoc[0];
60     private static final String JavaDoc JDK14_STE_GMN = "getMethodName";
61     private static final Class JavaDoc[] JDK14_STE_GMN_ARGS = new Class JavaDoc[0];
62     
63     private static final String JavaDoc ST_START = "at ";
64     
65     
66     // Check if we are running in IBM's visual age.
67
// - it has a different stack trace
68
private static boolean IN_VISUAL_AGE = false;
69     static {
70         try
71         {
72             Class JavaDoc dummy = Class.forName("com.ibm.uvm.tools.DebugSupport");
73             IN_VISUAL_AGE = true;
74             //LOG.info("Using VisualAge style stack traces.");
75
}
76         catch (Throwable JavaDoc e)
77         {
78             // ignore. We're not in visual age.
79
//LOG.info("Using standard JDK style stack traces.");
80
}
81     }
82
83     
84     
85     public StackTraceLineParser( String JavaDoc className, String JavaDoc methodName )
86     {
87         this( className, methodName, -1 );
88     }
89     
90     
91     public StackTraceLineParser( String JavaDoc className, String JavaDoc methodName,
92             int lineNumber )
93     {
94         if (className == null || methodName == null)
95         {
96             throw new IllegalArgumentException JavaDoc("no null arguments");
97         }
98         if (lineNumber < 0)
99         {
100             lineNumber = -1;
101         }
102         this.lineNumber = lineNumber;
103         this.className = className;
104         this.methodName = methodName;
105     }
106     
107     
108     /**
109      * Parses a JDK 1.4 StackTraceElement or a stack trace line.
110      *
111      * @exception IllegalArgumentException if this is not a recognizable stack
112      * trace line, or is <tt>null</tt>, or is not a StackTraceElement.
113      */

114     public StackTraceLineParser( Object JavaDoc obj )
115     {
116         if (obj == null)
117         {
118             throw new IllegalArgumentException JavaDoc("no null arguments");
119         }
120         
121         if (obj instanceof String JavaDoc)
122         {
123             parseLine( (String JavaDoc)obj );
124         }
125         else
126         {
127             parseElement( obj );
128         }
129     }
130     
131     
132     public String JavaDoc getClassName()
133     {
134         return this.className;
135     }
136     
137     
138     public String JavaDoc getMethodName()
139     {
140         return this.methodName;
141     }
142     
143     
144     public int getLineNumber()
145     {
146         return this.lineNumber;
147     }
148     
149     
150     public String JavaDoc toString()
151     {
152         return getClassName() + '#' + getMethodName() + " (line " +
153             getLineNumber() + ')';
154     }
155     
156     
157     //-------------------------------------------------------------------------
158
// Protected methods
159

160     
161     protected void parseLine( String JavaDoc line )
162     {
163         String JavaDoc nl = line.trim();
164         //LOG.debug("parsing trace line '"+line+"'.");
165
int startPos = 0;
166         if (!IN_VISUAL_AGE)
167         {
168             if (nl.startsWith(ST_START))
169             {
170                 startPos += ST_START.length();
171             }
172             else
173             {
174                 //LOG.debug("trace line does not start with '"+ST_START+"'.");
175
notValidStackTraceLine( line );
176             }
177         }
178         
179         int endNamePos = nl.lastIndexOf('(');
180         if (endNamePos < startPos)
181         {
182             //LOG.debug("no '(' in trace line.");
183
notValidStackTraceLine( line );
184         }
185         
186         int lastDot = nl.lastIndexOf('.', endNamePos );
187         if (lastDot < startPos)
188         {
189             //LOG.debug("No '.' in trace line before last '(', which is at "+
190
// endNamePos+".");
191
notValidStackTraceLine( line );
192         }
193         
194         this.methodName = findMethodName( nl, startPos, lastDot, endNamePos );
195         this.className = findClassName( nl, startPos, lastDot, endNamePos );
196         this.lineNumber = findLineNumber( nl, startPos, lastDot, endNamePos );
197     }
198     
199     
200     /**
201      *
202      */

203     protected String JavaDoc findMethodName( String JavaDoc line, int startPos, int lastDot,
204             int endNamePos )
205     {
206         String JavaDoc name = line.substring( lastDot+1, endNamePos ).trim();
207         //LOG.debug("Parsed method name out to '"+name+"'.");
208
return name;
209     }
210     
211     
212     /**
213      *
214      */

215     protected String JavaDoc findClassName( String JavaDoc line, int startPos, int lastDot,
216             int endNamePos )
217     {
218         String JavaDoc name = line.substring( startPos, lastDot ).trim();
219         //LOG.debug("Parsed class name out to '"+name+"'.");
220
return name;
221     }
222     
223     
224     /**
225      *
226      */

227     protected int findLineNumber( String JavaDoc line, int startPos, int lastDot,
228             int endNamePos )
229     {
230         int ln = -1;
231         if (!IN_VISUAL_AGE)
232         {
233             int lineNumberStart = line.indexOf( ':', endNamePos );
234             if (lineNumberStart > 0)
235             {
236                 //LOG.debug("line number is at position "+lineNumberStart+".");
237
int lineNumberEnd = line.indexOf( ')', lineNumberStart );
238                 if (lineNumberEnd > 0)
239                 {
240                     //LOG.debug("final ')', after line number, is at "+
241
// lineNumberEnd+".");
242
try
243                     {
244                         String JavaDoc lineNumber = line.substring(
245                             lineNumberStart+1, lineNumberEnd );
246                         //LOG.debug("line number text is "+lineNumber+".");
247
ln = Integer.parseInt( lineNumber );
248                     }
249                     catch (NumberFormatException JavaDoc e)
250                     {
251                         //LOG.debug("line number text is not a number.");
252
ln = -1;
253                     }
254                 }
255                 else
256                 {
257                     //LOG.debug("stack trace text does not have a final ')'");
258
}
259             }
260             else
261             {
262                 //LOG.debug("stack trace text did not provide line number "+
263
// "information.");
264
}
265         }
266         return ln;
267     }
268     
269     
270     /**
271      * We may not be in JDK 1.4 during compilation or runtime, but we
272      * can support it through reflection anyway.
273      */

274     protected void parseElement( Object JavaDoc el )
275     {
276         Class JavaDoc c = el.getClass();
277         if (String JavaDoc.class.equals( c ))
278         {
279             // specialized method for internal usage checks.
280
throw new IllegalStateException JavaDoc("Incorrect method invoked.");
281         }
282         if (!JDK14_STE_CLASS.equals( c.getName() ))
283         {
284             throw new IllegalArgumentException JavaDoc( "Object "+el+
285                 " is not of type "+JDK14_STE_CLASS+
286                 ", but rather of type "+c.getName() );
287         }
288         
289         Method JavaDoc gcn;
290         Method JavaDoc gln;
291         Method JavaDoc gmn;
292         try
293         {
294             gcn = c.getDeclaredMethod( JDK14_STE_GCN,
295                 JDK14_STE_GCN_ARGS );
296             gln = c.getDeclaredMethod( JDK14_STE_GLN,
297                 JDK14_STE_GLN_ARGS );
298             gmn = c.getDeclaredMethod( JDK14_STE_GMN,
299                 JDK14_STE_GMN_ARGS );
300         }
301         catch (NoSuchMethodException JavaDoc nsme)
302         {
303             throw new IllegalArgumentException JavaDoc( "Object "+el+
304                 " does not support the JDK 1.4 specification of "+
305                     JDK14_STE_CLASS );
306         }
307         
308         String JavaDoc cn;
309         int ln;
310         String JavaDoc mn;
311         try
312         {
313             cn = (String JavaDoc)gcn.invoke( el, null );
314             ln = ((Integer JavaDoc)gln.invoke( el, null )).intValue();
315             mn = (String JavaDoc)gmn.invoke( el, null );
316         }
317         catch (Exception JavaDoc e)
318         {
319             throw new IllegalArgumentException JavaDoc( "Object "+el+
320                 " could not retrieve values for JDK 1.4 specification of "+
321                     JDK14_STE_CLASS );
322         }
323         
324         this.className = cn;
325         this.lineNumber = ln;
326         this.methodName = mn;
327     }
328     
329     
330     protected void notValidStackTraceLine( String JavaDoc line )
331     {
332         throw new IllegalArgumentException JavaDoc("Line ["+
333             line+"] is not a valid stack-trace line");
334     }
335 }
336
337
Popular Tags