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