Coverage Report - org.codehaus.plexus.util.cli.CommandLineUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
CommandLineUtils
0%
0/75
0%
0/36
3,333
CommandLineUtils$1
0%
0/8
0%
0/6
3,333
CommandLineUtils$StringStreamConsumer
0%
0/6
N/A
3,333
 
 1  
 package org.codehaus.plexus.util.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 java.io.BufferedReader;
 23  
 import java.io.IOException;
 24  
 import java.io.InputStream;
 25  
 import java.io.InputStreamReader;
 26  
 import java.util.Collections;
 27  
 import java.util.HashMap;
 28  
 import java.util.Iterator;
 29  
 import java.util.Map;
 30  
 import java.util.Properties;
 31  
 
 32  
 /**
 33  
  * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l </a>
 34  
  * @version $Id: CommandLineUtils.java 591654 2007-11-03 17:14:56Z dennisl $
 35  
  */
 36  0
 public abstract class CommandLineUtils
 37  
 {
 38  0
     private static Map processes = Collections.synchronizedMap( new HashMap() );
 39  
 
 40  
     static
 41  
     {
 42  0
         Runtime.getRuntime().addShutdownHook( new Thread( "CommandlineUtil shutdown" )
 43  
         {
 44  0
             public void run()
 45  
             {
 46  0
                 if ( ( processes != null ) && ( processes.size() > 0 ) )
 47  
                 {
 48  0
                     System.err.println( "Destroying " + processes.size() + " processes" );
 49  0
                     for ( Iterator it = processes.values().iterator(); it.hasNext(); )
 50  
                     {
 51  0
                         System.err.println( "Destroying process.." );
 52  0
                         ( (Process) it.next() ).destroy();
 53  
 
 54  
                     }
 55  0
                     System.err.println( "Destroyed " + processes.size() + " processes" );
 56  
                 }
 57  0
             }
 58  
         } );
 59  0
     }
 60  
 
 61  0
     public static class StringStreamConsumer
 62  
         implements StreamConsumer
 63  
     {
 64  0
         private StringBuffer string = new StringBuffer();
 65  
 
 66  0
         private String ls = System.getProperty( "line.separator" );
 67  
 
 68  
         public void consumeLine( String line )
 69  
         {
 70  0
             string.append( line + ls );
 71  0
         }
 72  
 
 73  
         public String getOutput()
 74  
         {
 75  0
             return string.toString();
 76  
         }
 77  
     }
 78  
 
 79  
     public static int executeCommandLine( Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr )
 80  
         throws CommandLineException
 81  
     {
 82  0
         return executeCommandLine( cl, null, systemOut, systemErr );
 83  
     }
 84  
 
 85  
     public static int executeCommandLine( Commandline cl, InputStream systemIn, StreamConsumer systemOut,
 86  
                                           StreamConsumer systemErr )
 87  
         throws CommandLineException
 88  
     {
 89  0
         if ( cl == null )
 90  
         {
 91  0
             throw new IllegalArgumentException( "cl cannot be null." );
 92  
         }
 93  
 
 94  
         Process p;
 95  
 
 96  0
         p = cl.execute();
 97  
 
 98  0
         processes.put( new Long( cl.getPid() ), p );
 99  
 
 100  0
         StreamFeeder inputFeeder = null;
 101  
 
 102  0
         if ( systemIn != null )
 103  
         {
 104  0
             inputFeeder = new StreamFeeder( systemIn, p.getOutputStream() );
 105  
         }
 106  
 
 107  0
         StreamPumper outputPumper = new StreamPumper( p.getInputStream(), systemOut );
 108  
 
 109  0
         StreamPumper errorPumper = new StreamPumper( p.getErrorStream(), systemErr );
 110  
 
 111  0
         if ( inputFeeder != null )
 112  
         {
 113  0
             inputFeeder.start();
 114  
         }
 115  
 
 116  0
         outputPumper.start();
 117  
 
 118  0
         errorPumper.start();
 119  
 
 120  
         try
 121  
         {
 122  0
             int returnValue = p.waitFor();
 123  
 
 124  0
             if ( inputFeeder != null )
 125  
             {
 126  0
                 synchronized ( inputFeeder )
 127  
                 {
 128  0
                     if ( !inputFeeder.isDone() )
 129  
                     {
 130  0
                         inputFeeder.wait();
 131  
                     }
 132  0
                 }
 133  
             }
 134  
 
 135  0
             synchronized ( outputPumper )
 136  
             {
 137  0
                 if ( !outputPumper.isDone() )
 138  
                 {
 139  0
                     outputPumper.wait();
 140  
                 }
 141  0
             }
 142  
 
 143  0
             synchronized ( errorPumper )
 144  
             {
 145  0
                 if ( !errorPumper.isDone() )
 146  
                 {
 147  0
                     errorPumper.wait();
 148  
                 }
 149  0
             }
 150  
 
 151  0
             processes.remove( new Long( cl.getPid() ) );
 152  
 
 153  0
             return returnValue;
 154  
         }
 155  0
         catch ( InterruptedException ex )
 156  
         {
 157  0
             killProcess( cl.getPid() );
 158  0
             throw new CommandLineException( "Error while executing external command, process killed.", ex );
 159  
         }
 160  
         finally
 161  
         {
 162  0
             if ( inputFeeder != null )
 163  
             {
 164  0
                 inputFeeder.close();
 165  
             }
 166  
 
 167  0
             outputPumper.close();
 168  
 
 169  0
             errorPumper.close();
 170  
         }
 171  
     }
 172  
 
 173  
     public static Properties getSystemEnvVars()
 174  
         throws IOException
 175  
     {
 176  0
         return getSystemEnvVars( true );
 177  
     }
 178  
 
 179  
     /**
 180  
      * Return the shell environment variables. If <code>caseSensitive == true</code>, then envar
 181  
      * keys will all be upper-case.
 182  
      *
 183  
      * @param caseSensitive Whether environment variable keys should be treated case-sensitively.
 184  
      * @return Properties object of (possibly modified) envar keys mapped to their values.
 185  
      * @throws IOException
 186  
      */
 187  
     public static Properties getSystemEnvVars( boolean caseSensitive )
 188  
         throws IOException
 189  
     {
 190  0
         Process p = null;
 191  
 
 192  0
         Properties envVars = new Properties();
 193  
 
 194  0
         Runtime r = Runtime.getRuntime();
 195  
 
 196  0
         String os = System.getProperty( "os.name" ).toLowerCase();
 197  
 
 198  
         //If this is windows set the shell to command.com or cmd.exe with correct arguments.
 199  0
         if ( os.indexOf( "windows" ) != -1 )
 200  
         {
 201  0
             if ( os.indexOf( "95" ) != -1 || os.indexOf( "98" ) != -1 || os.indexOf( "Me" ) != -1 )
 202  
             {
 203  0
                 p = r.exec( "command.com /c set" );
 204  
             }
 205  
             else
 206  
             {
 207  0
                 p = r.exec( "cmd.exe /c set" );
 208  
             }
 209  
         }
 210  
         else
 211  
         {
 212  0
             p = r.exec( "env" );
 213  
         }
 214  
 
 215  0
         BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
 216  
 
 217  
         String line;
 218  
 
 219  0
         String lastKey = null;
 220  0
         String lastVal = null;
 221  
 
 222  0
         while ( ( line = br.readLine() ) != null )
 223  
         {
 224  0
             int idx = line.indexOf( '=' );
 225  
 
 226  0
             if ( idx > 1 )
 227  
             {
 228  0
                 lastKey = line.substring( 0, idx );
 229  
 
 230  0
                 if ( !caseSensitive )
 231  
                 {
 232  0
                     lastKey = lastKey.toUpperCase();
 233  
                 }
 234  
 
 235  0
                 lastVal = line.substring( idx + 1 );
 236  
 
 237  0
                 envVars.setProperty( lastKey, lastVal );
 238  
             }
 239  0
             else if ( lastKey != null )
 240  
             {
 241  0
                 lastVal += "\n" + line;
 242  
 
 243  0
                 envVars.setProperty( lastKey, lastVal );
 244  
             }
 245  
         }
 246  
 
 247  0
         return envVars;
 248  
     }
 249  
 
 250  
     /**
 251  
      * Kill a process launched by executeCommandLine methods
 252  
      * 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>)
 253  
      *
 254  
      * @param pid The pid of command return by Commandline.getPid()
 255  
      */
 256  
     public static void killProcess( long pid )
 257  
     {
 258  0
         Process p = (Process) processes.get( new Long( pid ) );
 259  
 
 260  0
         if ( p != null )
 261  
         {
 262  0
             p.destroy();
 263  0
             System.out.println( "killed." );
 264  0
             processes.remove( new Long( pid ) );
 265  
         }
 266  
         else
 267  
         {
 268  0
             System.out.println( "don't exist." );
 269  
         }
 270  0
     }
 271  
 
 272  
     public static boolean isAlive( long pid )
 273  
     {
 274  0
         return ( processes.get( new Long( pid ) ) != null );
 275  
     }
 276  
 
 277  
 }