KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > groboutils > util > thread > v1 > BackgroundProcess


1 /*
2  * @(#)BackgroundProcess.java 1.0.0 11/17/2000 - 13:41:07
3  *
4  * Copyright (C) 2000,,2003 2002 Matt Albrecht
5  * groboclown@users.sourceforge.net
6  * http://groboutils.sourceforge.net
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all 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
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  */

26
27 package net.sourceforge.groboutils.util.thread.v1;
28
29
30 import java.io.File JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.InputStream JavaDoc;
33 import java.io.OutputStream JavaDoc;
34 import java.io.PipedInputStream JavaDoc;
35 import java.io.PipedOutputStream JavaDoc;
36
37 import java.lang.reflect.Method JavaDoc;
38
39
40 /**
41  * Creates and executes the given process. Ensures that all the output
42  * is properly read without overflowing or dead-locking the process.
43  * Outside of the streaming, this class has an identical API to that
44  * of {@link java.lang.Process}.
45  * <P>
46  * Creation of a background process begins at the creation of this object.
47  * <P>
48  * <H3>Changes for 0.9.1d</H3>
49  * <UL>
50  * <LI>Each IOThreadRunner which handles the background process's
51  * IO have been changed such that they now close the streams when
52  * an EOL is encountered, and have no delay between reads.
53  * </UL>
54  *
55  * @author Matt Albrecht <a HREF="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
56  * @since June 4, 2000 (0.9.1d Alpha)
57  * @version $Date: 2003/02/10 22:52:48 $
58  */

59 public class BackgroundProcess
60 {
61     private Process JavaDoc proc;
62     private OutputStream JavaDoc stdIn;
63     private PipedInputStream JavaDoc outReader;
64     private PipedOutputStream JavaDoc outWriter;
65     private PipedInputStream JavaDoc errReader;
66     private PipedOutputStream JavaDoc errWriter;
67     
68     private IOThreadRunner outThread;
69     private IOThreadRunner errThread;
70     
71     
72     /**
73      *
74      *
75      * @see java.lang.Runtime#exec( String )
76      */

77     public BackgroundProcess( String JavaDoc command )
78         throws IOException JavaDoc
79     {
80         setupProcess( exec( command, null, null ) );
81     }
82     
83     
84     /**
85      * @see java.lang.Runtime#exec( String[] )
86      */

87     public BackgroundProcess( String JavaDoc[] cmdarray )
88         throws IOException JavaDoc
89     {
90         setupProcess( exec( cmdarray, null, null ) );
91     }
92     
93     
94     /**
95      * @see java.lang.Runtime#exec( String[], String[], File )
96      */

97     public BackgroundProcess( String JavaDoc[] cmdarray, String JavaDoc[] envp, File JavaDoc dir )
98         throws IOException JavaDoc
99     {
100         setupProcess( exec( cmdarray, envp, dir ) );
101     }
102     
103     
104     /**
105      * @see java.lang.Runtime#exec( String, String[], File )
106      */

107     public BackgroundProcess( String JavaDoc command, String JavaDoc[] envp, File JavaDoc dir )
108         throws IOException JavaDoc
109     {
110         setupProcess( exec( command, envp, dir ) );
111     }
112     
113     
114     /**
115      * @see java.lang.Runtime#exec( String[], String[] )
116      */

117     public BackgroundProcess( String JavaDoc[] cmdarray, String JavaDoc[] envp )
118         throws IOException JavaDoc
119     {
120         setupProcess( exec( cmdarray, envp, null ) );
121     }
122     
123     
124     /**
125      * @see java.lang.Runtime#exec( String, String[] )
126      */

127     public BackgroundProcess( String JavaDoc command, String JavaDoc[] envp )
128         throws IOException JavaDoc
129     {
130         setupProcess( exec( command, envp, null ) );
131     }
132     
133     
134     /**
135      * Initializes the background process with an existing process.
136      */

137     public BackgroundProcess( Process JavaDoc p )
138         throws IOException JavaDoc
139     {
140         if (p == null)
141         {
142             throw new IllegalArgumentException JavaDoc("no null args");
143         }
144         setupProcess( p );
145     }
146     
147     
148     /**
149      * Get the OutputStream that is sent to the StdIn of the process.
150      */

151     public OutputStream JavaDoc getStdIn()
152     {
153         return this.stdIn;
154     }
155     
156     
157     /**
158      * Get the InputStream that retrieves the data from the StdOut of the
159      * process.
160      */

161     public InputStream JavaDoc getStdOut()
162     {
163         return this.outReader;
164     }
165     
166     
167     /**
168      * Get the InputStream that retrieves the data from the StdErr of the
169      * process.
170      */

171     public InputStream JavaDoc getStdErr()
172     {
173         return this.errReader;
174     }
175     
176     
177     /**
178      * @see java.lang.Process#destroy()
179      */

180     public void destroy()
181     {
182         this.proc.destroy();
183     }
184     
185     
186     /**
187      * @see java.lang.Process#exitValue()
188      */

189     public int exitValue()
190     {
191         return this.proc.exitValue();
192     }
193     
194
195     /**
196      * @see java.lang.Process#waitFor()
197      */

198     public int waitFor()
199             throws InterruptedException JavaDoc
200     {
201         return this.proc.waitFor();
202     }
203     
204     
205     //-------------------------------------------------
206
// Protected methods
207

208     
209     /**
210      * Initalize the process for internal use.
211      */

212     protected void setupProcess( Process JavaDoc p )
213             throws IOException JavaDoc
214     {
215         this.proc = p;
216         
217         this.stdIn = p.getOutputStream();
218         
219         this.outReader = new PipedInputStream JavaDoc();
220         this.outWriter = new PipedOutputStream JavaDoc( this.outReader );
221         
222         this.errReader = new PipedInputStream JavaDoc();
223         this.errWriter = new PipedOutputStream JavaDoc( this.errReader );
224         
225         this.outThread =
226             new IOThreadRunner( p.getInputStream(), this.outWriter );
227         this.outThread.setCloseInputOnStop( true );
228         this.outThread.setCloseOutputOnStop( true );
229         this.outThread.getThread().setSleepTime( 0 );
230
231         this.errThread =
232             new IOThreadRunner( p.getErrorStream(), this.errWriter );
233         this.errThread.setCloseInputOnStop( true );
234         this.errThread.setCloseOutputOnStop( true );
235         this.errThread.getThread().setSleepTime( 0 );
236         
237         
238         this.outThread.start();
239         this.errThread.start();
240     }
241     
242     
243     
244     /**
245      * Invoke the correct Exec method for the given parameters.
246      */

247     protected Process JavaDoc exec( String JavaDoc cmd, String JavaDoc[] env, File JavaDoc dir )
248             throws IOException JavaDoc
249     {
250         Runtime JavaDoc r = Runtime.getRuntime();
251         Process JavaDoc p;
252         if (dir == null)
253         {
254             if (env == null)
255             {
256                 p = r.exec( cmd );
257             }
258             else
259             {
260                 p = r.exec( cmd, env );
261             }
262         }
263         else
264         {
265             p = reflectExec( cmd, env, dir );
266             if (p == null)
267             {
268                 p = r.exec( cmd, setPWD( env, dir ) );
269             }
270         }
271         return p;
272     }
273     
274     
275     /**
276      *
277      */

278     protected static Process JavaDoc exec( String JavaDoc[] cmd, String JavaDoc[] env, File JavaDoc dir )
279             throws IOException JavaDoc
280     {
281         Runtime JavaDoc r = Runtime.getRuntime();
282         Process JavaDoc p;
283         if (dir == null)
284         {
285             if (env == null)
286             {
287                 p = r.exec( cmd );
288             }
289             else
290             {
291                 p = r.exec( cmd, env );
292             }
293         }
294         else
295         {
296             p = reflectExec( cmd, env, dir );
297             if (p == null)
298             {
299                 p = r.exec( cmd, setPWD( env, dir ) );
300             }
301         }
302         return p;
303     }
304     
305     
306     /**
307      * Attempts to invoke the JDK 1.3 exec method with the given dir.
308      * <tt>cmd</tt> is either a String or String[] type.
309      *
310      * @return the generated Process. If the process is <tt>null</tt>,
311      * then another technique must be used to execute the command.
312      */

313     protected static Process JavaDoc reflectExec( Object JavaDoc cmd, String JavaDoc[] env, File JavaDoc dir )
314             throws IOException JavaDoc
315     {
316         try
317         {
318             Runtime JavaDoc r = Runtime.getRuntime();
319             Method JavaDoc m = r.getClass().getMethod( "exec",
320                 new Class JavaDoc[] { cmd.getClass(), String JavaDoc[].class,
321                     File JavaDoc.class }
322                 );
323             if (m == null)
324             {
325                 return null;
326             }
327             return (Process JavaDoc)m.invoke( r, new Object JavaDoc[] { cmd, env, dir } );
328         }
329         catch (java.lang.reflect.InvocationTargetException JavaDoc ite)
330         {
331             Throwable JavaDoc t = ite.getTargetException();
332             if (t instanceof IOException JavaDoc)
333             {
334                 throw (IOException JavaDoc)t;
335             }
336             if (t instanceof RuntimeException JavaDoc)
337             {
338                 throw (RuntimeException JavaDoc)t;
339             }
340             if (t instanceof Error JavaDoc)
341             {
342                 throw (Error JavaDoc)t;
343             }
344             // else swallow it
345
t.printStackTrace();
346         }
347         catch (IllegalAccessException JavaDoc e)
348         {
349             // gulp!
350
}
351         catch (NoSuchMethodException JavaDoc e)
352         {
353             // gulp!
354
}
355         catch (IllegalArgumentException JavaDoc e)
356         {
357             // gulp!
358
}
359         /* allow this to be thrown - it indicates a programatic error
360         catch (NullPointerException e)
361         {
362         }
363         */

364         /* allow this to be thrown
365         catch (ExceptionInInitializerError e)
366         {
367         }
368         */

369         return null;
370     }
371     
372     
373     /**
374      * Don't change <tt>env</tt>!
375      */

376     protected static String JavaDoc[] setPWD( String JavaDoc env[], File JavaDoc dir )
377     {
378         String JavaDoc tmp[];
379         String JavaDoc pwd = "PWD="+dir.getAbsolutePath();
380         if (env == null)
381         {
382             tmp = new String JavaDoc[] { pwd };
383         }
384         else
385         {
386             int len = env.length;
387             tmp = new String JavaDoc[ len ];
388             System.arraycopy( env, 0, tmp, 0, len );
389             String JavaDoc s[] = new String JavaDoc[ len + 1 ];
390             for (int i = 0; i < len; ++i)
391             {
392                 if (tmp[i].startsWith( "PWD=" ))
393                 {
394                     tmp[i] = pwd;
395                     s = null;
396                     break;
397                 }
398                 else
399                 {
400                     s[i] = tmp[i];
401                 }
402             }
403             if (s != null)
404             {
405                 s[ env.length ] = pwd;
406                 tmp = s;
407             }
408         }
409         return tmp;
410     }
411 }
412
Popular Tags