Coverage Report - org.apache.maven.it.util.cli.CommandLineUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
CommandLineUtils
0%
0/80
0%
0/38
3.444
CommandLineUtils$1
0%
0/8
0%
0/6
3.444
CommandLineUtils$StringStreamConsumer
0%
0/6
N/A
3.444
 
 1  
 package org.apache.maven.it.util.cli;
 2  
 
 3  
 /*
 4  
  * The MIT License
 5  
  *
 6  
  * Copyright (c) 2004, The Codehaus
 7  
  *
 8  
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
 9  
  * this software and associated documentation files (the "Software"), to deal in
 10  
  * the Software without restriction, including without limitation the rights to
 11  
  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 12  
  * of the Software, and to permit persons to whom the Software is furnished to do
 13  
  * so, subject to the following conditions:
 14  
  *
 15  
  * The above copyright notice and this permission notice shall be included in all
 16  
  * copies or substantial portions of the Software.
 17  
  *
 18  
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  
  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 24  
  * SOFTWARE.
 25  
  */
 26  
 
 27  
 import java.io.BufferedReader;
 28  
 import java.io.IOException;
 29  
 import java.io.InputStream;
 30  
 import java.io.InputStreamReader;
 31  
 import java.util.Collections;
 32  
 import java.util.HashMap;
 33  
 import java.util.Iterator;
 34  
 import java.util.Locale;
 35  
 import java.util.Map;
 36  
 import java.util.Properties;
 37  
 
 38  
 /**
 39  
  * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l </a>
 40  
  * @version $Id: CommandLineUtils.java 748485 2009-02-27 11:02:03Z bentmann $
 41  
  */
 42  0
 public abstract class CommandLineUtils
 43  
 {
 44  0
     private static Map processes = Collections.synchronizedMap( new HashMap() );
 45  
 
 46  
     private static Properties envVars;
 47  
 
 48  
     static
 49  
     {
 50  0
         Runtime.getRuntime().addShutdownHook( new Thread( "CommandlineUtil shutdown" )
 51  
         {
 52  0
             public void run()
 53  
             {
 54  0
                 if ( ( processes != null ) && ( processes.size() > 0 ) )
 55  
                 {
 56  0
                     System.err.println( "Destroying " + processes.size() + " processes" );
 57  0
                     for ( Iterator it = processes.values().iterator(); it.hasNext(); )
 58  
                     {
 59  0
                         System.err.println( "Destroying process.." );
 60  0
                         ( (Process) it.next() ).destroy();
 61  
 
 62  
                     }
 63  0
                     System.err.println( "Destroyed " + processes.size() + " processes" );
 64  
                 }
 65  0
             }
 66  
         } );
 67  0
     }
 68  
 
 69  0
     public static class StringStreamConsumer
 70  
         implements StreamConsumer
 71  
     {
 72  0
         private StringBuffer string = new StringBuffer();
 73  
 
 74  0
         private String ls = System.getProperty( "line.separator" );
 75  
 
 76  
         public void consumeLine( String line )
 77  
         {
 78  0
             string.append( line ).append( ls );
 79  0
         }
 80  
 
 81  
         public String getOutput()
 82  
         {
 83  0
             return string.toString();
 84  
         }
 85  
     }
 86  
 
 87  
     public static int executeCommandLine( Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr )
 88  
         throws CommandLineException
 89  
     {
 90  0
         return executeCommandLine( cl, null, systemOut, systemErr );
 91  
     }
 92  
 
 93  
     public static int executeCommandLine( Commandline cl, InputStream systemIn, StreamConsumer systemOut,
 94  
                                           StreamConsumer systemErr )
 95  
         throws CommandLineException
 96  
     {
 97  0
         if ( cl == null )
 98  
         {
 99  0
             throw new IllegalArgumentException( "cl cannot be null." );
 100  
         }
 101  
 
 102  
         Process p;
 103  
 
 104  0
         p = cl.execute();
 105  
 
 106  0
         processes.put( new Long( cl.getPid() ), p );
 107  
 
 108  0
         StreamFeeder inputFeeder = null;
 109  
 
 110  0
         if ( systemIn != null )
 111  
         {
 112  0
             inputFeeder = new StreamFeeder( systemIn, p.getOutputStream() );
 113  
         }
 114  
 
 115  0
         StreamPumper outputPumper = new StreamPumper( p.getInputStream(), systemOut );
 116  
 
 117  0
         StreamPumper errorPumper = new StreamPumper( p.getErrorStream(), systemErr );
 118  
 
 119  0
         if ( inputFeeder != null )
 120  
         {
 121  0
             inputFeeder.start();
 122  
         }
 123  
 
 124  0
         outputPumper.start();
 125  
 
 126  0
         errorPumper.start();
 127  
 
 128  
         try
 129  
         {
 130  0
             int returnValue = p.waitFor();
 131  
 
 132  0
             if ( inputFeeder != null )
 133  
             {
 134  0
                 synchronized ( inputFeeder )
 135  
                 {
 136  0
                     if ( !inputFeeder.isDone() )
 137  
                     {
 138  0
                         inputFeeder.wait();
 139  
                     }
 140  0
                 }
 141  
             }
 142  
 
 143  0
             synchronized ( outputPumper )
 144  
             {
 145  0
                 if ( !outputPumper.isDone() )
 146  
                 {
 147  0
                     outputPumper.wait();
 148  
                 }
 149  0
             }
 150  
 
 151  0
             synchronized ( errorPumper )
 152  
             {
 153  0
                 if ( !errorPumper.isDone() )
 154  
                 {
 155  0
                     errorPumper.wait();
 156  
                 }
 157  0
             }
 158  
 
 159  0
             processes.remove( new Long( cl.getPid() ) );
 160  
 
 161  0
             return returnValue;
 162  
         }
 163  0
         catch ( InterruptedException ex )
 164  
         {
 165  0
             killProcess( cl.getPid() );
 166  0
             throw new CommandLineException( "Error while executing external command, process killed.", ex );
 167  
         }
 168  
         finally
 169  
         {
 170  0
             if ( inputFeeder != null )
 171  
             {
 172  0
                 inputFeeder.close();
 173  
             }
 174  
 
 175  0
             outputPumper.close();
 176  
 
 177  0
             errorPumper.close();
 178  
         }
 179  
     }
 180  
 
 181  
     public static Properties getSystemEnvVars()
 182  
         throws IOException
 183  
     {
 184  0
         if ( envVars == null )
 185  
         {
 186  0
             envVars = getSystemEnvVars( true );
 187  
         }
 188  
 
 189  0
         Properties props = new Properties();
 190  0
         props.putAll( envVars );
 191  0
         return props;
 192  
     }
 193  
 
 194  
     /**
 195  
      * Return the shell environment variables. If <code>caseSensitive == true</code>, then envar
 196  
      * keys will all be upper-case.
 197  
      *
 198  
      * @param caseSensitive Whether environment variable keys should be treated case-sensitively.
 199  
      * @return Properties object of (possibly modified) envar keys mapped to their values.
 200  
      * @throws IOException
 201  
      */
 202  
     public static Properties getSystemEnvVars( boolean caseSensitive )
 203  
         throws IOException
 204  
     {
 205  0
         Process p = null;
 206  
 
 207  0
         Properties envVars = new Properties();
 208  
 
 209  0
         Runtime r = Runtime.getRuntime();
 210  
 
 211  0
         String os = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
 212  
 
 213  
         //If this is windows set the shell to command.com or cmd.exe with correct arguments.
 214  0
         if ( os.indexOf( "windows" ) != -1 )
 215  
         {
 216  0
             if ( os.indexOf( "95" ) != -1 || os.indexOf( "98" ) != -1 || os.indexOf( "Me" ) != -1 )
 217  
             {
 218  0
                 p = r.exec( "command.com /c set" );
 219  
             }
 220  
             else
 221  
             {
 222  0
                 p = r.exec( "cmd.exe /c set" );
 223  
             }
 224  
         }
 225  
         else
 226  
         {
 227  0
             p = r.exec( "env" );
 228  
         }
 229  
 
 230  0
         BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
 231  
 
 232  
         String line;
 233  
 
 234  0
         String lastKey = null;
 235  0
         String lastVal = null;
 236  
 
 237  0
         while ( ( line = br.readLine() ) != null )
 238  
         {
 239  0
             int idx = line.indexOf( '=' );
 240  
 
 241  0
             if ( idx > 1 )
 242  
             {
 243  0
                 lastKey = line.substring( 0, idx );
 244  
 
 245  0
                 if ( !caseSensitive )
 246  
                 {
 247  0
                     lastKey = lastKey.toUpperCase();
 248  
                 }
 249  
 
 250  0
                 lastVal = line.substring( idx + 1 );
 251  
 
 252  0
                 envVars.setProperty( lastKey, lastVal );
 253  
             }
 254  0
             else if ( lastKey != null )
 255  
             {
 256  0
                 lastVal += "\n" + line;
 257  
 
 258  0
                 envVars.setProperty( lastKey, lastVal );
 259  
             }
 260  0
         }
 261  
 
 262  0
         return envVars;
 263  
     }
 264  
 
 265  
     /**
 266  
      * Kill a process launched by executeCommandLine methods
 267  
      * Doesn't work correctly on windows, only the cmd process will be destroy but not the sub process (<a href="http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4770092">Bug ID 4770092</a>)
 268  
      *
 269  
      * @param pid The pid of command return by Commandline.getPid()
 270  
      */
 271  
     public static void killProcess( long pid )
 272  
     {
 273  0
         Process p = (Process) processes.get( new Long( pid ) );
 274  
 
 275  0
         if ( p != null )
 276  
         {
 277  0
             p.destroy();
 278  0
             System.out.println( "killed." );
 279  0
             processes.remove( new Long( pid ) );
 280  
         }
 281  
         else
 282  
         {
 283  0
             System.out.println( "don't exist." );
 284  
         }
 285  0
     }
 286  
 
 287  
     public static boolean isAlive( long pid )
 288  
     {
 289  0
         return ( processes.get( new Long( pid ) ) != null );
 290  
     }
 291  
 
 292  
 }