/******************************************************************************* * This file is part of the OpenNMS(R) Application. * * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. All rights reserved. * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * This file is a derivative work, containing both original code, included code, * and modified code that was published under the GNU General Public License. * * Original code for this file Copyright (C) 2002 Scott McCrory. * All rights reserved. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see <http://www.gnu.org/licenses/>. * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.core.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.PrintWriter; import org.apache.commons.io.IOUtils; /** * <P> * Captures the output of an InputStream. * </P> * * With acknowledgements to Michael C. Daconta, author of "Java Pitfalls, Time * Saving Solutions, and Workarounds to Improve Programs." and his article in * JavaWorld "When Runtime.exec() Won't". * * See the ExecRunner class for a reference implementation. * * @author <a href="mailto:smccrory@users.sourceforge.net">Scott McCrory </a>. */ public class StreamGobbler extends Thread { /** The {@link InputStream} we're gobbling */ private InputStream in = null; /** The {@link PrintWriter} we'll send the gobbled characters to if asked */ private PrintWriter pwOut = null; /** Our flag to allow us to safely terminate the monitoring thread */ private boolean quit = false; /** * Basic constructor for StreamGobbler. */ public StreamGobbler() { super(); } /** * A simpler constructor for StreamGobbler - defaults to {@link System#out} * * @param in * InputStream */ public StreamGobbler(final InputStream in) { this(); this.in = in; this.pwOut = new PrintWriter(System.out, true); } /** * A more explicit constructor for StreamGobbler where you can tell it * exactly where to relay the output to. Creation date: (9/23/2001 8:48:01 * PM) * * @param in * InputStream * @param out * OutputStream */ public StreamGobbler(final InputStream in, final OutputStream out) { this(); this.in = in; this.pwOut = new PrintWriter(out, true); } /** * A more explicit constructor for StreamGobbler where you can tell it * exactly where to relay the output to. Creation date: (9/23/2001 8:48:01 * PM) * * @param in * InputStream * @param pwOut * PrintWriter */ public StreamGobbler(final InputStream in, final PrintWriter pwOut) { this(); this.in = in; this.pwOut = pwOut; } /** * We override the <code>clone</code> method here to prevent cloning of * our class. * * @throws java.lang.CloneNotSupportedException * To indicate cloning is not allowed * @return Nothing ever really returned since we throw a * CloneNotSupportedException */ public final Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } /** * Tells the StreamGobbler to quit it's operation. This is safer than using * stop() since it uses a semaphore checked in the main wait loop instead of * possibly forcing semaphores to untimely unlock. */ public void quit() { quit = true; } /** * We override the <code>readObject</code> method here to prevent * deserialization of our class for security reasons. * * @param in * java.io.ObjectInputStream * @throws IOException * thrown if a problem occurs */ private final void readObject(final ObjectInputStream in) throws IOException { throw new IOException("Object cannot be deserialized"); } /** * Gobbles up all the stuff coming from the InputStream and sends it to the * OutputStream specified during object construction. */ public void run() { InputStreamReader isr = null; BufferedReader br = null; try { // Set up the input stream isr = new InputStreamReader(in); br = new BufferedReader(isr); // Initialize the temporary results containers String line = null; // Main processing loop which captures the output while ((line = br.readLine()) != null) { if (quit) { break; } else { pwOut.println(line); } } } catch (final Throwable e) { LogUtils.debugf(this, e, "Unable to read lines."); } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(isr); } } /** * We override the <code>writeObject</code> method here to prevent * serialization of our class for security reasons. * * @param out * java.io.ObjectOutputStream * @throws IOException * thrown if a problem occurs */ private final void writeObject(final ObjectOutputStream out) throws IOException { throw new IOException("Object cannot be serialized"); } }