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