Fields Summary |
---|
private static final String | DEFAULT_ENCODING |
private File[] | inputThe file(s) from which standard input is being taken.
If > 1, files' content will be concatenated in the order received. |
private File[] | outThe file(s) receiving standard output. Will also receive standard error
unless standard error is redirected or logError is true. |
private File[] | errorThe file(s) to which standard error is being redirected |
private boolean | logErrorIndicates if standard error should be logged to Ant's log system
rather than the output. This has no effect if standard error is
redirected to a file or property. |
private PropertyOutputStream | baosBuffer used to capture output for storage into a property |
private PropertyOutputStream | errorBaosBuffer used to capture error output for storage into a property |
private String | outputPropertyThe name of the property into which output is to be stored |
private String | errorPropertyThe name of the property into which error output is to be stored |
private String | inputStringString from which input is taken |
private boolean | appendFlag which indicates if error and output files are to be appended. |
private boolean | alwaysLogFlag which indicates that output should be always sent to the log |
private boolean | createEmptyFilesFlag which indicates whether files should be created even when empty. |
private org.apache.tools.ant.ProjectComponent | managingTaskThe task for which this redirector is working |
private OutputStream | outputStreamThe stream for output data |
private OutputStream | errorStreamThe stream for error output |
private InputStream | inputStreamThe stream for input |
private PrintStream | outPrintStreamStream which is used for line oriented output |
private PrintStream | errorPrintStreamStream which is used for line oriented error output |
private Vector | outputFilterChainsThe output filter chains |
private Vector | errorFilterChainsThe error filter chains |
private Vector | inputFilterChainsThe input filter chains |
private String | outputEncodingThe output encoding |
private String | errorEncodingThe error encoding |
private String | inputEncodingThe input encoding |
private boolean | appendPropertiesWhether to complete properties settings |
private ThreadGroup | threadGroupThe thread group used for starting StreamPumper threads |
private boolean | logInputStringwhether to log the inputstring |
Methods Summary |
---|
public synchronized void | complete()Complete redirection.
This operation will close any streams and create any specified
property values.
System.out.flush();
System.err.flush();
if (inputStream != null) {
inputStream.close();
}
outputStream.flush();
outputStream.close();
errorStream.flush();
errorStream.close();
//wait for the StreamPumpers to finish
while (threadGroup.activeCount() > 0) {
try {
managingTask.log("waiting for " + threadGroup.activeCount()
+ " Threads:", Project.MSG_DEBUG);
Thread[] thread = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(thread);
for (int i = 0; i < thread.length && thread[i] != null; i++) {
try {
managingTask.log(thread[i].toString(), Project.MSG_DEBUG);
} catch (NullPointerException enPeaEx) {
// Ignore exception
}
}
wait(1000);
} catch (InterruptedException eyeEx) {
// Ignore exception
}
}
setProperties();
inputStream = null;
outputStream = null;
errorStream = null;
outPrintStream = null;
errorPrintStream = null;
|
public synchronized ExecuteStreamHandler | createHandler()Create the StreamHandler to use with our Execute instance.
createStreams();
return new PumpStreamHandler(outputStream, errorStream, inputStream);
|
public synchronized void | createStreams()Create the input, error and output streams based on the
configuration options.
if (out != null && out.length > 0) {
String logHead = new StringBuffer("Output ").append(
((append) ? "appended" : "redirected")).append(
" to ").toString();
outputStream = foldFiles(out, logHead, Project.MSG_VERBOSE);
}
if (outputProperty != null) {
if (baos == null) {
baos = new PropertyOutputStream(outputProperty);
managingTask.log("Output redirected to property: "
+ outputProperty, Project.MSG_VERBOSE);
}
//shield it from being closed by a filtering StreamPumper
OutputStream keepAliveOutput = new KeepAliveOutputStream(baos);
outputStream = (outputStream == null) ? keepAliveOutput
: new TeeOutputStream(outputStream, keepAliveOutput);
} else {
baos = null;
}
if (error != null && error.length > 0) {
String logHead = new StringBuffer("Error ").append(
((append) ? "appended" : "redirected")).append(
" to ").toString();
errorStream = foldFiles(error, logHead, Project.MSG_VERBOSE);
} else if (!(logError || outputStream == null)) {
long funnelTimeout = 0L;
OutputStreamFunneler funneler
= new OutputStreamFunneler(outputStream, funnelTimeout);
try {
outputStream = funneler.getFunnelInstance();
errorStream = funneler.getFunnelInstance();
} catch (IOException eyeOhEx) {
throw new BuildException(
"error splitting output/error streams", eyeOhEx);
}
}
if (errorProperty != null) {
if (errorBaos == null) {
errorBaos = new PropertyOutputStream(errorProperty);
managingTask.log("Error redirected to property: " + errorProperty,
Project.MSG_VERBOSE);
}
//shield it from being closed by a filtering StreamPumper
OutputStream keepAliveError = new KeepAliveOutputStream(errorBaos);
errorStream = (error == null || error.length == 0) ? keepAliveError
: new TeeOutputStream(errorStream, keepAliveError);
} else {
errorBaos = null;
}
if (alwaysLog || outputStream == null) {
OutputStream outputLog
= new LogOutputStream(managingTask, Project.MSG_INFO);
outputStream = (outputStream == null)
? outputLog : new TeeOutputStream(outputLog, outputStream);
}
if (alwaysLog || errorStream == null) {
OutputStream errorLog
= new LogOutputStream(managingTask, Project.MSG_WARN);
errorStream = (errorStream == null)
? errorLog : new TeeOutputStream(errorLog, errorStream);
}
if ((outputFilterChains != null && outputFilterChains.size() > 0)
|| !(outputEncoding.equalsIgnoreCase(inputEncoding))) {
try {
LeadPipeInputStream snk = new LeadPipeInputStream();
snk.setManagingComponent(managingTask);
InputStream outPumpIn = snk;
Reader reader = new InputStreamReader(outPumpIn, inputEncoding);
if (outputFilterChains != null && outputFilterChains.size() > 0) {
ChainReaderHelper helper = new ChainReaderHelper();
helper.setProject(managingTask.getProject());
helper.setPrimaryReader(reader);
helper.setFilterChains(outputFilterChains);
reader = helper.getAssembledReader();
}
outPumpIn = new ReaderInputStream(reader, outputEncoding);
Thread t = new Thread(threadGroup, new StreamPumper(
outPumpIn, outputStream, true), "output pumper");
t.setPriority(Thread.MAX_PRIORITY);
outputStream = new PipedOutputStream(snk);
t.start();
} catch (IOException eyeOhEx) {
throw new BuildException(
"error setting up output stream", eyeOhEx);
}
}
if ((errorFilterChains != null && errorFilterChains.size() > 0)
|| !(errorEncoding.equalsIgnoreCase(inputEncoding))) {
try {
LeadPipeInputStream snk = new LeadPipeInputStream();
snk.setManagingComponent(managingTask);
InputStream errPumpIn = snk;
Reader reader = new InputStreamReader(errPumpIn, inputEncoding);
if (errorFilterChains != null && errorFilterChains.size() > 0) {
ChainReaderHelper helper = new ChainReaderHelper();
helper.setProject(managingTask.getProject());
helper.setPrimaryReader(reader);
helper.setFilterChains(errorFilterChains);
reader = helper.getAssembledReader();
}
errPumpIn = new ReaderInputStream(reader, errorEncoding);
Thread t = new Thread(threadGroup, new StreamPumper(
errPumpIn, errorStream, true), "error pumper");
t.setPriority(Thread.MAX_PRIORITY);
errorStream = new PipedOutputStream(snk);
t.start();
} catch (IOException eyeOhEx) {
throw new BuildException(
"error setting up error stream", eyeOhEx);
}
}
// if input files are specified, inputString and inputStream are ignored;
// classes that work with redirector attributes can enforce
// whatever warnings are needed
if (input != null && input.length > 0) {
managingTask.log("Redirecting input from file"
+ ((input.length == 1) ? "" : "s"), Project.MSG_VERBOSE);
try {
inputStream = new ConcatFileInputStream(input);
} catch (IOException eyeOhEx) {
throw new BuildException(eyeOhEx);
}
((ConcatFileInputStream) inputStream).setManagingComponent(managingTask);
} else if (inputString != null) {
StringBuffer buf = new StringBuffer("Using input ");
if (logInputString) {
buf.append('"").append(inputString).append('"");
} else {
buf.append("string");
}
managingTask.log(buf.toString(), Project.MSG_VERBOSE);
inputStream = new ByteArrayInputStream(inputString.getBytes());
}
if (inputStream != null
&& inputFilterChains != null && inputFilterChains.size() > 0) {
ChainReaderHelper helper = new ChainReaderHelper();
helper.setProject(managingTask.getProject());
try {
helper.setPrimaryReader(
new InputStreamReader(inputStream, inputEncoding));
} catch (IOException eyeOhEx) {
throw new BuildException(
"error setting up input stream", eyeOhEx);
}
helper.setFilterChains(inputFilterChains);
inputStream = new ReaderInputStream(
helper.getAssembledReader(), inputEncoding);
}
|
private java.io.OutputStream | foldFiles(java.io.File[] file, java.lang.String logHead, int loglevel)
OutputStream result
= new LazyFileOutputStream(file[0], append, createEmptyFiles);
managingTask.log(logHead + file[0], loglevel);
char[] c = new char[logHead.length()];
Arrays.fill(c, ' ");
String indent = new String(c);
for (int i = 1; i < file.length; i++) {
outputStream = new TeeOutputStream(outputStream,
new LazyFileOutputStream(file[i], append, createEmptyFiles));
managingTask.log(indent + file[i], loglevel);
}
return result;
|
public synchronized java.io.OutputStream | getErrorStream()Get the error stream for the redirector
return errorStream;
|
public synchronized java.io.InputStream | getInputStream()Get the input stream for the redirector
return inputStream;
|
public synchronized java.io.OutputStream | getOutputStream()Get the output stream for the redirector
return outputStream;
|
protected synchronized void | handleErrorFlush(java.lang.String output)Handle a flush operation on the error stream
if (errorPrintStream == null) {
errorPrintStream = new PrintStream(errorStream);
}
errorPrintStream.print(output);
|
protected synchronized void | handleErrorOutput(java.lang.String output)Process error output
if (errorPrintStream == null) {
errorPrintStream = new PrintStream(errorStream);
}
errorPrintStream.print(output);
|
protected synchronized void | handleFlush(java.lang.String output)Process data due to a flush operation.
if (outPrintStream == null) {
outPrintStream = new PrintStream(outputStream);
}
outPrintStream.print(output);
outPrintStream.flush();
|
protected synchronized int | handleInput(byte[] buffer, int offset, int length)Handle an input request
if (inputStream == null) {
return managingTask.getProject().defaultInput(buffer, offset,
length);
} else {
return inputStream.read(buffer, offset, length);
}
|
protected synchronized void | handleOutput(java.lang.String output)Pass output sent to System.out to specified output.
if (outPrintStream == null) {
outPrintStream = new PrintStream(outputStream);
}
outPrintStream.print(output);
|
public synchronized void | setAlwaysLog(boolean alwaysLog)If true, (error and non-error) output will be "teed", redirected
as specified while being sent to Ant's logging mechanism as if no
redirection had taken place. Defaults to false.
this.alwaysLog = alwaysLog;
|
public synchronized void | setAppend(boolean append)Whether output should be appended to or overwrite an existing file.
Defaults to false.
this.append = append;
|
public synchronized void | setAppendProperties(boolean appendProperties)This Redirector 's subordinate
PropertyOutputStream s will not set their respective
properties while (appendProperties && append) .
this.appendProperties = appendProperties;
|
public synchronized void | setCreateEmptyFiles(boolean createEmptyFiles)Whether output and error files should be created even when empty.
Defaults to true.
this.createEmptyFiles = createEmptyFiles;
|
public void | setError(java.io.File error)Set the file to which standard error is to be redirected.
setError((error == null) ? null : new File[] {error});
|
public synchronized void | setError(java.io.File[] error)Set the files to which standard error is to be redirected.
this.error = error;
|
public synchronized void | setErrorEncoding(java.lang.String errorEncoding)Set the error encoding.
if (errorEncoding == null) {
throw new IllegalArgumentException(
"errorEncoding must not be null");
} else {
this.errorEncoding = errorEncoding;
}
|
public synchronized void | setErrorFilterChains(java.util.Vector errorFilterChains)Set the error FilterChain s.
this.errorFilterChains = errorFilterChains;
|
public synchronized void | setErrorProperty(java.lang.String errorProperty)Property name whose value should be set to the error of
the process.
if (errorProperty == null
|| !(errorProperty.equals(this.errorProperty))) {
this.errorProperty = errorProperty;
errorBaos = null;
}
|
public void | setInput(java.io.File input)Set the input to use for the task
setInput((input == null) ? null : new File[] {input});
|
public synchronized void | setInput(java.io.File[] input)Set the input to use for the task
this.input = input;
|
public synchronized void | setInputEncoding(java.lang.String inputEncoding)Set the input encoding.
if (inputEncoding == null) {
throw new IllegalArgumentException(
"inputEncoding must not be null");
} else {
this.inputEncoding = inputEncoding;
}
|
public synchronized void | setInputFilterChains(java.util.Vector inputFilterChains)Set the input FilterChain s.
this.inputFilterChains = inputFilterChains;
|
void | setInputStream(java.io.InputStream inputStream)Set a stream to use as input.
this.inputStream = inputStream;
|
public synchronized void | setInputString(java.lang.String inputString)Set the string to use as input
this.inputString = inputString;
|
public synchronized void | setLogError(boolean logError)Controls whether error output of exec is logged. This is only useful
when output is being redirected and error output is desired in the
Ant log
this.logError = logError;
|
public void | setLogInputString(boolean logInputString)Set whether to include the value of the input string in log messages.
Defaults to true.
this.logInputString = logInputString;
|
public void | setOutput(java.io.File out)File the output of the process is redirected to. If error is not
redirected, it too will appear in the output
setOutput((out == null) ? null : new File[] {out});
|
public synchronized void | setOutput(java.io.File[] out)Files the output of the process is redirected to. If error is not
redirected, it too will appear in the output
this.out = out;
|
public synchronized void | setOutputEncoding(java.lang.String outputEncoding)Set the output encoding.
if (outputEncoding == null) {
throw new IllegalArgumentException(
"outputEncoding must not be null");
} else {
this.outputEncoding = outputEncoding;
}
|
public synchronized void | setOutputFilterChains(java.util.Vector outputFilterChains)Set the output FilterChain s.
this.outputFilterChains = outputFilterChains;
|
public synchronized void | setOutputProperty(java.lang.String outputProperty)Property name whose value should be set to the output of
the process.
if (outputProperty == null
|| !(outputProperty.equals(this.outputProperty))) {
this.outputProperty = outputProperty;
baos = null;
}
|
public synchronized void | setProperties()Notify the Redirector that it is now okay
to set any output and/or error properties.
if (baos != null) {
try {
baos.close();
} catch (IOException eyeOhEx) {
// Ignore exception
}
}
if (errorBaos != null) {
try {
errorBaos.close();
} catch (IOException eyeOhEx) {
// Ignore exception
}
}
|
private void | setPropertyFromBAOS(java.io.ByteArrayOutputStream baos, java.lang.String propertyName)Set a property from a ByteArrayOutputStream
BufferedReader in
= new BufferedReader(new StringReader(Execute.toString(baos)));
String line = null;
StringBuffer val = new StringBuffer();
while ((line = in.readLine()) != null) {
if (val.length() != 0) {
val.append(StringUtils.LINE_SEP);
}
val.append(line);
}
managingTask.getProject().setNewProperty(propertyName, val.toString());
|