org.apache.karaf.util.process.PumpStreamHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.karaf.util Show documentation
Show all versions of org.apache.karaf.util Show documentation
Karaf Util contains utility classes used in different Karaf modules.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.karaf.util.process;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
/**
* Copies standard output and error of children streams to standard output and error of the parent.
*/
public class PumpStreamHandler {
private final InputStream in;
private final OutputStream out;
private final OutputStream err;
private final String name;
private StreamPumper outputPump;
private StreamPumper errorPump;
private StreamPumper inputPump;
//
// NOTE: May want to use a ThreadPool here, 3 threads per/pair seems kinda expensive :-(
//
public PumpStreamHandler(final InputStream in, final OutputStream out, final OutputStream err, String name) {
assert in != null;
assert out != null;
assert err != null;
assert name != null;
this.in = in;
this.out = out;
this.err = err;
this.name = name;
}
public PumpStreamHandler(final InputStream in, final OutputStream out, final OutputStream err) {
this(in, out, err, "");
}
public PumpStreamHandler(final OutputStream out, final OutputStream err) {
this(null, out, err);
}
public PumpStreamHandler(final OutputStream outAndErr) {
this(outAndErr, outAndErr);
}
/**
* Set the input stream from which to read the standard output of the child.
*/
public void setChildOutputStream(final InputStream in) {
assert in != null;
createChildOutputPump(in, out);
}
/**
* Set the input stream from which to read the standard error of the child.
*/
public void setChildErrorStream(final InputStream in) {
assert in != null;
if (err != null) {
createChildErrorPump(in, err);
}
}
/**
* Set the output stream by means of which input can be sent to the child.
*/
public void setChildInputStream(final OutputStream out) {
assert out != null;
if (in != null) {
inputPump = createInputPump(in, out, true);
}
else {
try {
out.close();
} catch (IOException e) { }
}
}
/**
* Attach to a child streams from the given process.
*
* @param p The process to attach to.
*/
public void attach(final Process p) {
assert p != null;
setChildInputStream(p.getOutputStream());
setChildOutputStream(p.getInputStream());
setChildErrorStream(p.getErrorStream());
}
/**
* Start pumping the streams.
*/
public void start() {
if (outputPump != null) {
Thread thread = new Thread(outputPump);
thread.setDaemon(true);
thread.setName("Output pump for " + this.name);
thread.start();
}
if (errorPump != null) {
Thread thread = new Thread(errorPump);
thread.setDaemon(true);
thread.setName("Error pump for " + this.name);
thread.start();
}
if (inputPump != null) {
Thread thread = new Thread(inputPump);
thread.setDaemon(true);
thread.setName("Input pump for " + this.name);
thread.start();
}
}
/**
* Stop pumping the streams.
*/
public void stop() {
if (outputPump != null) {
try {
outputPump.stop();
outputPump.waitFor();
}
catch (InterruptedException e) {
// ignore
}
try {
outputPump.getIn().close();
} catch (IOException e) { }
}
if (errorPump != null) {
try {
errorPump.stop();
errorPump.waitFor();
}
catch (InterruptedException e) {
// ignore
}
try {
errorPump.getIn().close();
} catch (IOException e) { }
}
if (inputPump != null) {
inputPump.stop();
try {
inputPump.getOut().close();
} catch (IOException e) { }
}
try {
err.flush();
} catch (IOException e) { }
try {
out.flush();
} catch (IOException e) { }
}
/**
* Create the pump to handle child output.
*/
protected void createChildOutputPump(final InputStream in, final OutputStream out) {
assert in != null;
assert out != null;
outputPump = createPump(in, out);
}
/**
* Create the pump to handle error output.
*/
protected void createChildErrorPump(final InputStream in, final OutputStream out) {
assert in != null;
assert out != null;
errorPump = createPump(in, out);
}
/**
* Creates a stream pumper to copy the given input stream to the given output stream.
*/
protected StreamPumper createPump(final InputStream in, final OutputStream out) {
assert in != null;
assert out != null;
return createPump(in, out, false);
}
/**
* Creates a stream pumper to copy the given input stream to the
* given output stream.
*
* @param in The input stream to copy from.
* @param out The output stream to copy to.
* @param closeWhenExhausted If true close the inputstream.
* @return A thread object that does the pumping.
*/
protected StreamPumper createPump(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
assert in != null;
assert out != null;
StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
return pumper;
}
/**
* Creates a stream pumper to copy the given input stream to the
* given output stream. Used for standard input.
*/
protected StreamPumper createInputPump(final InputStream in, final OutputStream out, final boolean closeWhenExhausted) {
assert in != null;
assert out != null;
StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
pumper.setNonBlocking(true);
pumper.setAutoflush(true);
return pumper;
}
public StreamPumper getOutputPump() {
return this.outputPump;
}
public StreamPumper getErrorPump() {
return this.errorPump;
}
}