KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > nutch > util > CommandRunner


1 /* Copyright (c) 2004 The Nutch Organization. All rights reserved. */
2 /* Use subject to the conditions in http://www.nutch.org/LICENSE.txt. */
3
4 /*
5  * Adopted by John Xing for Nutch Project from
6  * http://blog.fivesight.com/prb/space/Call+an+External+Command+from+Java/,
7  * which explains the code in detail.
8  *
9  * Comments by John Xing on 20040621:
10  * (1) EDU.oswego.cs.dl.util.concurrent.* is in j2sdk 1.5 now.
11  * Modifications are needed if we move to j2sdk 1.5.
12  * (2) The original looks good, not much to change.
13  *
14  * This code is in the public domain and comes with no warranty.
15  */

16 package net.nutch.util;
17
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.OutputStream JavaDoc;
21
22 import EDU.oswego.cs.dl.util.concurrent.BrokenBarrierException;
23 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
24 import EDU.oswego.cs.dl.util.concurrent.TimeoutException;
25
26 public class CommandRunner {
27
28   private boolean _waitForExit = true;
29   private String JavaDoc _command;
30   private int _timeout = 10;
31   private boolean _destroyOnTimeout = true;
32
33   private InputStream JavaDoc _stdin;
34   private OutputStream JavaDoc _stdout;
35   private OutputStream JavaDoc _stderr;
36
37   private static final int BUF = 4096;
38
39   private int _xit;
40
41   private Throwable JavaDoc _thrownError;
42
43   private CyclicBarrier _barrier;
44
45   public int getExitValue() {
46     return _xit;
47   }
48
49   public void setCommand(String JavaDoc s) {
50     _command = s;
51   }
52
53   public String JavaDoc getCommand() {
54     return _command;
55   }
56
57   public void setInputStream(InputStream JavaDoc is) {
58     _stdin = is;
59   }
60
61   public void setStdOutputStream(OutputStream JavaDoc os) {
62     _stdout = os;
63   }
64
65   public void setStdErrorStream(OutputStream JavaDoc os) {
66     _stderr = os;
67   }
68
69   public void evaluate() throws IOException JavaDoc {
70     Process JavaDoc proc = Runtime.getRuntime().exec(_command);
71
72     _barrier = new CyclicBarrier(3 + ((_stdin != null) ? 1 : 0));
73
74     PullerThread so =
75       new PullerThread("STDOUT", proc.getInputStream(), _stdout);
76     so.start();
77
78     PullerThread se =
79       new PullerThread("STDERR", proc.getErrorStream(), _stderr);
80     se.start();
81
82     PusherThread si = null;
83     if (_stdin != null) {
84       si = new PusherThread("STDIN", _stdin, proc.getOutputStream());
85       si.start();
86     }
87
88     boolean _timedout = false;
89     long end = System.currentTimeMillis() + _timeout * 1000;
90
91     try {
92       if (_timeout == 0) {
93         _barrier.barrier();
94       } else {
95         _barrier.attemptBarrier(_timeout * 1000);
96       }
97     } catch (TimeoutException ex) {
98       _timedout = true;
99       if (si != null) {
100         si.interrupt();
101       }
102       so.interrupt();
103       se.interrupt();
104       if (_destroyOnTimeout) {
105         proc.destroy();
106       }
107     } catch (BrokenBarrierException bbe) {
108       /* IGNORE */
109     } catch (InterruptedException JavaDoc e) {
110       /* IGNORE */
111     }
112
113     _xit = -1;
114
115     if (!_timedout) {
116       if (_waitForExit) {
117         do {
118           try {
119             _xit = proc.exitValue();
120             Thread.sleep(250);
121           } catch (InterruptedException JavaDoc ie) {
122             /* IGNORE */
123           } catch (IllegalThreadStateException JavaDoc iltse) {
124             continue;
125           }
126           break;
127         } while (!(_timedout = (System.currentTimeMillis() > end)));
128       } else {
129         try {
130           _xit = proc.exitValue();
131         } catch (IllegalThreadStateException JavaDoc iltse) {
132           _timedout = true;
133         }
134       }
135     }
136
137     if (_timedout) {
138       if (_destroyOnTimeout) {
139         proc.destroy();
140       }
141     }
142   }
143
144   public Throwable JavaDoc getThrownError() {
145     return _thrownError;
146   }
147
148   private class PumperThread extends Thread JavaDoc {
149
150     private OutputStream JavaDoc _os;
151     private InputStream JavaDoc _is;
152
153     private volatile boolean _kaput;
154
155     private boolean _closeInput;
156
157     protected PumperThread(
158       String JavaDoc name,
159       InputStream JavaDoc is,
160       OutputStream JavaDoc os,
161       boolean closeInput) {
162       super(name);
163       _is = is;
164       _os = os;
165       _closeInput = closeInput;
166     }
167
168     public void run() {
169       _kaput = false;
170       try {
171         byte[] buf = new byte[BUF];
172         int read = 0;
173         while (!isInterrupted() && (read = _is.read(buf)) != -1) {
174           if (read == 0)
175             continue;
176           _os.write(buf, 0, read);
177           _os.flush();
178         }
179       } catch (Throwable JavaDoc t) {
180         _thrownError = t;
181         return;
182       } finally {
183         try {
184           if (_closeInput) {
185             _is.close();
186           } else {
187             _os.close();
188           }
189         } catch (IOException JavaDoc ioe) {
190           /* IGNORE */
191         }
192       }
193       try {
194         _barrier.barrier();
195       } catch (InterruptedException JavaDoc ie) {
196         /* IGNORE */
197       } catch (BrokenBarrierException bbe) {
198         /* IGNORE */
199       }
200     }
201   }
202
203   private class PusherThread extends PumperThread {
204     PusherThread(String JavaDoc name, InputStream JavaDoc is, OutputStream JavaDoc os) {
205       super(name, is, os, false);
206     }
207   }
208
209   private class PullerThread extends PumperThread {
210     PullerThread(String JavaDoc name, InputStream JavaDoc is, OutputStream JavaDoc os) {
211       super(name, is, os, true);
212     }
213   }
214
215   public int getTimeout() {
216     return _timeout;
217   }
218
219   public void setTimeout(int timeout) {
220     _timeout = timeout;
221   }
222
223   public boolean getDestroyOnTimeout() {
224     return _destroyOnTimeout;
225   }
226
227   public void setDestroyOnTimeout(boolean destroyOnTimeout) {
228     _destroyOnTimeout = destroyOnTimeout;
229   }
230
231   public boolean getWaitForExit() {
232     return _waitForExit;
233   }
234
235   public void setWaitForExit(boolean waitForExit) {
236     _waitForExit = waitForExit;
237   }
238
239   public static void main(String JavaDoc[] args) throws Exception JavaDoc {
240     String JavaDoc commandPath = null;
241     String JavaDoc filePath = null;
242     int timeout = 10;
243
244     String JavaDoc usage = "Usage: CommandRunner [-timeout timeout] commandPath filePath";
245
246     if (args.length < 2) {
247       System.err.println(usage);
248       System.exit(-1);
249     }
250
251     for (int i = 0; i < args.length; i++) {
252       if (args[i].equals("-timeout")) {
253         timeout = Integer.parseInt(args[++i]);;
254       } else if (i != args.length-2) {
255         System.err.println(usage);
256         System.exit(-1);
257       } else {
258         commandPath = args[i];
259         filePath = args[++i];
260       }
261     }
262
263     CommandRunner cr = new CommandRunner();
264
265     cr.setCommand(commandPath);
266     cr.setInputStream(new java.io.FileInputStream JavaDoc(filePath));
267     cr.setStdErrorStream(System.err);
268     cr.setStdOutputStream(System.out);
269
270     cr.setTimeout(timeout);
271
272     cr.evaluate();
273
274     System.err.println("output value: "+cr.getExitValue());
275   }
276 }
277
Popular Tags