conor 2003/02/08 06:14:27
Modified: src/main/org/apache/tools/ant/taskdefs ExecTask.java
Java.java PumpStreamHandler.java
Added: src/main/org/apache/tools/ant/taskdefs Redirector.java
Log:
Refactor output handling from Exec into a new class Redirector and
use this in Java task to get access to features such as
separate error stream, redirected input, etc.
Revision Changes Path
1.49 +23 -146
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
Index: ExecTask.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -w -u -r1.48 -r1.49
--- ExecTask.java 7 Feb 2003 13:57:41 -0000 1.48
+++ ExecTask.java 8 Feb 2003 14:14:27 -0000 1.49
@@ -54,24 +54,14 @@
package org.apache.tools.ant.taskdefs;
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileInputStream;
import java.io.IOException;
-import java.io.StringReader;
-import java.io.OutputStream;
-import java.io.InputStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Environment;
-import org.apache.tools.ant.util.StringUtils;
import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.TeeOutputStream;
/**
* Executes a given command if the os platform is appropriate.
@@ -89,11 +79,6 @@
public class ExecTask extends Task {
private String os;
- private File out;
- private File error;
- private File input;
-
- private boolean logError = false;
private File dir;
protected boolean failOnError = false;
@@ -101,17 +86,13 @@
private Long timeout = null;
private Environment env = new Environment();
protected Commandline cmdl = new Commandline();
- private FileOutputStream fos = null;
- private ByteArrayOutputStream baos = null;
- private ByteArrayOutputStream errorBaos = null;
- private String outputprop;
- private String errorProperty;
private String resultProperty;
private boolean failIfExecFails = true;
- private boolean append = false;
private String executable;
private boolean resolveExecutable = false;
+ private Redirector redirector = new Redirector(this);
+
/**
* Controls whether the VM (1.3 and above) is used to execute the
* command
@@ -171,18 +152,22 @@
}
/**
- * Set the input to use for the task
+ * File the output of the process is redirected to. If error is not
+ * redirected, it too will appear in the output
*/
- public void setInput(File input) {
- this.input = input;
+ public void setOutput(File out) {
+ redirector.setOutput(out);
}
/**
- * File the output of the process is redirected to. If error is not
- * redirected, it too will appear in the output
+ * Set the input to use for the task
*/
- public void setOutput(File out) {
- this.out = out;
+ public void setInput(File input) {
+ redirector.setInput(input);
+ }
+
+ public void setInputString(String inputString) {
+ redirector.setInputString(inputString);
}
/**
@@ -191,7 +176,7 @@
* Ant log
*/
public void setLogError(boolean logError) {
- this.logError = logError;
+ redirector.setLogError(logError);
}
/**
@@ -200,15 +185,15 @@
* @since ant 1.6
*/
public void setError(File error) {
- this.error = error;
+ redirector.setError(error);
}
/**
* Property name whose value should be set to the output of
* the process.
*/
- public void setOutputproperty(String outputprop) {
- this.outputprop = outputprop;
+ public void setOutputproperty(String outputProp) {
+ redirector.setOutputProperty(outputProp);
}
/**
@@ -218,7 +203,7 @@
* @since ant 1.6
*/
public void setErrorProperty(String errorProperty) {
- this.errorProperty = errorProperty;
+ redirector.setErrorProperty(errorProperty);
}
/**
@@ -293,7 +278,7 @@
* @since 1.30, Ant 1.5
*/
public void setAppend(boolean append) {
- this.append = append;
+ redirector.setAppend(append);
}
@@ -410,22 +395,6 @@
return exe;
}
- private void setPropertyFromBAOS(ByteArrayOutputStream baos,
- String propertyName) throws IOException
{
-
- 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);
- }
- getProject().setNewProperty(propertyName, val.toString());
- }
-
/**
* A Utility method for this classes and subclasses to run an
* Execute instance (an external command).
@@ -447,12 +416,7 @@
log("Result: " + returnCode, Project.MSG_ERR);
}
}
- if (baos != null) {
- setPropertyFromBAOS(baos, outputprop);
- }
- if (errorBaos != null) {
- setPropertyFromBAOS(errorBaos, errorProperty);
- }
+ redirector.complete();
}
/**
@@ -483,86 +447,7 @@
* Create the StreamHandler to use with our Execute instance.
*/
protected ExecuteStreamHandler createHandler() throws BuildException {
- OutputStream outputStream = null;
- OutputStream errorStream = null;
- InputStream inputStream = null;
-
- if (out == null && outputprop == null) {
- outputStream = new LogOutputStream(this, Project.MSG_INFO);
- errorStream = new LogOutputStream(this, Project.MSG_WARN);
- } else {
- if (out != null) {
- try {
- outputStream
- = new FileOutputStream(out.getAbsolutePath(),
append);
- log("Output redirected to " + out, Project.MSG_VERBOSE);
- } catch (FileNotFoundException fne) {
- throw new BuildException("Cannot write to " + out, fne,
- getLocation());
- } catch (IOException ioe) {
- throw new BuildException("Cannot write to " + out, ioe,
- getLocation());
- }
- }
-
- if (outputprop != null) {
- baos = new ByteArrayOutputStream();
- log("Output redirected to property: " + outputprop,
- Project.MSG_VERBOSE);
- if (out == null) {
- outputStream = baos;
- } else {
- outputStream = new TeeOutputStream(outputStream, baos);
- }
- } else {
- baos = null;
- }
-
- errorStream = outputStream;
- }
-
- if (logError) {
- errorStream = new LogOutputStream(this, Project.MSG_WARN);
- }
-
- if (error != null) {
- try {
- errorStream
- = new FileOutputStream(error.getAbsolutePath(), append);
- log("Error redirected to " + error, Project.MSG_VERBOSE);
- } catch (FileNotFoundException fne) {
- throw new BuildException("Cannot write to " + error, fne,
- getLocation());
- } catch (IOException ioe) {
- throw new BuildException("Cannot write to " + error, ioe,
- getLocation());
- }
- }
-
- if (errorProperty != null) {
- errorBaos = new ByteArrayOutputStream();
- log("Error redirected to property: " + errorProperty,
- Project.MSG_VERBOSE);
- if (error == null) {
- errorStream = errorBaos;
- } else {
- errorStream = new TeeOutputStream(errorStream, errorBaos);
- }
- } else {
- errorBaos = null;
- }
-
- if (input != null) {
- try {
- inputStream = new FileInputStream(input);
- } catch (FileNotFoundException fne) {
- throw new BuildException("Cannot read from " + input, fne,
- getLocation());
- }
- }
-
- return new PumpStreamHandler(outputStream, errorStream, inputStream,
- true, true, true);
+ return redirector.createHandler();
}
/**
@@ -579,14 +464,6 @@
* Flush the output stream - if there is one.
*/
protected void logFlush() {
- try {
- if (fos != null) {
- fos.close();
- }
- if (baos != null) {
- baos.close();
- }
- } catch (IOException io) {}
}
}
1.53 +70 -54
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Java.java
Index: Java.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Java.java,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -w -u -r1.52 -r1.53
--- Java.java 31 Jan 2003 07:57:41 -0000 1.52
+++ Java.java 8 Feb 2003 14:14:27 -0000 1.53
@@ -55,9 +55,7 @@
package org.apache.tools.ant.taskdefs;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.PrintStream;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ExitException;
@@ -89,12 +87,10 @@
private boolean fork = false;
private boolean newEnvironment = false;
private File dir = null;
- private File out;
- private PrintStream outStream = null;
private boolean failOnError = false;
private boolean append = false;
private Long timeout = null;
-
+ private Redirector redirector = new Redirector(this);
/**
* Do the execution.
*/
@@ -302,7 +298,54 @@
* File the output of the process is redirected to.
*/
public void setOutput(File out) {
- this.out = out;
+ redirector.setOutput(out);
+ }
+
+ /**
+ * Set the input to use for the task
+ */
+ public void setInput(File input) {
+ redirector.setInput(input);
+ }
+
+ public void setInputString(String inputString) {
+ redirector.setInputString(inputString);
+ }
+
+ /**
+ * 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
+ */
+ public void setLogError(boolean logError) {
+ redirector.setLogError(logError);
+ }
+
+ /**
+ * File the error stream of the process is redirected to.
+ *
+ * @since ant 1.6
+ */
+ public void setError(File error) {
+ redirector.setError(error);
+ }
+
+ /**
+ * Property name whose value should be set to the output of
+ * the process.
+ */
+ public void setOutputproperty(String outputProp) {
+ redirector.setOutputProperty(outputProp);
+ }
+
+ /**
+ * Property name whose value should be set to the error of
+ * the process.
+ *
+ * @since ant 1.6
+ */
+ public void setErrorProperty(String errorProperty) {
+ redirector.setErrorProperty(errorProperty);
}
/**
@@ -366,8 +409,8 @@
* @since Ant 1.5
*/
protected void handleOutput(String line) {
- if (outStream != null) {
- outStream.println(line);
+ if (redirector.getOutputStream() != null) {
+ redirector.handleOutput(line);
} else {
super.handleOutput(line);
}
@@ -379,8 +422,8 @@
* @since Ant 1.5.2
*/
protected void handleFlush(String line) {
- if (outStream != null) {
- outStream.print(line);
+ if (redirector.getOutputStream() != null) {
+ redirector.handleFlush(line);
} else {
super.handleFlush(line);
}
@@ -392,8 +435,8 @@
* @since Ant 1.5
*/
protected void handleErrorOutput(String line) {
- if (outStream != null) {
- outStream.println(line);
+ if (redirector.getErrorStream() != null) {
+ redirector.handleErrorOutput(line);
} else {
super.handleErrorOutput(line);
}
@@ -405,8 +448,8 @@
* @since Ant 1.5.2
*/
protected void handleErrorFlush(String line) {
- if (outStream != null) {
- outStream.println(line);
+ if (redirector.getErrorStream() != null) {
+ redirector.handleErrorFlush(line);
} else {
super.handleErrorOutput(line);
}
@@ -417,28 +460,17 @@
* was a command line application.
*/
private void run(CommandlineJava command) throws BuildException {
+ try {
ExecuteJava exe = new ExecuteJava();
exe.setJavaCommand(command.getJavaCommand());
exe.setClasspath(command.getClasspath());
exe.setSystemProperties(command.getSystemProperties());
exe.setTimeout(timeout);
- if (out != null) {
- try {
- outStream =
- new PrintStream(new
FileOutputStream(out.getAbsolutePath(),
- append));
- exe.execute(getProject());
- System.out.flush();
- System.err.flush();
- } catch (IOException io) {
- throw new BuildException(io, getLocation());
- } finally {
- if (outStream != null) {
- outStream.close();
- }
- }
- } else {
+ redirector.createStreams();
exe.execute(getProject());
+ redirector.complete();
+ } catch (IOException e) {
+ throw new BuildException(e);
}
}
@@ -446,19 +478,9 @@
* Executes the given classname with the given arguments in a separate
VM.
*/
private int run(String[] command) throws BuildException {
- FileOutputStream fos = null;
- try {
- Execute exe = null;
- if (out == null) {
- exe = new Execute(new LogStreamHandler(this,
Project.MSG_INFO,
- Project.MSG_WARN),
- createWatchdog());
- } else {
- fos = new FileOutputStream(out.getAbsolutePath(), append);
- exe = new Execute(new PumpStreamHandler(fos),
- createWatchdog());
- }
+ Execute exe
+ = new Execute(redirector.createHandler(), createWatchdog());
exe.setAntRun(getProject());
if (dir == null) {
@@ -487,17 +509,11 @@
if (exe.killedProcess()) {
log("Timeout: killed the sub-process",
Project.MSG_WARN);
}
+ redirector.complete();
return rc;
} catch (IOException e) {
throw new BuildException(e, getLocation());
}
- } catch (IOException io) {
- throw new BuildException(io, getLocation());
- } finally {
- if (fos != null) {
- try {fos.close();} catch (IOException io) {}
- }
- }
}
/**
1.12 +2 -22
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
Index: PumpStreamHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -w -u -r1.11 -r1.12
--- PumpStreamHandler.java 7 Feb 2003 23:14:12 -0000 1.11
+++ PumpStreamHandler.java 8 Feb 2003 14:14:27 -0000 1.12
@@ -77,24 +77,15 @@
private OutputStream err;
private InputStream input;
- private boolean closeOutOnStop = false;
- private boolean closeErrOnStop = false;
- private boolean closeInputOnStop = false;
-
public PumpStreamHandler(OutputStream out, OutputStream err,
- InputStream input,
- boolean closeOutOnStop, boolean closeErrOnStop,
- boolean closeInputOnStop) {
+ InputStream input) {
this.out = out;
this.err = err;
this.input = input;
- this.closeOutOnStop = closeOutOnStop;
- this.closeErrOnStop = closeErrOnStop;
- this.closeInputOnStop = closeInputOnStop;
}
public PumpStreamHandler(OutputStream out, OutputStream err) {
- this(out, err, null, false, false, false);
+ this(out, err, null);
}
public PumpStreamHandler(OutputStream outAndErr) {
@@ -151,29 +142,18 @@
if (inputThread != null) {
try {
inputThread.join();
- if (closeInputOnStop) {
- input.close();
- }
} catch (InterruptedException e) {
// ignore
- } catch (IOException e) {
- // ignore
}
}
try {
err.flush();
- if (closeErrOnStop) {
- err.close();
- }
} catch (IOException e) {
// ignore
}
try {
out.flush();
- if (closeOutOnStop) {
- out.close();
- }
} catch (IOException e) {
// ignore
}
1.1
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Redirector.java
Index: Redirector.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.taskdefs;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.util.StringUtils;
import org.apache.tools.ant.util.TeeOutputStream;
/**
* The Redirector class manages the setup and connection of
* input and output redirection for an Ant task.
*
* @author Conor MacNeill
* @since Ant 1.6
*/
public class Redirector {
private File out;
private File error;
private File input;
private boolean logError = false;
private ByteArrayOutputStream baos = null;
private ByteArrayOutputStream errorBaos = null;
private String outputProperty;
private String errorProperty;
private String inputString;
private boolean append = false;
private Task managingTask;
private OutputStream outputStream = null;
private OutputStream errorStream = null;
private InputStream inputStream = null;
private PrintStream outPrintStream = null;
private PrintStream errorPrintStream = null;
public Redirector(Task managingTask) {
this.managingTask = managingTask;
}
/**
* Set the input to use for the task
*/
public void setInput(File input) {
this.input = input;
}
public void setInputString(String inputString) {
this.inputString = inputString;
}
/**
* File the output of the process is redirected to. If error is not
* redirected, it too will appear in the output
*/
public void setOutput(File out) {
this.out = out;
}
/**
* 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
*/
public void setLogError(boolean logError) {
this.logError = logError;
}
/**
* File the error stream of the process is redirected to.
*
*/
public void setError(File error) {
this.error = error;
}
/**
* Property name whose value should be set to the output of
* the process.
*/
public void setOutputProperty(String outputProperty) {
this.outputProperty = outputProperty;
}
/**
* Whether output should be appended to or overwrite an existing file.
* Defaults to false.
*
*/
public void setAppend(boolean append) {
this.append = append;
}
/**
* Property name whose value should be set to the error of
* the process.
*
*/
public void setErrorProperty(String errorProperty) {
this.errorProperty = errorProperty;
}
private void setPropertyFromBAOS(ByteArrayOutputStream baos,
String propertyName) throws IOException {
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());
}
public void createStreams() {
if (out == null && outputProperty == null) {
outputStream = new LogOutputStream(managingTask,
Project.MSG_INFO);
errorStream = new LogOutputStream(managingTask, Project.MSG_WARN);
} else {
if (out != null) {
try {
outputStream
= new FileOutputStream(out.getAbsolutePath(), append);
managingTask.log("Output redirected to " + out,
Project.MSG_VERBOSE);
} catch (FileNotFoundException fne) {
throw new BuildException("Cannot write to " + out, fne);
} catch (IOException ioe) {
throw new BuildException("Cannot write to " + out, ioe);
}
}
if (outputProperty != null) {
baos = new ByteArrayOutputStream();
managingTask.log("Output redirected to property: "
+ outputProperty, Project.MSG_VERBOSE);
if (out == null) {
outputStream = baos;
} else {
outputStream = new TeeOutputStream(outputStream, baos);
}
} else {
baos = null;
}
errorStream = outputStream;
}
if (logError) {
errorStream = new LogOutputStream(managingTask, Project.MSG_WARN);
}
if (error != null) {
try {
errorStream
= new FileOutputStream(error.getAbsolutePath(), append);
managingTask.log("Error redirected to " + error,
Project.MSG_VERBOSE);
} catch (FileNotFoundException fne) {
throw new BuildException("Cannot write to " + error, fne);
} catch (IOException ioe) {
throw new BuildException("Cannot write to " + error, ioe);
}
}
if (errorProperty != null) {
errorBaos = new ByteArrayOutputStream();
managingTask.log("Error redirected to property: " +
errorProperty,
Project.MSG_VERBOSE);
if (error == null) {
errorStream = errorBaos;
} else {
errorStream = new TeeOutputStream(errorStream, errorBaos);
}
} else {
errorBaos = null;
}
if (input != null && inputString != null) {
throw new BuildException("The \"input\" and \"inputstring\" "
+ "attributes cannot both be specified");
}
if (input != null) {
try {
inputStream = new FileInputStream(input);
} catch (FileNotFoundException fne) {
throw new BuildException("Cannot read from " + input, fne);
}
} else if (inputString != null) {
inputStream = new ByteArrayInputStream(inputString.getBytes());
}
}
/**
* Create the StreamHandler to use with our Execute instance.
*/
public ExecuteStreamHandler createHandler() throws BuildException {
createStreams();
return new PumpStreamHandler(outputStream, errorStream, inputStream);
}
/**
* Pass output sent to System.out to specified output file.
*
*/
protected void handleOutput(String line) {
if (outPrintStream == null) {
outPrintStream = new PrintStream(outputStream);
}
outPrintStream.println(line);
}
/**
* Pass output sent to System.out to specified output file.
*
*/
protected void handleFlush(String line) {
if (outPrintStream == null) {
outPrintStream = new PrintStream(outputStream);
}
outPrintStream.print(line);
}
/**
* Pass output sent to System.err to specified output file.
*
*/
protected void handleErrorOutput(String line) {
if (errorPrintStream == null) {
errorPrintStream = new PrintStream(errorStream);
}
errorPrintStream.println(line);
}
/**
* Pass output sent to System.err to specified output file.
*
*/
protected void handleErrorFlush(String line) {
if (errorPrintStream == null) {
errorPrintStream = new PrintStream(errorStream);
}
errorPrintStream.print(line);
}
public OutputStream getOutputStream() {
return outputStream;
}
public OutputStream getErrorStream() {
return errorStream;
}
public void complete() throws IOException {
System.out.flush();
System.err.flush();
if (inputStream != null) {
inputStream.close();
}
outputStream.close();
errorStream.close();
if (baos != null) {
setPropertyFromBAOS(baos, outputProperty);
}
if (errorBaos != null) {
setPropertyFromBAOS(errorBaos, errorProperty);
}
}
}