Source Code Cross Referenced for StackTrace.java in  » Portal » uPortal_rel-2-6-1-GA » org » jasig » portal » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Portal » uPortal_rel 2 6 1 GA » org.jasig.portal.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2004 The JA-SIG Collaborative.  All rights reserved.
002:         *  See license distributed with this file and
003:         *  available online at http://www.uportal.org/license.html
004:         */
005:
006:        package org.jasig.portal.lang;
007:
008:        import java.lang.reflect.Method;
009:        import java.io.PrintWriter;
010:        import java.io.StringWriter;
011:
012:        /**
013:         * The <code>StackTrace</code> object represents a single stack frame
014:         * of information. The entire set of stack frames is represented as an
015:         * array of <code>StackTrace</code> object.<p/>
016:         *
017:         * Note: The stack frame information is not always available because
018:         * some JVMs strip some or all the required information.
019:         *
020:         * @author <a href="mailto:jnielsen@sct.com">Jan Nielsen</a>
021:         *
022:         * @version "$Revision: 35982 $"
023:         **/
024:        public final class StackTrace {
025:            /** Default size of the stack trace array buffer. */
026:            private static final int DEFAULT_STACK_TRACE_ARRAY_SIZE = TypeConverter
027:                    .toInt(Resources
028:                            .getString(StackTrace.class,
029:                                    "getStackTraceElement.default_stack_trace_array_size"));
030:
031:            /** Moniker for native method. */
032:            private static final int NATIVE_METHOD = -2;
033:
034:            /** Prime number used to calculate hash code. */
035:            private static final int PRIME = 31;
036:
037:            /**
038:             * Returns the name of the source file. If the parser failed to
039:             * find the source file name the value <code>"Unknown"</code> will
040:             * be returned.
041:             *
042:             * @return name of the source file
043:             **/
044:            public final String getFileName() {
045:                String fileName = mFileName;
046:
047:                if (null == fileName) {
048:                    fileName = Resources.getString(StackTrace.class,
049:                            "unknown_source");
050:                }
051:
052:                return fileName;
053:            }
054:
055:            /**
056:             * Returns the name of the class. The parser should always be
057:             * able to identify the calling class.
058:             *
059:             * @return name of the class
060:             **/
061:            public final String getClassName() {
062:                return mClassName;
063:            }
064:
065:            /**
066:             * Returns the name of the method. The parser should alwas be
067:             * able to identify the calling method name.
068:             *
069:             * @return name of the method
070:             **/
071:            public final String getMethodName() {
072:                return mMethodName;
073:            }
074:
075:            /**
076:             * Returns the line number in the source file. If the parser is
077:             * unable to determine the line number the value <code>-1</code>
078:             * will be returned. If the parser determines the method is a
079:             * native, a -2 is returned.
080:             *
081:             * @return source code line number, or -1 or -2
082:             **/
083:            public final int getLineNumber() {
084:                return mLineNumber;
085:            }
086:
087:            /**
088:             * Returns <code>true</code> if method is implemented
089:             * natively.
090:             *
091:             * @return <code>true</code> is native method; otherwise
092:             * <code>false</code>
093:             **/
094:            public final boolean isNativeMethod() {
095:                return NATIVE_METHOD == mLineNumber;
096:            }
097:
098:            /**
099:             * Returns all <code>StackTrace</code>s in an array of the
100:             * specified throwable.
101:             *
102:             *
103:             * @param throwable throwable being parsed
104:             *
105:             * @return array of <code>StackTrace</code>s
106:             *
107:             * @throws NullPointerException if throwable is <code>null</code>
108:             *
109:             * @throws NullPointerException if stackTrace is <code>null</code>
110:             *
111:             * @throws IllegalArgumentException if stackTrace is an empty
112:             * string
113:             **/
114:            public static final StackTrace[] getStackTrace(Throwable throwable) {
115:                StringWriter stringWriter = new StringWriter();
116:                PrintWriter printWriter = null;
117:
118:                StackTrace[] elements = null;
119:
120:                try {
121:                    printWriter = new PrintWriter(stringWriter);
122:
123:                    throwable.printStackTrace(printWriter);
124:
125:                    elements = StackTrace.getStackTrace(throwable, stringWriter
126:                            .toString());
127:                } finally {
128:                    if (null != printWriter) {
129:                        printWriter.close();
130:                    }
131:                }
132:                return elements;
133:            }
134:
135:            /**
136:             * Returns all <code>StackTrace</code>s in an array. This method
137:             * is used by the <code>Chained*</code> concrete classes to avoid
138:             * a circular dependency. The throwable, and its string output
139:             * must both be specified. Both are required because the throwable
140:             * could be a <code>com.sct.pipeline.lang.ChainedException</code>
141:             * which would result in a circular dependency if a
142:             * <code>printStackTrace</code> was used in this method to
143:             * retrieve the trace information. Invoke this method in the
144:             * following fashion:
145:             *
146:             * <code><pre>
147:             *    StringWriter stringWriter = new StringWriter();
148:             *
149:             *    PrintWriter printWriter = new PrintWriter(
150:             *        stringWriter
151:             *        );
152:             *
153:             *    Throwable t = new Throwable();
154:             *
155:             *    t.printStackTrace(
156:             *        printWriter
157:             *        );
158:             *
159:             *    printWriter.close();
160:             *
161:             *    StackTrace[] frames = getStackTraceElements(
162:             *        t,
163:             *        stringWriter.toString()
164:             *        );
165:             * </pre></code>
166:             *
167:             * @param throwable throwable being parsed
168:             *
169:             * @param stackTrace string output of
170:             * <code>throwable.printStackTrace</code>
171:             *
172:             * @return array of <code>StackTrace</code>s
173:             *
174:             * @throws NullPointerException if throwable is <code>null</code>
175:             *
176:             * @throws NullPointerException if stackTrace is <code>null</code>
177:             *
178:             * @throws IllegalArgumentException if stackTrace is an empty string
179:             **/
180:            static final StackTrace[] getStackTrace(Throwable throwable,
181:                    String stackTrace) {
182:                if (null == throwable) {
183:                    throw new NullPointerException(
184:                            ThrowableHelper
185:                                    .getInternationalizedMessage(
186:                                            StackTrace.class,
187:                                            "getStackTraceElement.error.throwable_is_null"));
188:                }
189:
190:                if (null == stackTrace) {
191:                    throw new NullPointerException(
192:                            ThrowableHelper
193:                                    .getInternationalizedMessage(
194:                                            StackTrace.class,
195:                                            "getStackTraceElement.error.stack_trace_is_null"));
196:                }
197:
198:                if (stackTrace.equals("")) {
199:                    throw new IllegalArgumentException(
200:                            ThrowableHelper
201:                                    .getInternationalizedMessage(
202:                                            StackTrace.class,
203:                                            "getStackTraceElement.error.stack_trace_is_empty"));
204:                }
205:
206:                return parseStackTrace(throwable, stackTrace);
207:            }
208:
209:            /**
210:             * Returns the stack trace elements of the client. The array of
211:             * stack trace elements start with the client's invoking frame in
212:             * the zeroth element.
213:             *
214:             * @return array of stack trace elements of the client
215:             **/
216:            public static final StackTrace[] getStackTrace() {
217:                StringWriter stringWriter = new StringWriter();
218:
219:                PrintWriter printWriter = null;
220:                StackTrace[] clientFrames = null;
221:
222:                try {
223:
224:                    printWriter = new PrintWriter(stringWriter);
225:
226:                    Throwable t = new Throwable();
227:
228:                    t.printStackTrace(printWriter);
229:
230:                    printWriter.close();
231:
232:                    StackTrace[] frames = getStackTrace(t, stringWriter
233:                            .toString());
234:
235:                    clientFrames = new StackTrace[frames.length - 1];
236:
237:                    // Skip the first frame (this method).
238:                    System.arraycopy(frames, 1, clientFrames, 0,
239:                            clientFrames.length);
240:                } finally {
241:                    if (null != printWriter) {
242:                        printWriter.close();
243:                    }
244:                }
245:
246:                return clientFrames;
247:            }
248:
249:            /**
250:             * Returns the specified stack trace element if it exists. If an
251:             * invalid, either too large or too small, index is specified
252:             * <code>null</code> is returned.
253:             *
254:             * @param index index of the stack trace element to return
255:             *
256:             * @return stack trace element at the index or <code>null</code>
257:             **/
258:            public static final StackTrace getStackTrace(int index) {
259:                StackTrace element = null;
260:                PrintWriter printWriter = null;
261:
262:                try {
263:
264:                    if (!(0 > index)) {
265:                        String moniker = "dummy moniker";
266:
267:                        StringWriter stringWriter = new StringWriter();
268:
269:                        printWriter = new PrintWriter(stringWriter);
270:
271:                        Throwable throwable = new Throwable(moniker);
272:
273:                        throwable.printStackTrace(printWriter);
274:
275:                        StackTrace[] elements = getStackTrace(throwable,
276:                                stringWriter.toString());
277:
278:                        if ((0 < index + 1) && (elements.length > index + 1)) {
279:                            element = elements[index + 1];
280:                        }
281:                    }
282:                } finally {
283:                    if (null != printWriter) {
284:                        printWriter.close();
285:                    }
286:                }
287:
288:                return element;
289:            }
290:
291:            /**
292:             * Converts a JDK 1.4 stack trace to this object.
293:             * 
294:             * @param stackTrace array of JDK 1.4 stack trace objects
295:             * 
296:             * @return array of <code>StackTrace</code> objects
297:             **/
298:            static final StackTrace[] convertStackTrace(Object[] stackTrace) {
299:                int size = stackTrace.length;
300:
301:                StackTrace[] elements = new StackTrace[size];
302:
303:                for (int i = 0; i < size; i++) {
304:                    elements[i] = convertElement(stackTrace[i]);
305:                }
306:                return elements;
307:            }
308:
309:            /**
310:             * Converts a J2SDK 1.4 <code>StackTraceElement</code> object
311:             * to a <code>StackTrace</code> object.
312:             * 
313:             * @param element <code>StackTraceElement</code> object
314:             * 
315:             * @return corresponding <code>StackTrace</code> object
316:             **/
317:            private static final StackTrace convertElement(Object element) {
318:                StackTrace stackTraceElement = null;
319:
320:                try {
321:                    Method getClassName = element.getClass().getMethod(
322:                            "getClassName", (Class[]) null);
323:
324:                    Method getMethodName = element.getClass().getMethod(
325:                            "getMethodName", (Class[]) null);
326:
327:                    Method getFileName = element.getClass().getMethod(
328:                            "getFileName", (Class[]) null);
329:
330:                    Method getLineNumber = element.getClass().getMethod(
331:                            "getLineNumber", (Class[]) null);
332:
333:                    stackTraceElement = new StackTrace((String) getClassName
334:                            .invoke(element, (Object[]) null),
335:                            (String) getMethodName.invoke(element,
336:                                    (Object[]) null), (String) getFileName
337:                                    .invoke(element, (Object[]) null),
338:                            ((Integer) getLineNumber.invoke(element,
339:                                    (Object[]) null)).intValue());
340:                } catch (Exception x) {
341:                    ThrowableHelper.handle(x);
342:                }
343:                return stackTraceElement;
344:            }
345:
346:            /**
347:             * Returns an array of <code>StackTrace</code> objects representing
348:             * the <code>Throwable</code> argument.
349:             * 
350:             * @param throwable 
351:             * 
352:             * @param stackTrace 
353:             * 
354:             * @return array of <code>StackTrace</code> objects
355:             **/
356:            private static final StackTrace[] parseStackTrace(
357:                    Throwable throwable, String stackTrace) {
358:                // Remove the standard header information in the stack trace.
359:                try {
360:                    stackTrace = stackTrace
361:                            .substring(null != throwable.getLocalizedMessage() ? ((throwable
362:                                    .getClass().getName()
363:                                    + ":" + throwable.getLocalizedMessage())
364:                                    .length() + 1)
365:                                    : (throwable.getClass().getName().length() + 1));
366:                } catch (IndexOutOfBoundsException x) {
367:                    ThrowableHelper.handle(x);
368:                }
369:
370:                Object[] stackTraceObjects = parseStackTrace(stackTrace);
371:
372:                StackTrace[] stackTraceArray = new StackTrace[stackTraceObjects.length];
373:
374:                if (null != stackTraceObjects) {
375:                    System.arraycopy(stackTraceObjects, 0, stackTraceArray, 0,
376:                            stackTraceArray.length);
377:                }
378:
379:                return stackTraceArray;
380:            }
381:
382:            /**
383:             * Parses a stack trace into individual stack frames.
384:             *  
385:             * @param stackTrace stack trace to parse
386:             * 
387:             * @return array of stack trace objects
388:             **/
389:            private static final Object[] parseStackTrace(String stackTrace) {
390:                final ParseState state = new ParseState(stackTrace);
391:
392:                java.util.ArrayList stackTraceElements = new java.util.ArrayList(
393:                        DEFAULT_STACK_TRACE_ARRAY_SIZE);
394:
395:                while ((state.mIndex + 3) < state.mSize) {
396:                    StackTrace frame = parseStackTrace(state);
397:
398:                    stackTraceElements.add(frame);
399:                }
400:
401:                return stackTraceElements.toArray();
402:            }
403:
404:            /**
405:             * Returns a representation of the stack frame element. The
406:             * format of the information may vary but the following examples
407:             * are typical:
408:             *
409:             * <ul>
410:             * <li><tt>mycompany.MyClass.snap(MyClass.java:9)</tt></li>
411:             * <li><tt>mycompany.MyClass.snap(MyClass.java)</tt></li>
412:             * <li><tt>mycompany.MyClass.snap(Unknown Source)</tt></li>
413:             * <li><tt>mycompany.MyClass.snap(Native Method)</tt></li>
414:             * </ul>
415:             *
416:             * @return string presentation of the stack frame.
417:             **/
418:            public final String toString() {
419:                StringBuffer buffer = new StringBuffer(mClassName).append(".")
420:                        .append(mMethodName);
421:
422:                if (isNativeMethod()) {
423:                    buffer.append("("
424:                            + Resources.getString(StackTrace.class,
425:                                    "native_method") + ")");
426:                } else if (null != mFileName && 0 <= mLineNumber) {
427:                    buffer.append("(").append(mFileName).append(":").append(
428:                            mLineNumber).append(")");
429:                } else if (null != mFileName) {
430:                    buffer.append("(").append(mFileName).append(")");
431:                } else {
432:                    buffer.append("("
433:                            + Resources.getString(StackTrace.class,
434:                                    "unknown_source") + ")");
435:                }
436:
437:                return buffer.toString();
438:            }
439:
440:            /**
441:             * Returns a string representation of the stack trace elements.
442:             *
443:             * @param elements stack trace elements to stringify
444:             *
445:             * @return string representation of the stack trace array 
446:             **/
447:            public static final String toString(StackTrace[] elements) {
448:                String sep = System.getProperty("line.separator");
449:                StringBuffer buffer = new StringBuffer();
450:
451:                for (int i = 0; i < elements.length; i++) {
452:                    buffer.append(elements[i].toString()).append(sep);
453:                }
454:
455:                return buffer.toString();
456:            }
457:
458:            /**
459:             * Returns <code>true<code> if the specified object is another
460:             * <tt>StackTrace</tt> instance representing the same
461:             * execution point as this instance.  Two stack trace elements
462:             * <tt>a</tt> and <tt>b</tt> are equal if and only if:
463:             *
464:             * <pre><code>
465:             *     equals(a.getFileName(), b.getFileName()) &&
466:             *     a.getLineNumber() == b.getLineNumber()) &&
467:             *     equals(a.getClassName(), b.getClassName()) &&
468:             *     equals(a.getMethodName(), b.getMethodName())
469:             * </code></pre>
470:             *
471:             * where <tt>equals</tt> is defined as:
472:             *
473:             * <pre><code>
474:             *     static boolean equals(Object a, Object b) {
475:             *         return a==b || (a != null && a.equals(b));
476:             *     }
477:             * </code></pre>
478:             *
479:             * @param obj the object to be compared with this stack trace
480:             * element
481:             *
482:             * @return <code>true</code> if the specified object is another
483:             * <tt>StackTrace</tt> instance representing the same
484:             * execution point as this instance; otherwise <code>false</code>
485:             **/
486:            public boolean equals(Object obj) {
487:                boolean isEqual = false;
488:
489:                if (this  == obj) {
490:                    isEqual = true;
491:                } else if (obj instanceof  StackTrace) {
492:                    StackTrace e = (StackTrace) obj;
493:
494:                    isEqual = e.mClassName.equals(mClassName)
495:                            && e.mLineNumber == mLineNumber
496:                            && eq(mMethodName, e.mMethodName)
497:                            && eq(mFileName, e.mFileName);
498:                }
499:
500:                return isEqual;
501:            }
502:
503:            /**
504:             * Returns <code>true</code> if the two objects are
505:             * equal. Equality is defined as either object identity or if
506:             * <code>a.equals(b)</code> if <code>a</code> is not
507:             * <code>null</code>.
508:             * 
509:             * @param a left hand side argument
510:             * 
511:             * @param b right hand side argument
512:             * 
513:             * @return <code>true</code> if the two are equal; otherwise
514:             * <code>false</code>
515:             **/
516:            private static final boolean eq(Object a, Object b) {
517:                return a == b || (null != a && a.equals(b));
518:            }
519:
520:            /**
521:             * Returns a hash code value for this stack trace element.
522:             *
523:             * @return hash code value
524:             **/
525:            public int hashCode() {
526:                int result = PRIME * mClassName.hashCode()
527:                        + mMethodName.hashCode();
528:                result = PRIME * result
529:                        + (null == mFileName ? 0 : mFileName.hashCode());
530:                result = PRIME * result + mLineNumber;
531:
532:                return result;
533:            }
534:
535:            /**
536:             * Hidden constructor for the <code>StackTrace</code> object.
537:             * 
538:             * @param className class name in the stack frame
539:             * 
540:             * @param methodName method name in the stack frame
541:             * 
542:             * @param fileName file name in the stack frame
543:             * 
544:             * @param lineNumber line number in the stack frame 
545:             **/
546:            private StackTrace(String className, String methodName,
547:                    String fileName, int lineNumber) {
548:                mClassName = className;
549:                mMethodName = methodName;
550:                mFileName = fileName;
551:                mLineNumber = lineNumber;
552:            }
553:
554:            /**
555:             * Parse the first class name from the specified stack trace
556:             * starting at the specified index.
557:             *
558:             * @param state parsing state
559:             *
560:             * @return parsed stack trace element
561:             **/
562:            private static final StackTrace parseStackTrace(ParseState state) {
563:                String className = null;
564:                String methodName = null;
565:                String fileName = null;
566:                int lineNumber = -1;
567:
568:                int classNameStart;
569:                int classNameEnd;
570:                int methodNameStart = 0;
571:                int methodNameEnd = 0;
572:                int fileNameStart;
573:                int fileNameEnd;
574:                int lineNumberStart;
575:                int lineNumberEnd;
576:
577:                // Move to beginning of class name.
578:                while (state.mIndex + 2 < state.mSize) {
579:                    if ('a' == state.mStackTraceCharacters[state.mIndex]
580:                            && 't' == state.mStackTraceCharacters[state.mIndex + 1]
581:                            && ' ' == state.mStackTraceCharacters[state.mIndex + 2]) {
582:                        state.mIndex += 3;
583:                        break;
584:                    }
585:                    state.mIndex++;
586:                }
587:                classNameStart = state.mIndex;
588:                classNameEnd = classNameStart;
589:
590:                // Move the end of method name, saving the class name end and
591:                // method name start along the way.
592:                while (state.mIndex < state.mSize) {
593:                    if ('.' == state.mStackTraceCharacters[state.mIndex]) {
594:                        classNameEnd = state.mIndex;
595:                        methodNameStart = classNameEnd + 1;
596:                    } else if ('(' == state.mStackTraceCharacters[state.mIndex]) {
597:                        methodNameEnd = state.mIndex;
598:                        break;
599:                    }
600:                    state.mIndex++;
601:                }
602:
603:                // Define the class name.
604:                try {
605:                    className = state.mStackTrace.substring(classNameStart,
606:                            classNameEnd);
607:                } catch (IndexOutOfBoundsException x) {
608:                    ThrowableHelper.handle(x);
609:                }
610:
611:                try {
612:                    // Define the method name.
613:                    methodName = state.mStackTrace.substring(methodNameStart,
614:                            methodNameEnd);
615:                } catch (IndexOutOfBoundsException x) {
616:                    ThrowableHelper.handle(x);
617:                }
618:
619:                // Move to after the parenthesis.
620:                fileNameStart = state.mIndex + 1;
621:
622:                if (state.mIndex + 14 < state.mSize
623:                        && 'U' == state.mStackTraceCharacters[state.mIndex + 1]
624:                        && 'n' == state.mStackTraceCharacters[state.mIndex + 2]
625:                        && 'k' == state.mStackTraceCharacters[state.mIndex + 3]
626:                        && 'n' == state.mStackTraceCharacters[state.mIndex + 4]
627:                        && 'o' == state.mStackTraceCharacters[state.mIndex + 5]
628:                        && 'w' == state.mStackTraceCharacters[state.mIndex + 6]
629:                        && 'n' == state.mStackTraceCharacters[state.mIndex + 7]
630:                        && ' ' == state.mStackTraceCharacters[state.mIndex + 8]
631:                        && 'S' == state.mStackTraceCharacters[state.mIndex + 9]
632:                        && 'o' == state.mStackTraceCharacters[state.mIndex + 10]
633:                        && 'u' == state.mStackTraceCharacters[state.mIndex + 11]
634:                        && 'r' == state.mStackTraceCharacters[state.mIndex + 12]
635:                        && 'c' == state.mStackTraceCharacters[state.mIndex + 13]
636:                        && 'e' == state.mStackTraceCharacters[state.mIndex + 14]) {
637:                    fileName = null;
638:                    lineNumber = -1;
639:                } else if (state.mIndex + 13 < state.mSize
640:                        && 'N' == state.mStackTraceCharacters[state.mIndex + 1]
641:                        && 'a' == state.mStackTraceCharacters[state.mIndex + 2]
642:                        && 't' == state.mStackTraceCharacters[state.mIndex + 3]
643:                        && 'i' == state.mStackTraceCharacters[state.mIndex + 4]
644:                        && 'v' == state.mStackTraceCharacters[state.mIndex + 5]
645:                        && 'e' == state.mStackTraceCharacters[state.mIndex + 6]
646:                        && ' ' == state.mStackTraceCharacters[state.mIndex + 7]
647:                        && 'M' == state.mStackTraceCharacters[state.mIndex + 8]
648:                        && 'e' == state.mStackTraceCharacters[state.mIndex + 9]
649:                        && 't' == state.mStackTraceCharacters[state.mIndex + 10]
650:                        && 'h' == state.mStackTraceCharacters[state.mIndex + 11]
651:                        && 'o' == state.mStackTraceCharacters[state.mIndex + 12]
652:                        && 'd' == state.mStackTraceCharacters[state.mIndex + 13]) {
653:                    lineNumber = -2;
654:                } else {
655:                    // Current character.
656:                    char ch;
657:
658:                    // Move to end of source file name by looking for the ':'.
659:                    while (state.mIndex < state.mSize) {
660:                        ch = state.mStackTraceCharacters[state.mIndex];
661:
662:                        if ('\n' == ch || '\r' == ch) {
663:                            // Failed to find ':' so leave the file name and line
664:                            // number as unknown.
665:
666:                            // In case this is a '\r\n' platform.
667:                            if ((state.mIndex + 1) < state.mSize
668:                                    && '\n' == state.mStackTraceCharacters[state.mIndex + 1]) {
669:                                state.mIndex++;
670:                            }
671:                            break;
672:                        } else if ('.' == ch) {
673:                            // Move past the ".java".
674:                            fileNameEnd = state.mIndex + 5;
675:
676:                            // Move past the ":".
677:                            lineNumberStart = fileNameEnd + 1;
678:
679:                            // Define the file name.
680:                            fileName = state.mStackTrace.substring(
681:                                    fileNameStart, fileNameEnd);
682:
683:                            // Move to the start of the line number.
684:                            state.mIndex = lineNumberStart;
685:
686:                            while (state.mIndex < state.mSize) {
687:                                ch = state.mStackTraceCharacters[state.mIndex];
688:                                if ('\n' == ch || '\r' == ch) {
689:                                    // Failed to find the terminator, so leave
690:                                    // line number unknown.
691:
692:                                    // In case this is a '\r\n' platform.
693:                                    if ((state.mIndex + 1) < state.mSize
694:                                            && '\n' == state.mStackTraceCharacters[state.mIndex + 1]) {
695:                                        state.mIndex++;
696:                                    }
697:                                    break;
698:                                } else if (')' == state.mStackTraceCharacters[state.mIndex]) {
699:                                    lineNumberEnd = state.mIndex;
700:
701:                                    // Define the line number.
702:                                    lineNumber = TypeConverter
703:                                            .toInt(state.mStackTrace.substring(
704:                                                    lineNumberStart,
705:                                                    lineNumberEnd));
706:                                    // Don't break here in case there are spaces at
707:                                    // the end of the stack trace.
708:                                }
709:                                state.mIndex++;
710:                            }
711:                            break;
712:                        }
713:                        state.mIndex++;
714:                    }
715:                }
716:
717:                StackTrace frame = new StackTrace(className, methodName,
718:                        fileName, lineNumber);
719:
720:                return frame;
721:            }
722:
723:            /**
724:             * The <code>ParseState</code> class holds the current parsing
725:             * state.
726:             * 
727:             * @author <a href="mailto:jnielsen@sct.com">Jan Nielsen</a>
728:             * 
729:             * @version "$Revision: 35982 $"
730:             *
731:             * @invariant null != mStackTrace
732:             **/
733:            private static class ParseState {
734:                /**
735:                 * Construct a parsing state object with the specified
736:                 * stack trace.
737:                 *
738:                 * @param stackTrace stack trace to be parsed
739:                 **/
740:                private ParseState(String stackTrace) {
741:                    mStackTrace = stackTrace;
742:                    mStackTraceCharacters = mStackTrace.toCharArray();
743:                    mSize = mStackTraceCharacters.length;
744:                    mIndex = 0;
745:                }
746:
747:                /** Entire stack trace. */
748:                private String mStackTrace;
749:
750:                /** Entire stack trace in character array form. */
751:                private char[] mStackTraceCharacters;
752:
753:                /** Size of the entire stack trace. */
754:                private int mSize;
755:
756:                /** Current index in the stack trace array. */
757:                private int mIndex;
758:            }
759:
760:            /**
761:             * Holder for the source file name.
762:             **/
763:            private String mFileName;
764:
765:            /**
766:             * Holder for the class name.
767:             **/
768:            private String mClassName;
769:
770:            /**
771:             * Holder for the method name.
772:             **/
773:            private String mMethodName;
774:
775:            /**
776:             * Holder for the line number. The value (-2) is used to denote a
777:             * native method.
778:             **/
779:            private int mLineNumber = -1;
780:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.