001    package org.apache.maven.cli;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.io.PrintStream;
025    import java.text.DateFormat;
026    import java.text.SimpleDateFormat;
027    import java.util.Date;
028    import java.util.Locale;
029    import java.util.Properties;
030    import java.util.TimeZone;
031    
032    import org.codehaus.plexus.logging.Logger;
033    import org.codehaus.plexus.util.IOUtil;
034    import org.codehaus.plexus.util.Os;
035    
036    /**
037     * Utility class used to report errors, statistics, application version info, etc.
038     *
039     * @author jdcasey
040     *
041     */
042    public final class CLIReportingUtils
043    {
044    
045        public static final long MB = 1024 * 1024;
046    
047        public static final int MS_PER_SEC = 1000;
048    
049        public static final int SEC_PER_MIN = 60;
050        
051        public static final String BUILD_VERSION_PROPERTY = "version";
052    
053        public static void showVersion( PrintStream stdout )
054        {
055            Properties properties = getBuildProperties();
056            stdout.println( createMavenVersionString( properties ) );
057            String shortName = reduce( properties.getProperty( "distributionShortName" ) );
058    
059            stdout.println( shortName + " home: " + System.getProperty( "maven.home", "<unknown maven home>" ) );
060    
061            stdout.println( "Java version: " + System.getProperty( "java.version", "<unknown java version>" )
062                + ", vendor: " + System.getProperty( "java.vendor", "<unknown vendor>" ) );
063    
064            stdout.println( "Java home: " + System.getProperty( "java.home", "<unknown java home>" ) );
065    
066            stdout.println( "Default locale: " + Locale.getDefault() + ", platform encoding: "
067                + System.getProperty( "file.encoding", "<unknown encoding>" ) );
068    
069            stdout.println( "OS name: \"" + Os.OS_NAME + "\", version: \"" + Os.OS_VERSION + "\", arch: \"" + Os.OS_ARCH
070                + "\", family: \"" + Os.OS_FAMILY + "\"" );
071        }
072    
073        /**
074         * Create a human readable string containing the Maven version, buildnumber, and time of build
075         * 
076         * @param buildProperties The build properties
077         * @return Readable build info
078         */
079        static String createMavenVersionString( Properties buildProperties )
080        {
081            String timestamp = reduce( buildProperties.getProperty( "timestamp" ) );
082            String version = reduce( buildProperties.getProperty( BUILD_VERSION_PROPERTY ) );
083            String rev = reduce( buildProperties.getProperty( "buildNumber" ) );
084            String distributionName = reduce( buildProperties.getProperty( "distributionName" ) );
085    
086            String msg = distributionName + " ";
087            msg += ( version != null ? version : "<version unknown>" );
088            if ( rev != null || timestamp != null )
089            {
090                msg += " (";
091                msg += ( rev != null ? "r" + rev : "" );
092                if ( timestamp != null )
093                {
094                    SimpleDateFormat fmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ssZ" );
095                    String ts = fmt.format( new Date( Long.valueOf( timestamp ).longValue() ) );
096                    msg += ( rev != null ? "; " : "" ) + ts;
097                }
098                msg += ")";
099            }
100            return msg;
101        }
102    
103        private static String reduce( String s )
104        {
105            return ( s != null ? ( s.startsWith( "${" ) && s.endsWith( "}" ) ? null : s ) : null );
106        }
107    
108    
109        private static void stats( Date start, Logger logger )
110        {
111            Date finish = new Date();
112    
113            long time = finish.getTime() - start.getTime();
114    
115            logger.info( "Total time: " + formatTime( time ) );
116    
117            logger.info( "Finished at: " + finish );
118    
119            //noinspection CallToSystemGC
120            System.gc();
121    
122            Runtime r = Runtime.getRuntime();
123    
124            logger.info( "Final Memory: " + ( r.totalMemory() - r.freeMemory() ) / MB + "M/" + r.totalMemory() / MB + "M" );
125        }
126    
127        private static String formatTime( long ms )
128        {
129            long secs = ms / MS_PER_SEC;
130    
131            long min = secs / SEC_PER_MIN;
132    
133            secs = secs % SEC_PER_MIN;
134    
135            String msg = "";
136    
137            if ( min > 1 )
138            {
139                msg = min + " minutes ";
140            }
141            else if ( min == 1 )
142            {
143                msg = "1 minute ";
144            }
145    
146            if ( secs > 1 )
147            {
148                msg += secs + " seconds";
149            }
150            else if ( secs == 1 )
151            {
152                msg += "1 second";
153            }
154            else if ( min == 0 )
155            {
156                msg += "< 1 second";
157            }
158            return msg;
159        }
160    
161        private static String getFormattedTime( long time )
162        {
163            String pattern = "s.SSS's'";
164            if ( time / 60000L > 0 )
165            {
166                pattern = "m:s" + pattern;
167                if ( time / 3600000L > 0 )
168                {
169                    pattern = "H:m" + pattern;
170                }
171            }
172            DateFormat fmt = new SimpleDateFormat( pattern );
173            fmt.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
174            return fmt.format( new Date( time ) );
175        }
176    
177        static Properties getBuildProperties()
178        {
179            Properties properties = new Properties();
180            InputStream resourceAsStream = null;
181            try
182            {
183                resourceAsStream = MavenCli.class.getResourceAsStream( "/org/apache/maven/messages/build.properties" );
184    
185                if ( resourceAsStream != null )
186                {
187                    properties.load( resourceAsStream );
188                }
189            }
190            catch ( IOException e )
191            {
192                System.err.println( "Unable determine version from JAR file: " + e.getMessage() );
193            }
194            finally
195            {
196                IOUtil.close( resourceAsStream );
197            }
198    
199            return properties;
200        }
201    
202        public static void showError( Logger logger, String message, Throwable e, boolean showStackTrace )
203        {
204            if ( logger == null )
205            {
206                logger = new PrintStreamLogger( System.out );
207            }
208    
209            if ( showStackTrace )
210            {
211                logger.error( message, e );
212            }
213            else
214            {
215                logger.error( message );
216    
217                if ( e != null )
218                {
219                    logger.error( e.getMessage() );
220    
221                    for ( Throwable cause = e.getCause(); cause != null; cause = cause.getCause() )
222                    {
223                        logger.error( "Caused by: " + cause.getMessage() );
224                    }
225                }
226            }
227        }
228    
229    }