initial commit
[jalview.git] / forester / java / src / org / forester / util / ThreadedStreamHandler.java
1 // $Id:
2 /**
3  * This class is intended to be used with the SystemCommandExecutor class to let
4  * users execute system commands from Java applications.
5  * 
6  * This class is based on work that was shared in a JavaWorld article named
7  * "When System.exec() won't". That article is available at this url:
8  * 
9  * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
10  * 
11  * Documentation for this class is available at this URL:
12  * 
13  * http://devdaily.com/java/java-processbuilder-process-system-exec
14  * 
15  * 
16  * Copyright 2010 alvin j. alexander, devdaily.com.
17  * 
18  * This program is free software: you can redistribute it and/or modify it under
19  * the terms of the GNU Lesser Public License as published by the Free Software
20  * Foundation, either version 3 of the License, or (at your option) any later
21  * version.
22  * 
23  * This program is distributed in the hope that it will be useful, but WITHOUT
24  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25  * FOR A PARTICULAR PURPOSE. See the GNU Lesser Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser Public License along with
28  * this program. If not, see <http://www.gnu.org/licenses/>.
29  * 
30  * Please ee the following page for the LGPL license:
31  * http://www.gnu.org/licenses/lgpl.txt
32  * 
33  */
34
35 package org.forester.util;
36
37 import java.io.BufferedReader;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.io.OutputStream;
42 import java.io.PrintWriter;
43
44 class ThreadedStreamHandler extends Thread {
45
46     InputStream     inputStream;
47     String          adminPassword;
48     OutputStream    outputStream;
49     PrintWriter     printWriter;
50     StringBuilder   outputBuffer    = new StringBuilder( 65536 );
51     private boolean sudoIsRequested = false;
52
53     /**
54      * A simple constructor for when the sudo command is not necessary.
55      * This constructor will just run the command you provide, without
56      * running sudo before the command, and without expecting a password.
57      * 
58      * @param inputStream
59      * @param streamType
60      */
61     ThreadedStreamHandler( final InputStream inputStream ) {
62         this.inputStream = inputStream;
63     }
64
65     /**
66      * Use this constructor when you want to invoke the 'sudo' command.
67      * The outputStream must not be null. If it is, you'll regret it. :)
68      * 
69      * TODO this currently hangs if the admin password given for the sudo command is wrong.
70      * 
71      * @param inputStream
72      * @param streamType
73      * @param outputStream
74      * @param adminPassword
75      */
76     ThreadedStreamHandler( final InputStream inputStream, final OutputStream outputStream, final String adminPassword ) {
77         this.inputStream = inputStream;
78         this.outputStream = outputStream;
79         printWriter = new PrintWriter( outputStream );
80         this.adminPassword = adminPassword;
81         sudoIsRequested = true;
82     }
83
84     private void doSleep( final long millis ) {
85         try {
86             Thread.sleep( millis );
87         }
88         catch ( final InterruptedException e ) {
89             // ignore
90         }
91     }
92
93     public StringBuilder getOutputBuffer() {
94         return outputBuffer;
95     }
96
97     @Override
98     public void run() {
99         // on mac os x 10.5.x, when i run a 'sudo' command, i need to write
100         // the admin password out immediately; that's why this code is
101         // here.
102         if ( sudoIsRequested ) {
103             //doSleep(500);
104             printWriter.println( adminPassword );
105             printWriter.flush();
106         }
107         BufferedReader bufferedReader = null;
108         final String newline = ForesterUtil.LINE_SEPARATOR;
109         try {
110             bufferedReader = new BufferedReader( new InputStreamReader( inputStream ) );
111             String line = null;
112             while ( ( line = bufferedReader.readLine() ) != null ) {
113                 // outputBuffer.append( line + "\n" ); // CMZ change
114                 outputBuffer.append( line );
115                 outputBuffer.append( newline );
116             }
117         }
118         catch ( final IOException ioe ) {
119             // TODO handle this better
120             ioe.printStackTrace();
121         }
122         catch ( final Throwable t ) {
123             // TODO handle this better
124             t.printStackTrace();
125         }
126         finally {
127             try {
128                 bufferedReader.close();
129             }
130             catch ( final IOException e ) {
131                 // ignore this one
132             }
133         }
134     }
135 }