Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/klavergne/process/SmartProcess.java


1   /*
2    * 12/13/2001 - 15:41:35
3    *
4    * ClearCasePlugin.java - Plugin for Jext to integrate ClearCase
5    * Copyright (C) 2001 Kevin LaVergne
6    * klavergne@earthling.net
7    *
8    * This program is free software; you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License
10   * as published by the Free Software Foundation; either version 2
11   * of the License, or any later version.
12   *
13   * This program is distributed in the hope that it will be useful,
14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   * GNU General Public License for more details.
17   *
18   * You should have received a copy of the GNU General Public License
19   * along with this program; if not, write to the Free Software
20   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21   */
22  package com.klavergne.process;
23  
24  import java.io.*;
25  import java.util.*;
26  
27  /**
28   * <p>This class uses the <code>Runtime</code> and <code>Process</code> classes to
29   * execute the given command from inside the VM.</p>
30   * <p>While testing this I found that the <code>Runtime</code> class works a little
31   * differently than Sun's API documentation says. Their documentation says that
32   * <code>Runtime.exec()</code> creates a subprocess without a console window. This
33   * is true if using java.exe, but if you use javaw.exe it does create a console
34   * window.</p>
35   * @author Kevin LaVergne
36   * @version 1.0
37   */
38  public class SmartProcess {
39  
40    /**
41     * The command to execute.
42     */
43    private String command;
44  
45    /**
46     * A boolean value indicating whether the process should handle exceptions.
47     */
48    private boolean handleExceptions;
49  
50    /**
51     * A boolean value indicating whether the process should wait until complete before returning.
52     */
53    private boolean wait;
54  
55    /**
56     * The exit status code of the process.
57     */
58    private int exitStatus = -999;
59  
60    /**
61     * The standard output of the command that is executed.
62     */
63    private StreamReader stdout;
64  
65    /**
66     * The standard error of the command that is executed.
67     */
68    private StreamReader stderr;
69  
70    /**
71     * Creates a new <code>SmartProcess</code> object with the given String as the command.
72     * @param command the command to execute
73     */
74    public SmartProcess(String command) {
75      this(command, true, true);
76    }
77  
78    /**
79     * Creates a new <code>SmartProcess</code> object with the given String as the command.
80     * @param aCommand the command to execute
81     * @param aWait a boolean value indicating whether the process should wait to return until execution is completed
82     */
83    public SmartProcess(String aCommand, boolean aWait) {
84      this(aCommand, aWait, true);
85    }
86  
87    /**
88     * Creates a new <code>SmartProcess</code> object with the given String as the command.
89     * @param aCommand the command to execute
90     * @param aWait a boolean value indicating whether the process should wait to return until execution is completed
91     * @param aHandleExceptions a boolan value indicating whether the process should handle exceptions
92     */
93    public SmartProcess(String aCommand, boolean aWait, boolean aHandleExceptions) {
94      command = aCommand;
95      wait = aWait;
96      handleExceptions = aHandleExceptions;
97    }
98  
99    /**
100    * Returns the command that this process will execute.
101    * @return the command that this process will execute
102    */
103   public String getCommand() {
104     return command;
105   }
106 
107   /**
108    * Sets the command that this process will execute.
109    * @param aCommand the command that this process will execute
110    */
111   public void setCommand(String aCommand) {
112     command = aCommand;
113   }
114 
115   /**
116    * Sets the command that this process will execute.
117    * @param parameters an array of Strings containing the command and all parameters for the command
118    */
119   public void setCommand(String[] parameters) {
120     setCommand(Arrays.asList(parameters));
121   }
122 
123   /**
124    * Sets the command that this process will execute.
125    * @param parameters a List containing the command and all parameters for the command
126    */
127   public void setCommand(List parameters) {
128     StringBuffer sb = new StringBuffer();
129     for (Iterator i = parameters.iterator(); i.hasNext(); )
130       sb.append(' ').append(i.next());
131     command = sb.toString().trim();
132   }
133 
134   /**
135    * Returns a boolean value indicating whether the process should wait to finish
136    * before returning.
137    * @return a boolean value indicating whether the process should wait to finish before returning.
138    */
139   public boolean getWait() {
140     return wait;
141   }
142 
143   /**
144    * Sets the boolean value indicating whether the process should wait to finish
145    * before returning.
146    * @param aWait a boolean value indicating whether the process should wait to finish before returning
147    */
148   public void setWait(boolean aWait) {
149     wait = aWait;
150   }
151 
152   /**
153    * Returns a boolean value indicating whether the process should handle exceptions.
154    * @return a boolean value indicating whether the process should handle exceptions
155    */
156   public boolean getHandleExceptions() {
157     return handleExceptions;
158   }
159 
160   /**
161    * Sets a boolean value indicating whether the process should handle exceptions.
162    * @param aHandleExceptions a boolean value indicating whether the process should handle exceptions
163    */
164   public void setHandleExceptions(boolean aHandleExceptions) {
165     handleExceptions = aHandleExceptions;
166   }
167 
168   /**
169    * Returns the exit status of the process.
170    * @return the exit status of the process
171    */
172   public int getExitStatus() {
173     return exitStatus;
174   }
175 
176   /**
177    * Returns a String containing the text of the standard error from the process.
178    * @return a String containing the text of the standard error from the process
179    */
180   public String getStandardError() {
181     return stderr.flushStream();
182   }
183 
184   /**
185    * Returns a String containing the text of the standard output from the process.
186    * @return a String containing the text of the standard output from the process
187    */
188   public String getStandardOut() {
189     return stdout.flushStream();
190   }
191 
192   /**
193    * Executes the command in a new process.
194    */
195   public void go() {
196     Runtime runtime = Runtime.getRuntime();
197     try {
198       Process process = runtime.exec(command);
199       stdout = new StreamReader(process.getInputStream());
200       stderr = new StreamReader(process.getErrorStream());
201       stdout.start();
202       stderr.start();
203       if (wait) exitStatus = process.waitFor();
204     } catch (Exception ex) {
205       exitStatus = -999;
206       if (handleExceptions) ex.printStackTrace();
207     }
208   }
209 
210   /**
211    * Executes this class with the given commands in separate processes.
212    * @param args command line arguments
213    */
214   public static void main(String[] args) {
215     for (int i = 0; i < args.length; i++) {
216       String cmd = args[i];
217       try {
218         SmartProcess sp = new SmartProcess(cmd);
219         sp.go();
220         System.out.println("exit=" + sp.getExitStatus());
221         System.out.println("stdout:" + sp.getStandardOut());
222         System.out.println("stderr:" + sp.getStandardError());
223       } catch (Exception ex) {
224         ex.printStackTrace();
225         System.exit(-1);
226       }
227     }
228   }
229 
230   /**
231    * This class handles reading the standard out and standard error streams.
232    */
233   private class StreamReader extends Thread {
234 
235     /**
236      * The Reader that this StreamReader will read from.
237      */
238     private BufferedReader inputReader;
239 
240     /**
241      * A StringBuffer that holds the contents of the stream.
242      */
243     private StringBuffer data = new StringBuffer();
244 
245     /**
246      * Creates a new SreamReader object using the given InputStream.
247      * @param inputStream the InputStream to read
248      */
249     public StreamReader(InputStream inputStream) {
250       data = new StringBuffer();
251       inputReader = new BufferedReader(new InputStreamReader(inputStream));
252       data.setLength(0);
253     }
254 
255     /**
256      * Returns the contents of the stream.
257      * @return the contents of the stream
258      */
259     public synchronized String getStream(boolean flush) {
260       String result = "";
261       result = data.toString();
262       if (flush) data.setLength(0);
263       return result;
264     }
265 
266     /**
267      * Executes the reader thread.
268      */
269     public synchronized void run() {
270       String line;
271       try {
272         while ((line = inputReader.readLine()) != null)
273           data.append(line).append("\n");
274       } catch (IOException ex) {
275         if (handleExceptions)
276           ex.printStackTrace();
277       }
278     }
279 
280     /**
281      * Returns the contents of the stream and flushes it.
282      * @return the contents of the stream
283      */
284     public String flushStream() {
285       return getStream(true);
286     }
287   }
288 }