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.apache.maven.cling.utils;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.time.Duration;
24  import java.time.format.DateTimeFormatter;
25  import java.time.temporal.TemporalAccessor;
26  import java.util.Locale;
27  import java.util.Properties;
28  
29  import org.apache.maven.jline.MessageUtils;
30  import org.codehaus.plexus.util.Os;
31  import org.slf4j.Logger;
32  
33  /**
34   * Utility class used to report errors, statistics, application version info, etc.
35   *
36   */
37  public final class CLIReportingUtils {
38      // CHECKSTYLE_OFF: MagicNumber
39      public static final long MB = 1024 * 1024;
40  
41      private static final long ONE_SECOND = 1000L;
42  
43      private static final long ONE_MINUTE = 60 * ONE_SECOND;
44  
45      private static final long ONE_HOUR = 60 * ONE_MINUTE;
46  
47      private static final long ONE_DAY = 24 * ONE_HOUR;
48      // CHECKSTYLE_ON: MagicNumber
49  
50      public static final String BUILD_VERSION_PROPERTY = "version";
51  
52      public static String showVersion() {
53          return showVersion(null, null);
54      }
55  
56      public static String showVersion(String commandLine, String terminal) {
57          final String ls = System.lineSeparator();
58          Properties properties = getBuildProperties();
59          StringBuilder version = new StringBuilder(256);
60          version.append(MessageUtils.builder().strong(createMavenVersionString(properties)))
61                  .append(ls);
62          version.append(reduce(properties.getProperty("distributionShortName") + " home: "
63                          + System.getProperty("maven.home", "<unknown Maven " + "home>")))
64                  .append(ls);
65          version.append("Java version: ")
66                  .append(System.getProperty("java.version", "<unknown Java version>"))
67                  .append(", vendor: ")
68                  .append(System.getProperty("java.vendor", "<unknown vendor>"))
69                  .append(", runtime: ")
70                  .append(System.getProperty("java.home", "<unknown runtime>"))
71                  .append(ls);
72          version.append("Default locale: ")
73                  .append(Locale.getDefault())
74                  .append(", platform encoding: ")
75                  .append(System.getProperty("file.encoding", "<unknown encoding>"))
76                  .append(ls);
77          version.append("OS name: \"")
78                  .append(Os.OS_NAME)
79                  .append("\", version: \"")
80                  .append(Os.OS_VERSION)
81                  .append("\", arch: \"")
82                  .append(Os.OS_ARCH)
83                  .append("\", family: \"")
84                  .append(Os.OS_FAMILY)
85                  .append('\"');
86          // Add process information using modern Java API
87          if (commandLine != null) {
88              version.append(ls).append("Command line: ").append(commandLine);
89          }
90          if (terminal != null) {
91              version.append(ls).append("Terminal: ").append(terminal);
92          }
93          return version.toString();
94      }
95  
96      public static String showVersionMinimal() {
97          Properties properties = getBuildProperties();
98          String version = reduce(properties.getProperty(BUILD_VERSION_PROPERTY));
99          return (version != null ? version : "<version unknown>");
100     }
101 
102     /**
103      * Create a human-readable string containing the Maven version, buildnumber, and time of build
104      *
105      * @param buildProperties The build properties
106      * @return Readable build info
107      */
108     public static String createMavenVersionString(Properties buildProperties) {
109         String version = reduce(buildProperties.getProperty(BUILD_VERSION_PROPERTY));
110         String rev = reduce(buildProperties.getProperty("buildNumber"));
111         String distributionName = reduce(buildProperties.getProperty("distributionName"));
112 
113         return distributionName + " "
114                 + (version != null ? version : "<version unknown>")
115                 + (rev != null ? " (" + rev + ")" : "");
116     }
117 
118     private static String reduce(String s) {
119         return (s != null ? (s.startsWith("${") && s.endsWith("}") ? null : s) : null);
120     }
121 
122     public static Properties getBuildProperties() {
123         Properties properties = new Properties();
124 
125         try (InputStream resourceAsStream =
126                 CLIReportingUtils.class.getResourceAsStream("/org/apache/maven/messages/build.properties")) {
127 
128             if (resourceAsStream != null) {
129                 properties.load(resourceAsStream);
130             }
131         } catch (IOException e) {
132             System.err.println("Unable determine version from JAR file: " + e.getMessage());
133         }
134 
135         return properties;
136     }
137 
138     public static void showError(Logger logger, String message, Throwable e, boolean showStackTrace) {
139         if (logger == null) {
140             System.err.println(message);
141             if (showStackTrace && e != null) {
142                 e.printStackTrace(System.err);
143             }
144             return;
145         }
146         if (showStackTrace) {
147             logger.error(message, e);
148         } else {
149             logger.error(message);
150 
151             if (e != null) {
152                 logger.error(e.getMessage());
153 
154                 for (Throwable cause = e.getCause();
155                         cause != null && cause != cause.getCause();
156                         cause = cause.getCause()) {
157                     logger.error("Caused by: {}", cause.getMessage());
158                 }
159             }
160         }
161     }
162 
163     public static String formatTimestamp(TemporalAccessor instant) {
164         return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(instant);
165     }
166 
167     public static String formatDuration(Duration duration) {
168         long days = duration.toDays();
169         long hours = duration.toHoursPart();
170         long minutes = duration.toMinutesPart();
171         long seconds = duration.toSecondsPart();
172         long millis = duration.toMillisPart();
173 
174         if (days > 0) {
175             return String.format("%d d %02d:%02d h", days, hours, minutes);
176         } else if (hours > 0) {
177             return String.format("%02d:%02d h", hours, minutes);
178         } else if (minutes > 0) {
179             return String.format("%02d:%02d min", minutes, seconds);
180         } else {
181             return String.format("%d.%03d s", seconds, millis);
182         }
183     }
184 }