processing.app.exec.StreamPump Maven / Gradle / Ivy
package processing.app.exec;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import processing.app.Base;
/**
* A StreamPump reads lines of text from its given InputStream
* and informs its LineProcessors until the InputStream is exhausted.
* It is useful only for pumping lines of text, and not for arbitrary
* binary cruft. It's handy for reading the output of processes that
* emit textual data, for example.
*
* @author Jonathan Feinberg <[email protected]>
*
*/
public class StreamPump implements Runnable {
private static final ExecutorService threads =
Executors.newCachedThreadPool(new ThreadFactory() {
public Thread newThread(final Runnable r) {
final Thread t = new Thread(r);
t.setDaemon(true);
t.setName("StreamPump " + t.getId());
return t;
}
});
private final BufferedReader reader;
private final List outs = new CopyOnWriteArrayList();
private final String name;
public StreamPump(final InputStream in, final String name) {
this.reader = new BufferedReader(new InputStreamReader(in));
this.name = name;
}
public StreamPump addTarget(final OutputStream out) {
outs.add(new WriterLineProcessor(out));
return this;
}
public StreamPump addTarget(final Writer out) {
outs.add(new WriterLineProcessor(out));
return this;
}
public StreamPump addTarget(final LineProcessor out) {
outs.add(out);
return this;
}
public void start() {
// System.out.println("starting new StreamPump");
// new Exception().printStackTrace(EditorConsole.systemOut);
threads.execute(this);
}
public void run() {
try {
String line;
while ((line = reader.readLine()) != null) {
for (final LineProcessor out : outs) {
try {
out.processLine(line);
} catch (final Exception e) {
}
}
}
} catch (final IOException e) {
if (Base.DEBUG) {
System.err.println("StreamPump: " + name);
e.printStackTrace(System.err);
// removing for 0190, but need a better way to handle these
throw new RuntimeException("Inside " + this + " for " + name, e);
}
}
}
private static class WriterLineProcessor implements LineProcessor {
private final PrintWriter writer;
private WriterLineProcessor(final OutputStream out) {
this.writer = new PrintWriter(out, true);
}
private WriterLineProcessor(final Writer writer) {
this.writer = new PrintWriter(writer, true);
}
public void processLine(final String line) {
writer.println(line);
}
}
// public static final LineProcessor DEVNULL = new LineProcessor() {
// public void processLine(final String line) {
// // noop
// }
// };
}