KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > exolab > jms > net > jvm > Executor


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "Exolab" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of Exoffice Technologies. For written permission,
18  * please contact info@exolab.org.
19  *
20  * 4. Products derived from this Software may not be called "Exolab"
21  * nor may "Exolab" appear in their names without prior written
22  * permission of Exoffice Technologies. Exolab is a registered
23  * trademark of Exoffice Technologies.
24  *
25  * 5. Due credit should be given to the Exolab Project
26  * (http://www.exolab.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 2001-2004 (C) Exoffice Technologies Inc. All Rights Reserved.
42  *
43  * $Id: Executor.java,v 1.1 2004/11/26 01:51:10 tanderson Exp $
44  */

45 package org.exolab.jms.net.jvm;
46
47 import java.io.BufferedReader JavaDoc;
48 import java.io.InputStream JavaDoc;
49 import java.io.InputStreamReader JavaDoc;
50 import java.io.IOException JavaDoc;
51 import java.io.OutputStream JavaDoc;
52 import java.io.PrintStream JavaDoc;
53
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56
57
58 /**
59  * This class enables commands to be executed, with the output being
60  * captured, or echoed to System.out and System.err
61  *
62  * @version $Revision: 1.1 $ $Date: 2004/11/26 01:51:10 $
63  * @author <a HREF="mailto:tma@netspace.net.au">Tim Anderson</a>
64  */

65 public class Executor {
66
67     /**
68      * The command to execute
69      */

70     private final String JavaDoc _command;
71
72     /**
73      * The stream to direct standard out to
74      */

75     private final OutputStream JavaDoc _out;
76
77     /**
78      * The stream to direct standard err to
79      */

80     private final OutputStream JavaDoc _err;
81
82     /**
83      * The thread for _out
84      */

85     private Thread JavaDoc _outThread;
86
87     /**
88      * The thread for _err
89      */

90     private Thread JavaDoc _errThread;
91
92     /**
93      * The executing process
94      */

95     private volatile Process JavaDoc _process;
96
97     /**
98      * The logger
99      */

100     private static final Log _log = LogFactory.getLog(Executor.class);
101
102
103     /**
104      * Constructor to execute a command, with output going to System.out and
105      * System.err
106      *
107      * @param command the command to execute
108      */

109     public Executor(String JavaDoc command) {
110         this(command, System.out, System.err);
111     }
112
113     /**
114      * Constructor to execute a command, with all output going to a stream
115      *
116      * @param command the command to execute
117      * @param log the stream to log output to
118      */

119     public Executor(String JavaDoc command, OutputStream JavaDoc log) {
120         this(command, log, log);
121     }
122
123     /**
124      * Constructor to execute a command with standard output and error output
125      * going to two separate streams
126      *
127      * @param command the command to execute
128      * @param out the stream to direct standard output to
129      * @param err the stream to direct standard error to
130      */

131     public Executor(String JavaDoc command, OutputStream JavaDoc out, OutputStream JavaDoc err) {
132         if (command == null) {
133             throw new IllegalArgumentException JavaDoc("Argument 'command' is null");
134         }
135         if (out == null) {
136             throw new IllegalArgumentException JavaDoc("Argument 'out' is null");
137         }
138         if (err == null) {
139             throw new IllegalArgumentException JavaDoc("Argument 'err' is null");
140         }
141         _command = command;
142         _out = out;
143         _err = err;
144     }
145
146     /**
147      * Start the command
148      *
149      * @throws IOException if the command cannot be started
150      */

151     public void start() throws IOException JavaDoc {
152         _log.debug("Starting " + _command);
153         _process = Runtime.getRuntime().exec(_command);
154         Reader JavaDoc out = new Reader JavaDoc(_process.getInputStream(), _out);
155         Reader JavaDoc err = new Reader JavaDoc(_process.getErrorStream(), _err);
156         _outThread = new Thread JavaDoc(out, "StdOut<" + _command + ">");
157         _errThread = new Thread JavaDoc(err, "StdErr<" + _command + ">");
158         _outThread.start();
159         _errThread.start();
160         
161     }
162
163     /**
164      * Wait for the command to finish
165      *
166      * @return the command exit status
167      */

168     public int waitFor() {
169         boolean done = false;
170         int status = 1;
171
172         while (!done) {
173             try {
174                 status = _process.waitFor();
175                 done = true;
176             } catch (InterruptedException JavaDoc ignore) {
177                 // do nothing
178
}
179         }
180
181         while (true) {
182             try {
183                 _outThread.join();
184                 break;
185             } catch (InterruptedException JavaDoc ignore) {
186                 // do nothing
187
}
188         }
189
190         while (true) {
191             try {
192                 _errThread.join();
193                 break;
194             } catch (InterruptedException JavaDoc ignore) {
195                 // do nothing
196
}
197         }
198
199         _outThread = null;
200         _errThread = null;
201         _process = null;
202
203         return status;
204     }
205
206     /**
207      * Execute the command and wait for it to complete
208      *
209      * @return the command exit status
210      * @throws IOException if the command cannot be executed
211      */

212     public int run() throws IOException JavaDoc {
213         start();
214         return waitFor();
215     }
216
217     /**
218      * Stop the process
219      */

220     public void stop() {
221         Process JavaDoc process = _process;
222         if (process != null) {
223             _log.debug("Stopping " + _command);
224             process.destroy();
225         }
226     }
227
228     /**
229      * Helper class that reads from one stream and writes to another, in a
230      * separate thread.
231      */

232     class Reader implements Runnable JavaDoc {
233
234         /**
235          * The thread executing the reader instance
236          */

237         private volatile Thread JavaDoc _thread = null;
238
239         /**
240          * The input stream
241          */

242         private BufferedReader JavaDoc _input = null;
243
244         /**
245          * The output stream
246          */

247         private PrintStream JavaDoc _output = null;
248
249         /**
250          * The exception, if an exception was generated while performing I/O
251          */

252         private Exception JavaDoc _exception = null;
253
254         /**
255          * Construct a reader, reading from the input stream and writing to
256          * the output stream
257          *
258          * @param input the input stream
259          * @param output the output stream
260          */

261         public Reader(InputStream JavaDoc input, OutputStream JavaDoc output) {
262             _input = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(input));
263             _output = new PrintStream JavaDoc(output);
264         }
265
266         /**
267          * Run the reader
268          */

269         public void run() {
270             _thread = Thread.currentThread();
271             String JavaDoc line;
272             try {
273                 while (_thread != null && (line = _input.readLine()) != null) {
274                     _output.println(line);
275                 }
276             } catch (IOException JavaDoc exception) {
277                 // terminate this on an I/O error.
278
_exception = exception;
279                 _thread = null;
280             }
281             _input = null;
282             _output = null;
283         }
284
285         /**
286          * Stop the reader
287          */

288         public void stop() {
289             if (_thread != null) {
290                 Thread JavaDoc interrupter = _thread;
291                 _thread = null;
292                 interrupter.interrupt();
293             }
294         }
295
296         /**
297          * Returns the exception if one was generated. If {@link #stop} was
298          * invoked then an exception is likely to have been generated.
299          */

300         public Exception JavaDoc getException() {
301             return _exception;
302         }
303     }
304
305 }
306
Popular Tags