1   package com.mccrory.scott.base;
2   
3   ////////////////////////////////////////////////////////////////////////////////
4   // Copyright (C) 2002  Scott McCrory
5   //
6   // This program is free software; you can redistribute it and/or
7   // modify it under the terms of the GNU General Public License
8   // as published by the Free Software Foundation; either version 2
9   // of the License, or (at your option) any later version.
10  //
11  // This program is distributed in the hope that it will be useful,
12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  // GNU General Public License for more details.
15  //
16  // You should have received a copy of the GNU General Public License
17  // along with this program; if not, write to the Free Software
18  // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  ////////////////////////////////////////////////////////////////////////////////
20  
21  import java.io.BufferedReader;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.InputStreamReader;
25  import java.io.ObjectInputStream;
26  import java.io.ObjectOutputStream;
27  import java.io.OutputStream;
28  import java.io.PrintWriter;
29  
30  /**
31   * <P>Captures the output of an InputStream.</P>
32   *
33   * With acknowledgements to Michael C. Daconta, author of "Java Pitfalls,
34   * Time Saving Solutions, and Workarounds to Improve Programs." and his
35   * article in JavaWorld "When Runtime.exec() Won't".
36   *
37   * See the ExecRunner class for a reference implementation.
38   *
39   * @author <a href="mailto:smccrory@users.sourceforge.net">Scott McCrory</a>.
40   * @version CVS $Id: StreamGobbler.java,v 1.20 2002/08/04 22:04:53 smccrory Exp $
41   */
42  class StreamGobbler extends Thread {
43  
44      /** The input stream we're gobbling **/
45      private InputStream in = null;
46  
47      /** The printwriter we'll send the gobbled characters to if asked**/
48      private PrintWriter pwOut = null;
49  
50      /** Our flag to allow us to safely terminate the monitoring thread **/
51      private boolean quit = false;
52  
53      /** The name of this class to log context without introspection **/
54      private static final String CLASS_NAME = "StreamGobbler";
55  
56      /** The version of this class (filled in by CVS) **/
57      private static final String VERSION = "CVS $Revision: 1.20 $";
58  
59      /**
60       * A simpler constructor for StreamGobbler - defaults to stdout.
61       *
62       * @param in InputStream
63       */
64      public StreamGobbler(InputStream in) {
65  
66          this.in = in;
67          this.pwOut = new PrintWriter(System.out, true);
68  
69      }
70  
71      /**
72       * A more explicit constructor for StreamGobbler where you can tell
73       * it exactly where to relay the output to.
74       * Creation date: (9/23/2001 8:48:01 PM)
75       *
76       * @param in InputStream
77       * @param out OutputStream
78       */
79      public StreamGobbler(InputStream in, OutputStream out) {
80  
81          this.in = in;
82          this.pwOut = new PrintWriter(out, true);
83  
84      }
85  
86      /**
87       * A more explicit constructor for StreamGobbler where you can tell
88       * it exactly where to relay the output to.
89       * Creation date: (9/23/2001 8:48:01 PM)
90       *
91       * @param in InputStream
92       * @param pwOut PrintWriter
93       */
94      public StreamGobbler(InputStream in, PrintWriter pwOut) {
95  
96          this.in = in;
97          this.pwOut = pwOut;
98  
99      }
100 
101     /**
102      * We override the <code>clone</code> method here to prevent cloning of our class.
103      *
104      * @throws CloneNotSupportedException To indicate cloning is not allowed
105      * @return Nothing ever really returned since we throw a CloneNotSupportedException
106      **/
107     public final Object clone() throws CloneNotSupportedException {
108 
109         throw new CloneNotSupportedException();
110 
111     }
112 
113     /**
114      * Tells the StreamGobbler to quit it's operation.
115      * This is safer than using stop() since it uses a semophore checked in the
116      * main wait loop instead of possibly forcing semaphores to untimely unlock.
117      */
118     public void quit() {
119 
120         quit = true;
121 
122     }
123 
124     /**
125      * We override the <code>readObject</code> method here to prevent
126      * deserialization of our class for security reasons.
127      *
128      * @param in java.io.ObjectInputStream
129      * @throws IOException thrown if a problem occurs
130      **/
131     private final void readObject(ObjectInputStream in) throws IOException {
132 
133         throw new IOException("Object cannot be deserialized");
134 
135     }
136 
137     /**
138      * Gobbles up all the stuff coming from the InputStream and
139      * sends it to the OutputStream specified during object construction.
140      **/
141     public void run() {
142 
143         try {
144 
145             // Set up the input stream
146             InputStreamReader isr = new InputStreamReader(in);
147             BufferedReader br = new BufferedReader(isr);
148 
149             // Initialize the temporary results containers
150             String line = null;
151 
152             // Main processing loop which captures the output
153             while ((line = br.readLine()) != null) {
154                 if (quit) {
155                     break;
156                 }
157                 else {
158                     pwOut.println(line);
159                 }
160             }
161 
162         }
163         catch (Exception e) {
164             e.printStackTrace();
165         }
166 
167     }
168 
169     /**
170      * We override the <code>writeObject</code> method here to prevent
171      * serialization of our class for security reasons.
172      *
173      * @param out java.io.ObjectOutputStream
174      * @throws IOException thrown if a problem occurs
175      **/
176     private final void writeObject(ObjectOutputStream out) throws IOException {
177 
178         throw new IOException("Object cannot be serialized");
179 
180     }
181 
182 }