View Javadoc
1   package org.apache.maven.surefire.api.report;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  
23  import org.apache.maven.surefire.api.util.internal.StringUtils;
24  import static org.apache.maven.surefire.shared.utils.StringUtils.isNotEmpty;
25  
26  import java.io.PrintWriter;
27  import java.io.StringWriter;
28  
29  /**
30   * Write the trace out for a POJO test. Java 1.5 compatible.
31   *
32   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
33   */
34  public class LegacyPojoStackTraceWriter
35      implements StackTraceWriter
36  {
37      private final Throwable t;
38  
39      private final String testClass;
40  
41      private final String testMethod;
42  
43      public LegacyPojoStackTraceWriter( String testClass, String testMethod, Throwable t )
44      {
45          this.testClass = testClass;
46          this.testMethod = testMethod;
47          this.t = t;
48      }
49  
50      @Override
51      public String writeTraceToString()
52      {
53          if ( t != null )
54          {
55              StringWriter w = new StringWriter();
56              try ( PrintWriter stackTrace = new PrintWriter( w ) )
57              {
58                  t.printStackTrace( stackTrace );
59              }
60              StringBuffer builder = w.getBuffer();
61              if ( isMultiLineExceptionMessage( t ) )
62              {
63                  // SUREFIRE-986
64                  String exc = t.getClass().getName() + ": ";
65                  if ( StringUtils.startsWith( builder, exc ) )
66                  {
67                      builder.insert( exc.length(), '\n' );
68                  }
69              }
70              return builder.toString();
71          }
72          return "";
73      }
74  
75      @Override
76      public String smartTrimmedStackTrace()
77      {
78          StringBuilder result = new StringBuilder();
79          result.append( testClass );
80          result.append( "#" );
81          result.append( testMethod );
82          SafeThrowable throwable = getThrowable();
83          Throwable target = throwable.getTarget();
84          if ( target != null )
85          {
86              if ( ! ( target instanceof AssertionError ) )
87              {
88                  result.append( ' ' )
89                        .append( target.getClass().getSimpleName() );
90              }
91              final String msg = throwable.getMessage();
92              if ( isNotEmpty( msg ) )
93              {
94                  result.append( ' ' )
95                        .append( msg );
96              }
97          }
98          return result.toString();
99      }
100 
101     private static boolean isMultiLineExceptionMessage( Throwable t )
102     {
103         String msg = t.getLocalizedMessage();
104         if ( msg != null )
105         {
106             int countNewLines = 0;
107             for ( int i = 0, length = msg.length(); i < length; i++ )
108             {
109                 if ( msg.charAt( i ) == '\n' )
110                 {
111                     if ( ++countNewLines == 2 )
112                     {
113                         break;
114                     }
115                 }
116             }
117             return countNewLines > 1 || countNewLines == 1 && !msg.trim().endsWith( "\n" );
118         }
119         return false;
120     }
121 
122     @Override
123     public String writeTrimmedTraceToString()
124     {
125         String text = writeTraceToString();
126 
127         String marker = "at " + testClass + "." + testMethod;
128 
129         String[] lines = StringUtils.split( text, "\n" );
130         int lastLine = lines.length - 1;
131         int causedByLine = -1;
132         // skip first
133         for ( int i = 1; i < lines.length; i++ )
134         {
135             String line = lines[i].trim();
136             if ( line.startsWith( marker ) )
137             {
138                 lastLine = i;
139             }
140             else if ( line.startsWith( "Caused by" ) )
141             {
142                 causedByLine = i;
143                 break;
144             }
145         }
146 
147         StringBuilder trace = new StringBuilder();
148         for ( int i = 0; i <= lastLine; i++ )
149         {
150             trace.append( lines[i] );
151             trace.append( "\n" );
152         }
153 
154         if ( causedByLine != -1 )
155         {
156             for ( int i = causedByLine; i < lines.length; i++ )
157             {
158                 trace.append( lines[i] );
159                 trace.append( "\n" );
160             }
161         }
162         return trace.toString();
163     }
164 
165     @Override
166     public SafeThrowable getThrowable()
167     {
168         return new SafeThrowable( t );
169     }
170 }