1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jdiagnose.message;
17
18 import java.io.PrintWriter;
19 import java.io.StringWriter;
20 import java.lang.reflect.Method;
21
22 import org.jdiagnose.DefaultDiagnosticMessage;
23 import org.jdiagnose.DiagnosticMessage;
24 import org.jdiagnose.MessageFactory;
25 import org.jdiagnose.exception.NestableRuntimeException;
26
27 /***
28 * Creates diagnostic messages from exceptions. The exception message
29 * is used as the summary and the stacktrace as the body. Will use the
30 * root exception by default and can optionally suppress the stack trace.
31 * Uses reflection to find the root cause so that it can be backwards
32 * compatible with Java 1.3
33 *
34 * @author jmccrindle
35 */
36 public class ExceptionMessageFactory implements MessageFactory {
37
38 public static final ExceptionMessageFactory DEFAULT_EXCEPTION_MESSAGE_FACTORY = new ExceptionMessageFactory();
39
40 private boolean suppressStackTrace = false;
41 private boolean rootExceptionOnly = true;
42
43 /***
44 * @param suppressStackTrace whether the stackTrace should be used for the
45 * message body
46 * @param rootExceptionOnly whether the root exception should be used or the
47 * whole exception.
48 */
49 public ExceptionMessageFactory(boolean suppressStackTrace,
50 boolean rootExceptionOnly) {
51 super();
52 this.suppressStackTrace = suppressStackTrace;
53 this.rootExceptionOnly = rootExceptionOnly;
54 }
55
56 /***
57 * Default Constructor
58 */
59 public ExceptionMessageFactory() {
60 super();
61 }
62
63 /***
64 * Finds the root cause given an exception. Uses reflection to make it
65 * compatible with Java 1.3
66 *
67 * @param t
68 * @return
69 */
70 protected Throwable getRootCause(Throwable t) {
71 if(t == null) return t;
72 try {
73 Method method = t.getClass().getMethod("getCause", null);
74 Throwable cause = (Throwable) method.invoke(t, null);
75 if(cause == null) {
76 return t;
77 } else {
78 return getRootCause(cause);
79 }
80 } catch (NoSuchMethodException e) {
81
82 return null;
83 } catch (Throwable e) {
84 throw new NestableRuntimeException(e);
85 }
86 }
87
88 /***
89 * @see org.jdiagnose.MessageFactory#getMessage(java.lang.Object)
90 */
91 public DiagnosticMessage getMessage(Object object) {
92
93 if (object instanceof Throwable) {
94 Throwable throwable = (Throwable) object;
95 if(rootExceptionOnly) {
96 throwable = getRootCause(throwable);
97 }
98 String body = null;
99 if(!suppressStackTrace) {
100 StringWriter stringWriter = new StringWriter();
101 PrintWriter printer = new PrintWriter(stringWriter);
102 throwable.printStackTrace(printer);
103 body = stringWriter.toString();
104 }
105 return new DefaultDiagnosticMessage(throwable.getMessage(), body);
106 }
107 return null;
108 }
109
110 /***
111 * @param rootExceptionOnly whether the root exception should be used or the
112 * whole exception.
113 */
114 public void setRootExceptionOnly(boolean rootExceptionOnly) {
115 this.rootExceptionOnly = rootExceptionOnly;
116 }
117
118 /***
119 * @param suppressStackTrace whether the stackTrace should be used for the
120 * message body
121 */
122 public void setSuppressStackTrace(boolean suppressStackTrace) {
123 this.suppressStackTrace = suppressStackTrace;
124 }
125 }