1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.spi;
15
16 import ch.qos.logback.core.CoreConstants;
17
18
19
20
21
22
23
24 public class ThrowableProxyUtil {
25
26 public static final int REGULAR_EXCEPTION_INDENT = 1;
27 public static final int SUPPRESSED_EXCEPTION_INDENT = 2;
28
29 public static void build(ThrowableProxy nestedTP, Throwable nestedThrowable,
30 ThrowableProxy parentTP) {
31
32 StackTraceElement[] nestedSTE = nestedThrowable.getStackTrace();
33
34 int commonFramesCount = -1;
35 if (parentTP != null) {
36 commonFramesCount = findNumberOfCommonFrames(nestedSTE, parentTP
37 .getStackTraceElementProxyArray());
38 }
39
40 nestedTP.commonFrames = commonFramesCount;
41 nestedTP.stackTraceElementProxyArray = steArrayToStepArray(nestedSTE);
42 }
43
44 static StackTraceElementProxy[] steArrayToStepArray(StackTraceElement[] stea) {
45 if(stea == null) {
46 return new StackTraceElementProxy[0];
47 }
48 StackTraceElementProxy[] stepa = new StackTraceElementProxy[stea.length];
49 for (int i = 0; i < stepa.length; i++) {
50 stepa[i] = new StackTraceElementProxy(stea[i]);
51 }
52 return stepa;
53 }
54
55 static int findNumberOfCommonFrames(StackTraceElement[] steArray,
56 StackTraceElementProxy[] parentSTEPArray) {
57 if (parentSTEPArray == null || steArray == null) {
58 return 0;
59 }
60
61 int steIndex = steArray.length - 1;
62 int parentIndex = parentSTEPArray.length - 1;
63 int count = 0;
64 while (steIndex >= 0 && parentIndex >= 0) {
65 StackTraceElement ste = steArray[steIndex];
66 StackTraceElement otherSte = parentSTEPArray[parentIndex].ste;
67 if (ste.equals(otherSte)) {
68 count++;
69 } else {
70 break;
71 }
72 steIndex--;
73 parentIndex--;
74 }
75 return count;
76 }
77
78 public static String asString(IThrowableProxy tp) {
79 StringBuilder sb = new StringBuilder();
80
81 recursiveAppend(sb, null, REGULAR_EXCEPTION_INDENT, tp);
82
83 return sb.toString();
84 }
85
86 private static void recursiveAppend(StringBuilder sb, String prefix, int indent, IThrowableProxy tp) {
87 if(tp == null)
88 return;
89 subjoinFirstLine(sb, prefix, tp);
90 sb.append(CoreConstants.LINE_SEPARATOR);
91 subjoinSTEPArray(sb, indent, tp);
92 IThrowableProxy[] suppressed = tp.getSuppressed();
93 if(suppressed != null) {
94 for(IThrowableProxy current : suppressed) {
95 recursiveAppend(sb, CoreConstants.SUPPRESSED, SUPPRESSED_EXCEPTION_INDENT, current);
96 }
97 }
98 recursiveAppend(sb, CoreConstants.CAUSED_BY, REGULAR_EXCEPTION_INDENT, tp.getCause());
99 }
100
101 private static void subjoinFirstLine(StringBuilder buf, String prefix, IThrowableProxy tp) {
102 if (prefix != null) {
103 buf.append(prefix);
104 }
105 subjoinExceptionMessage(buf, tp);
106 }
107
108 public static void subjoinPackagingData(StringBuilder builder, StackTraceElementProxy step) {
109 if (step != null) {
110 ClassPackagingData cpd = step.getClassPackagingData();
111 if (cpd != null) {
112 if (!cpd.isExact()) {
113 builder.append(" ~[");
114 } else {
115 builder.append(" [");
116 }
117
118 builder.append(cpd.getCodeLocation()).append(':').append(
119 cpd.getVersion()).append(']');
120 }
121 }
122 }
123
124 public static void subjoinSTEP(StringBuilder sb, StackTraceElementProxy step) {
125 sb.append(step.toString());
126 subjoinPackagingData(sb, step);
127 }
128
129
130
131
132
133
134 public static void subjoinSTEPArray(StringBuilder sb, IThrowableProxy tp) {
135
136 subjoinSTEPArray(sb, REGULAR_EXCEPTION_INDENT, tp);
137 }
138
139
140
141
142
143
144 public static void subjoinSTEPArray(StringBuilder sb, int indentLevel, IThrowableProxy tp) {
145 StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
146 int commonFrames = tp.getCommonFrames();
147
148 for (int i = 0; i < stepArray.length - commonFrames; i++) {
149 StackTraceElementProxy step = stepArray[i];
150 for(int j = 0; j < indentLevel ; j++) {
151 sb.append(CoreConstants.TAB);
152 }
153 subjoinSTEP(sb, step);
154 sb.append(CoreConstants.LINE_SEPARATOR);
155 }
156
157 if (commonFrames > 0) {
158 for(int j = 0; j < indentLevel ; j++) {
159 sb.append(CoreConstants.TAB);
160 }
161 sb.append("... ").append(commonFrames).append(" common frames omitted")
162 .append(CoreConstants.LINE_SEPARATOR);
163 }
164
165 }
166
167 public static void subjoinFirstLine(StringBuilder buf, IThrowableProxy tp) {
168 int commonFrames = tp.getCommonFrames();
169 if (commonFrames > 0) {
170 buf.append(CoreConstants.CAUSED_BY);
171 }
172 subjoinExceptionMessage(buf, tp);
173 }
174
175 public static void subjoinFirstLineRootCauseFirst(StringBuilder buf, IThrowableProxy tp) {
176 if (tp.getCause() != null) {
177 buf.append(CoreConstants.WRAPPED_BY);
178 }
179 subjoinExceptionMessage(buf, tp);
180 }
181
182 private static void subjoinExceptionMessage(StringBuilder buf, IThrowableProxy tp) {
183 buf.append(tp.getClassName()).append(": ").append(tp.getMessage());
184 }
185 }