View Javadoc

1   package org.codehaus.mojo.fitnesse.plexus;
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.InputStream;
28  
29  import org.codehaus.plexus.util.cli.StreamConsumer;
30  import org.codehaus.plexus.util.cli.StreamFeeder;
31  import org.codehaus.plexus.util.cli.StreamPumper;
32  
33  /**
34   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l </a>
35   * @version $Id: FCommandLineUtils.java 6588 2008-03-28 12:22:57Z bentmann $
36   */
37  public abstract class FCommandLineUtils
38  {
39      public static class StringStreamConsumer
40          implements StreamConsumer
41      {
42          private StringBuffer string = new StringBuffer();
43  
44          private String ls = System.getProperty( "line.separator" );
45  
46          public void consumeLine( String line )
47          {
48              string.append( line + ls );
49          }
50  
51          public String getOutput()
52          {
53              return string.toString();
54          }
55      }
56  
57      public static int executeCommandLine( FCommandline cl, StreamConsumer systemOut, StreamConsumer systemErr )
58          throws FCommandLineException
59      {
60          return executeCommandLine( cl, null, systemOut, systemErr );
61      }
62  
63      public static int executeCommandLine( FCommandline cl, InputStream systemIn, StreamConsumer systemOut,
64                                            StreamConsumer systemErr )
65          throws FCommandLineException
66      {
67          if ( cl == null )
68          {
69              throw new IllegalArgumentException( "cl cannot be null." );
70          }
71  
72          Process p = null;
73  
74          p = cl.execute();
75          Thread tKiller = new KillerThread( p );
76          Runtime.getRuntime().addShutdownHook( tKiller );
77          StreamFeeder inputFeeder = null;
78  
79          if ( systemIn != null )
80          {
81              inputFeeder = new StreamFeeder( systemIn, p.getOutputStream() );
82          }
83  
84          StreamPumper outputPumper = new StreamPumper( p.getInputStream(), systemOut );
85  
86          StreamPumper errorPumper = new StreamPumper( p.getErrorStream(), systemErr );
87  
88          if ( inputFeeder != null )
89          {
90              inputFeeder.start();
91          }
92  
93          outputPumper.start();
94  
95          errorPumper.start();
96  
97          try
98          {
99              int returnValue = p.waitFor();
100             if ( inputFeeder != null )
101             {
102                 synchronized ( inputFeeder )
103                 {
104                     if ( !inputFeeder.isDone() )
105                     {
106                         inputFeeder.wait();
107                     }
108                 }
109             }
110 
111             if ( outputPumper != null )
112             {
113                 synchronized ( outputPumper )
114                 {
115                     if ( !outputPumper.isDone() )
116                     {
117                         outputPumper.wait();
118                     }
119                 }
120             }
121 
122             if ( errorPumper != null )
123             {
124                 synchronized ( errorPumper )
125                 {
126                     if ( !errorPumper.isDone() )
127                     {
128                         errorPumper.wait();
129                     }
130                 }
131             }
132             Runtime.getRuntime().removeShutdownHook( tKiller );
133 
134             return returnValue;
135         }
136         catch ( InterruptedException ex )
137         {
138             throw new FCommandLineException( "Error while executing external command.", ex );
139         }
140         finally
141         {
142             if ( inputFeeder != null )
143             {
144                 inputFeeder.close();
145             }
146 
147             outputPumper.close();
148 
149             errorPumper.close();
150         }
151     }
152 
153     public static class KillerThread
154         extends Thread
155     {
156         public KillerThread( Process pProcess )
157         {
158             mProcessToKill = pProcess;
159         }
160 
161         Process mProcessToKill;
162 
163         public void run()
164         {
165             super.run();
166             if ( mProcessToKill != null )
167             {
168                 System.err.println( "Sub process has been closed by destroy()" );
169                 System.err.flush();
170                 mProcessToKill.destroy();
171             }
172             else
173             {
174                 System.err.println( "Should kill Sub process but was null" );
175                 System.err.flush();
176             }
177         }
178 
179     }
180 }