View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.slf4j.impl;
20  
21  import java.io.PrintStream;
22  
23  import org.apache.maven.api.services.MessageBuilder;
24  
25  import static org.apache.maven.cli.jansi.MessageUtils.builder;
26  
27  /**
28   * Logger for Maven, that support colorization of levels and stacktraces. This class implements 2 methods introduced in
29   * slf4j-simple provider local copy.
30   *
31   * @since 3.5.0
32   */
33  public class MavenSimpleLogger extends SimpleLogger {
34  
35      private final String traceRenderedLevel = builder().trace("TRACE").build();
36      private final String debugRenderedLevel = builder().debug("DEBUG").build();
37      private final String infoRenderedLevel = builder().info("INFO").build();
38      private final String warnRenderedLevel = builder().warning("WARNING").build();
39      private final String errorRenderedLevel = builder().error("ERROR").build();
40  
41      MavenSimpleLogger(String name) {
42          super(name);
43      }
44  
45      @Override
46      protected String renderLevel(int level) {
47          switch (level) {
48              case LOG_LEVEL_TRACE:
49                  return traceRenderedLevel;
50              case LOG_LEVEL_DEBUG:
51                  return debugRenderedLevel;
52              case LOG_LEVEL_INFO:
53                  return infoRenderedLevel;
54              case LOG_LEVEL_WARN:
55                  return warnRenderedLevel;
56              case LOG_LEVEL_ERROR:
57              default:
58                  return errorRenderedLevel;
59          }
60      }
61  
62      @Override
63      protected void writeThrowable(Throwable t, PrintStream stream) {
64          if (t == null) {
65              return;
66          }
67          MessageBuilder builder = builder().failure(t.getClass().getName());
68          if (t.getMessage() != null) {
69              builder.a(": ").failure(t.getMessage());
70          }
71          stream.println(builder);
72  
73          printStackTrace(t, stream, "");
74      }
75  
76      private void printStackTrace(Throwable t, PrintStream stream, String prefix) {
77          MessageBuilder builder = builder();
78          for (StackTraceElement e : t.getStackTrace()) {
79              builder.a(prefix);
80              builder.a("    ");
81              builder.strong("at");
82              builder.a(" ");
83              builder.a(e.getClassName());
84              builder.a(".");
85              builder.a(e.getMethodName());
86              builder.a("(");
87              builder.strong(getLocation(e));
88              builder.a(")");
89              stream.println(builder);
90              builder.setLength(0);
91          }
92          for (Throwable se : t.getSuppressed()) {
93              writeThrowable(se, stream, "Suppressed", prefix + "    ");
94          }
95          Throwable cause = t.getCause();
96          if (cause != null && t != cause) {
97              writeThrowable(cause, stream, "Caused by", prefix);
98          }
99      }
100 
101     private void writeThrowable(Throwable t, PrintStream stream, String caption, String prefix) {
102         MessageBuilder builder =
103                 builder().a(prefix).strong(caption).a(": ").a(t.getClass().getName());
104         if (t.getMessage() != null) {
105             builder.a(": ").failure(t.getMessage());
106         }
107         stream.println(builder);
108 
109         printStackTrace(t, stream, prefix);
110     }
111 
112     protected String getLocation(final StackTraceElement e) {
113         assert e != null;
114 
115         if (e.isNativeMethod()) {
116             return "Native Method";
117         } else if (e.getFileName() == null) {
118             return "Unknown Source";
119         } else if (e.getLineNumber() >= 0) {
120             return e.getFileName() + ":" + e.getLineNumber();
121         } else {
122             return e.getFileName();
123         }
124     }
125 }