1 package org.apache.maven.surefire.report;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import org.apache.maven.surefire.util.internal.StringUtils;
24
25 import java.io.PrintWriter;
26 import java.io.StringWriter;
27
28
29
30
31
32
33
34 public class LegacyPojoStackTraceWriter
35 implements StackTraceWriter
36 {
37 private static final int MAX_LINE_LENGTH = 77;
38
39 private final Throwable t;
40
41 private final String testClass;
42
43 private final String testMethod;
44
45 public LegacyPojoStackTraceWriter( String testClass, String testMethod, Throwable t )
46 {
47 this.testClass = testClass;
48 this.testMethod = testMethod;
49 this.t = t;
50 }
51
52 public String writeTraceToString()
53 {
54 if ( t != null )
55 {
56 StringWriter w = new StringWriter();
57 PrintWriter stackTrace = new PrintWriter( w );
58 try
59 {
60 t.printStackTrace( stackTrace );
61 }
62 finally
63 {
64 stackTrace.close();
65 }
66 w.flush();
67 StringBuffer builder = w.getBuffer();
68 if ( isMultiLineExceptionMessage( t ) )
69 {
70
71 String exc = t.getClass().getName() + ": ";
72 if ( builder.toString().startsWith( exc ) )
73 {
74 builder.insert( exc.length(), '\n' );
75 }
76 }
77 return builder.toString();
78 }
79 return "";
80 }
81
82 public String smartTrimmedStackTrace()
83 {
84 StringBuilder result = new StringBuilder();
85 result.append( testClass );
86 result.append( "#" );
87 result.append( testMethod );
88 SafeThrowable throwable = getThrowable();
89 if ( throwable.getTarget() instanceof AssertionError )
90 {
91 result.append( " " );
92 result.append( getTruncatedMessage( throwable.getMessage(), MAX_LINE_LENGTH - result.length() ) );
93 }
94 else
95 {
96 Throwable target = throwable.getTarget();
97 if ( target != null )
98 {
99 result.append( " " );
100 result.append( target.getClass().getSimpleName() );
101 result.append( getTruncatedMessage( throwable.getMessage(), MAX_LINE_LENGTH - result.length() ) );
102 }
103 }
104 return result.toString();
105 }
106
107 private static boolean isMultiLineExceptionMessage( Throwable t )
108 {
109 String msg = t.getLocalizedMessage();
110 if ( msg != null )
111 {
112 int countNewLines = 0;
113 for ( int i = 0, length = msg.length(); i < length; i++ )
114 {
115 if ( msg.charAt( i ) == '\n' )
116 {
117 if ( ++countNewLines == 2 )
118 {
119 break;
120 }
121 }
122 }
123 return countNewLines > 1 || countNewLines == 1 && !msg.trim().endsWith( "\n" );
124 }
125 return false;
126 }
127
128 private static String getTruncatedMessage( String msg, int i )
129 {
130 if ( i < 0 )
131 {
132 return "";
133 }
134 if ( msg == null )
135 {
136 return "";
137 }
138 String substring = msg.substring( 0, Math.min( i, msg.length() ) );
139 if ( i < msg.length() )
140 {
141 return " " + substring + "...";
142 }
143 else
144 {
145 return " " + substring;
146 }
147 }
148
149
150 public String writeTrimmedTraceToString()
151 {
152 String text = writeTraceToString();
153
154 String marker = "at " + testClass + "." + testMethod;
155
156 String[] lines = StringUtils.split( text, "\n" );
157 int lastLine = lines.length - 1;
158 int causedByLine = -1;
159
160 for ( int i = 1; i < lines.length; i++ )
161 {
162 String line = lines[i].trim();
163 if ( line.startsWith( marker ) )
164 {
165 lastLine = i;
166 }
167 else if ( line.startsWith( "Caused by" ) )
168 {
169 causedByLine = i;
170 break;
171 }
172 }
173
174 StringBuilder trace = new StringBuilder();
175 for ( int i = 0; i <= lastLine; i++ )
176 {
177 trace.append( lines[i] );
178 trace.append( "\n" );
179 }
180
181 if ( causedByLine != -1 )
182 {
183 for ( int i = causedByLine; i < lines.length; i++ )
184 {
185 trace.append( lines[i] );
186 trace.append( "\n" );
187 }
188 }
189 return trace.toString();
190 }
191
192 public SafeThrowable getThrowable()
193 {
194 return new SafeThrowable( t );
195 }
196 }