You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bo...@locus.apache.org on 2000/07/19 15:00:56 UTC
cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant/types AllJUnitTests.java CommandlineJavaTest.java CommandlineTest.java
bodewig 00/07/19 06:00:55
Modified: . bootstrap.bat bootstrap.sh
src/main/org/apache/tools/ant IntrospectionHelper.java
Path.java
src/main/org/apache/tools/ant/taskdefs defaults.properties
src/testcases/org/apache/tools/ant AllJUnitTests.java
IntrospectionHelperTest.java
Added: src/main/org/apache/tools/ant/taskdefs ExecTask.java
Execute.java ExecuteJava.java
ExecuteStreamHandler.java ExecuteWatchdog.java
LogOutputStream.java LogStreamHandler.java
PumpStreamHandler.java StreamPumper.java
src/main/org/apache/tools/ant/types Commandline.java
CommandlineJava.java Environment.java
src/testcases/org/apache/tools/ant/types AllJUnitTests.java
CommandlineJavaTest.java CommandlineTest.java
Log:
New Execution Framework.
This new framework should ease development of tasks that need to
execute external processes.
<exec> now invokes ExecTask, a reimplementation of Exec that uses the
new framework but has some additional features.
Submitted by: Thomas Hass <th...@softwired-inc.com>
Revision Changes Path
1.16 +1 -1 jakarta-ant/bootstrap.bat
Index: bootstrap.bat
===================================================================
RCS file: /home/cvs/jakarta-ant/bootstrap.bat,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- bootstrap.bat 2000/07/13 15:23:41 1.15
+++ bootstrap.bat 2000/07/19 13:00:20 1.16
@@ -44,7 +44,7 @@
echo.
echo ... Compiling Ant Classes
-%JAVAC% -d %CLASSDIR% %TOOLS%\tar\*.java %TOOLS%\ant\*.java %TOOLS%\ant\taskdefs\*.java
+%JAVAC% -d %CLASSDIR% %TOOLS%\tar\*.java %TOOLS%\ant\*.java %TOOLS%\ant\types\*.java %TOOLS%\ant\taskdefs\*.java
echo.
echo ... Copying Required Files
1.19 +1 -0 jakarta-ant/bootstrap.sh
Index: bootstrap.sh
===================================================================
RCS file: /home/cvs/jakarta-ant/bootstrap.sh,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- bootstrap.sh 2000/07/17 10:12:00 1.18
+++ bootstrap.sh 2000/07/19 13:00:25 1.19
@@ -39,6 +39,7 @@
javac -d ${CLASSDIR} ${TOOLS}/tar/*.java
javac -d ${CLASSDIR} ${TOOLS}/ant/*.java
+javac -d ${CLASSDIR} ${TOOLS}/ant/types/*.java
javac -d ${CLASSDIR} ${TOOLS}/ant/taskdefs/*.java
echo ... Copying Required Files
1.6 +1 -0 jakarta-ant/src/main/org/apache/tools/ant/IntrospectionHelper.java
Index: IntrospectionHelper.java
===================================================================
RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- IntrospectionHelper.java 2000/07/13 16:35:04 1.5
+++ IntrospectionHelper.java 2000/07/19 13:00:29 1.6
@@ -171,6 +171,7 @@
} else if (name.startsWith("add")
&& java.lang.Void.TYPE.equals(returnType)
&& args.length == 1
+ && !java.lang.String.class.equals(args[0])
&& !args[0].isArray()
&& !args[0].isPrimitive()) {
1.4 +5 -0 jakarta-ant/src/main/org/apache/tools/ant/Path.java
Index: Path.java
===================================================================
RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Path.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Path.java 2000/07/14 08:25:52 1.3
+++ Path.java 2000/07/19 13:00:30 1.4
@@ -85,6 +85,7 @@
* to define a path from an environment variable.
*
* @author Thomas.Haas@softwired-inc.com
+ * @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
*/
public class Path {
@@ -220,5 +221,9 @@
return true;
}
return false;
+ }
+
+ public int size() {
+ return definition.size();
}
}
1.23 +2 -1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties
Index: defaults.properties
===================================================================
RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- defaults.properties 2000/07/14 13:50:26 1.22
+++ defaults.properties 2000/07/19 13:00:33 1.23
@@ -23,7 +23,7 @@
property=org.apache.tools.ant.taskdefs.Property
taskdef=org.apache.tools.ant.taskdefs.Taskdef
ant=org.apache.tools.ant.taskdefs.Ant
-exec=org.apache.tools.ant.taskdefs.Exec
+exec=org.apache.tools.ant.taskdefs.ExecTask
tar=org.apache.tools.ant.taskdefs.Tar
untar=org.apache.tools.ant.taskdefs.Untar
available=org.apache.tools.ant.taskdefs.Available
@@ -47,6 +47,7 @@
wlstop=org.apache.tools.ant.taskdefs.optional.ejb.WLStop
vssget=org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET
ejbjar=org.apache.tools.ant.taskdefs.optional.ejb.EjbJar
+javacc=org.apache.tools.ant.taskdefs.optional.javacc.JavaCC
# deprecated ant tasks (kept for back compatibility)
javadoc2=org.apache.tools.ant.taskdefs.Javadoc
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
Index: ExecTask.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 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", "Tomcat", 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 apache@apache.org.
*
* 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 org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import java.io.*;
/**
* Executes a given command if the os platform is appropriate.
*
* @author duncan@x180.com
* @author rubys@us.ibm.com
* @author thomas.haas@softwired-inc.com
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
*/
public class ExecTask extends Task {
private String os;
private File out;
private File dir;
private boolean failOnError = false;
private Integer timeout = null;
private Environment env = new Environment();
private Commandline cmdl = new Commandline();
private FileOutputStream fos = null;
public void setTimeout(Integer value) {
timeout = value;
}
public void setExecutable(String value) {
cmdl.setExecutable(value);
}
public void setDir(File d) {
this.dir = d;
}
public void setOs(String os) {
this.os = os;
}
public void setCommand(Commandline cmdl) {
this.cmdl = cmdl;
}
public void setOutput(File out) {
this.out = out;
}
public void setFailonerror(boolean fail) {
failOnError = fail;
}
public void addEnv(Environment.Variable var) {
env.addVariable(var);
}
public void execute() throws BuildException {
if (cmdl.getExecutable() == null) {
throw new BuildException("no executable specified", location);
}
String[] orig = cmdl.getCommandline();
int err = -1; // assume the worst
// test if os match
String myos = System.getProperty("os.name");
log("Myos = " + myos, Project.MSG_VERBOSE);
if ((os != null) && (os.indexOf(myos) < 0)){
// this command will be executed only on the specified OS
log("Not found in " + os, Project.MSG_VERBOSE);
return;
}
// default directory to the project's base directory
if (dir == null) dir = project.getBaseDir();
if (myos.toLowerCase().indexOf("windows") >= 0) {
if (!dir.equals(project.resolveFile("."))) {
if (myos.toLowerCase().indexOf("nt") >= 0) {
cmdl = new Commandline();
cmdl.setExecutable("cmd");
cmdl.addValue("/c");
cmdl.addValue("cd");
cmdl.addValue(dir.getAbsolutePath());
cmdl.addValue("&&");
cmdl.addLine(orig);
} else {
String ant = project.getProperty("ant.home");
if (ant == null) {
throw new BuildException("Property 'ant.home' not found", location);
}
String antRun = project.resolveFile(ant + "/bin/antRun.bat").toString();
cmdl = new Commandline();
cmdl.setExecutable(antRun);
cmdl.addValue(dir.getAbsolutePath());
cmdl.addLine(orig);
}
}
} else {
String ant = project.getProperty("ant.home");
if (ant == null) throw new BuildException("Property 'ant.home' not found", location);
String antRun = project.resolveFile(ant + "/bin/antRun").toString();
cmdl = new Commandline();
cmdl.setExecutable(antRun);
cmdl.addValue(dir.getAbsolutePath());
cmdl.addLine(orig);
}
try {
// show the command
log(cmdl.toString(), Project.MSG_VERBOSE);
final Execute exe = new Execute(createHandler(), createWatchdog());
exe.setCommandline(cmdl.getCommandline());
exe.setEnvironment(env.getVariables());
err = exe.execute();
if (err != 0) {
if (failOnError) {
throw new BuildException("Exec returned: "+err, location);
} else {
log("Result: " + err, Project.MSG_ERR);
}
}
} catch (IOException e) {
throw new BuildException("Execute failed: " + e, e, location);
} finally {
// close the output file if required
logFlush();
}
}
protected ExecuteStreamHandler createHandler() throws BuildException {
if(out!=null) {
try {
fos = new FileOutputStream(out);
log("Output redirected to " + out, Project.MSG_VERBOSE);
return new PumpStreamHandler(fos);
} catch (FileNotFoundException fne) {
throw new BuildException("Cannot write to "+out, fne, location);
}
} else {
return new LogStreamHandler(this,
Project.MSG_INFO, Project.MSG_WARN);
}
}
protected ExecuteWatchdog createWatchdog() throws BuildException {
if (timeout == null) return null;
return new ExecuteWatchdog(timeout.intValue());
}
protected void logFlush() {
try {
if (fos != null) fos.close();
} catch (IOException io) {}
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Execute.java
Index: Execute.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Runs an external program.
*
* @author thomas.haas@softwired-inc.com
*/
public class Execute {
/** Invalid exit code. **/
public final static int INVALID = Integer.MAX_VALUE;
private String[] cmdl = null;
private String[] env = null;
private int exitValue = INVALID;
private ExecuteStreamHandler streamHandler;
private ExecuteWatchdog watchdog;
/**
* Creates a new execute object using <code>PumpStreamHandler</code> for
* stream handling.
*/
public Execute() {
this(new PumpStreamHandler(), null);
}
/**
* Creates a new execute object.
*
* @param streamHandler the stream handler used to handle the input and
* output streams of the subprocess.
* @param watchdog a watchdog for the subprocess or <code>null</code> to
* to disable a timeout for the subprocess.
*/
public Execute(ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog) {
this.streamHandler = streamHandler;
this.watchdog = watchdog;
}
/**
* Returns the commandline used to create a subprocess.
*
* @return the commandline used to create a subprocess
*/
public String[] getCommandline() {
return cmdl;
}
/**
* Sets the commandline of the subprocess to launch.
*
* @param commandline the commandline of the subprocess to launch
*/
public void setCommandline(String[] commandline) {
cmdl = commandline;
}
/**
* Returns the commandline used to create a subprocess.
*
* @return the commandline used to create a subprocess
*/
public String[] getEnvironment() {
return env;
}
/**
* Sets the commandline of the subprocess to launch.
*
* @param commandline the commandline of the subprocess to launch
*/
public void setEnvironment(String[] env) {
this.env = env;
}
/**
* Runs a process defined by the command line and returns its exit status.
*
* @return the exit status of the subprocess or <code>INVALID</code>
* @exception java.io.IOExcpetion The exception is thrown, if launching
* of the subprocess failed
*/
public int execute() throws IOException {
final Process process = exec();
try {
streamHandler.setProcessInputStream(process.getOutputStream());
streamHandler.setProcessOutputStream(process.getInputStream());
streamHandler.setProcessErrorStream(process.getErrorStream());
} catch (IOException e) {
process.destroy();
throw e;
}
streamHandler.start();
if (watchdog != null) watchdog.start(process);
waitFor(process);
if (watchdog != null) watchdog.stop();
streamHandler.stop();
if (watchdog != null) watchdog.checkException();
return getExitValue();
}
protected Process exec() throws IOException {
return Runtime.getRuntime().exec(getCommandline(), getEnvironment());
}
protected void waitFor(Process process) {
try {
process.waitFor();
setExitValue(process.exitValue());
} catch (InterruptedException e) {}
}
protected void setExitValue(int value) {
exitValue = value;
}
protected int getExitValue() {
return exitValue;
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
Index: ExecuteJava.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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 org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Path;
import org.apache.tools.ant.types.Commandline;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
*
* @author thomas.haas@softwired-inc.com
*/
public class ExecuteJava {
private Commandline javaCommand = null;
public void setJavaCommand(Commandline javaCommand) {
this.javaCommand = javaCommand;
}
public void execute() throws BuildException{
final String classname = javaCommand.getExecutable();
final Object[] argument = { javaCommand.getArguments() };
final Class[] param = { argument[0].getClass() };
try {
final Class target = Class.forName(classname);
final Method main = target.getMethod("main", param);
main.invoke(null, argument);
} catch (NullPointerException e) {
throw new BuildException("Could not find main() method in " + classname);
} catch (ClassNotFoundException e) {
throw new BuildException("Could not find " + classname + ". Make sure you have it in your classpath");
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (!(t instanceof SecurityException)) {
throw new BuildException(t.toString());
}
// else ignore because the security exception is thrown
// if the invoked application tried to call System.exit()
} catch (Exception e) {
throw new BuildException(e);
}
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteStreamHandler.java
Index: ExecuteStreamHandler.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.InputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Used by <code>Execute</code> to handle input and output stream of
* subprocesses.
*
* @author thomas.haas@softwired-inc.com
*/
public interface ExecuteStreamHandler {
/**
* Install a handler for the input stream of the subprocess.
*
* @param os output stream to write to the standard input stream of the
* subprocess
*/
public void setProcessInputStream(OutputStream os) throws IOException;
/**
* Install a handler for the error stream of the subprocess.
*
* @param is input stream to read from the error stream from the subprocess
*/
public void setProcessErrorStream(InputStream is) throws IOException;
/**
* Install a handler for the output stream of the subprocess.
*
* @param is input stream to read from the error stream from the subprocess
*/
public void setProcessOutputStream(InputStream is) throws IOException;
/**
* Start handling of the streams.
*/
public void start() throws IOException;
/**
* Stop handling of the streams - will not be restarted.
*/
public void stop();
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java
Index: ExecuteWatchdog.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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 org.apache.tools.ant.BuildException;
/**
* Destroys a process running for too long.
*
* @author thomas.haas@softwired-inc.com
*/
public class ExecuteWatchdog implements Runnable {
private Process process;
private int timeout;
private boolean watch = true;
private Exception caught = null;
/**
* Creates a new watchdog.
*
* @param timeout the timeout for the process.
*/
public ExecuteWatchdog(int timeout) {
if (timeout < 1) {
throw new IllegalArgumentException("timeout lesser than 1.");
}
this.timeout = timeout;
}
/**
* Watches the given process and terminates it, if it runs for to long.
*
* @param process the process to watch.
*/
public synchronized void start(Process process) {
if (process == null) {
throw new NullPointerException("process is null.");
}
if (this.process != null) {
throw new IllegalStateException("Already running.");
}
watch = true;
this.process = process;
final Thread thread = new Thread(this, "WATCHDOG");
thread.setDaemon(true);
thread.start();
}
/**
* Stops the watcher.
*/
public synchronized void stop() {
watch = false;
notifyAll();
process = null;
}
/**
* Watches the process and terminates it, if it runs for to long.
*/
public synchronized void run() {
try {
// This isn't a Task, don't have a Project object to log.
// project.log("ExecuteWatchdog: timeout = "+timeout+" msec", Project.MSG_VERBOSE);
final long until = System.currentTimeMillis() + timeout;
long now;
while (watch && until > (now = System.currentTimeMillis())) {
try {
wait(until - now);
} catch (InterruptedException e) {}
}
if (watch) {
process.destroy();
}
stop();
} catch(Exception e) {
caught = e;
}
}
public void checkException() throws BuildException {
if (caught != null) {
throw new BuildException("Exception in ExecuteWatchdog.run: "
+ caught.getMessage(), caught);
}
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java
Index: LogOutputStream.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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 org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import java.io.IOException;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
/**
* Logs each line written to this stream to the log system of ant.
*
* Tries to be smart about line separators.<br>
* TODO: This class can be split to implement other line based processing
* of data written to the stream.
*
* @author thomas.haas@softwired-inc.com
*/
public class LogOutputStream extends OutputStream {
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
private boolean skip = false;
private Task task;
private int level = Project.MSG_INFO;
/**
* Creates a new instance of this class.
*
* @param task the task for whom to log
* @param level loglevel used to log data written to this stream.
*/
public LogOutputStream(Task task, int level) {
this.task = task;
this.level = level;
}
/**
* Write the data to the buffer and flush the buffer, if a line
* separator is detected.
*
* @param cc data to log (byte).
*/
public void write(int cc) throws IOException {
final byte c = (byte)cc;
if ((c == '\n') || (c == '\r')) {
if (!skip) processBuffer();
} else buffer.write(cc);
skip = (c == '\r');
}
/**
* Converts the buffer to a string and sends it to <code>processLine</code>
*/
protected void processBuffer() {
processLine(buffer.toString());
buffer.reset();
}
/**
* Logs a line to the log system of ant.
*
* @param line the line to log.
*/
protected void processLine(String line) {
task.log(line, level);
}
/**
* Writes all remaining
*/
public void close() throws IOException {
if (buffer.size() > 0) processBuffer();
super.close();
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
Index: LogStreamHandler.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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 org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import java.io.OutputStream;
import java.io.InputStream;
/**
* Logs standard output and error of a subprocess to the log system of ant.
*
* @author thomas.haas@softwired-inc.com
*/
public class LogStreamHandler extends PumpStreamHandler {
/**
* Creates a new instance of this class.
*
* @param task the task for whom to log
* @param outlevel the loglevel used to log standard output
* @param errlevel the loglevel used to log standard error
*/
public LogStreamHandler(Task task, int outlevel, int errlevel) {
super(new LogOutputStream(task, outlevel),
new LogOutputStream(task, errlevel));
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
Index: PumpStreamHandler.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.InputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Copies standard output and error of subprocesses to standard output and
* error of the parent process.
*
* TODO: standard input of the subprocess is not implemented.
*
* @author thomas.haas@softwired-inc.com
*/
public class PumpStreamHandler implements ExecuteStreamHandler {
private Thread inputThread;
private Thread errorThread;
private OutputStream out, err;
public PumpStreamHandler(OutputStream out, OutputStream err) {
this.out = out;
this.err = err;
}
public PumpStreamHandler(OutputStream outAndErr) {
this(outAndErr, outAndErr);
}
public PumpStreamHandler() {
this(System.out, System.err);
}
public void setProcessOutputStream(InputStream is) {
createProcessOutputPump(is, out);
}
public void setProcessErrorStream(InputStream is) {
createProcessErrorPump(is, err);
}
public void setProcessInputStream(OutputStream os) {
}
public void start() {
inputThread.start();
errorThread.start();
}
public void stop() {
try {
inputThread.join();
} catch(InterruptedException e) {}
try {
errorThread.join();
} catch(InterruptedException e) {}
}
protected void createProcessOutputPump(InputStream is, OutputStream os) {
inputThread = createPump(is, os);
}
protected void createProcessErrorPump(InputStream is, OutputStream os) {
errorThread = createPump(is, os);
}
/**
* Creates a stream pumper to copy the given input stream to the given output stream.
*/
protected Thread createPump(InputStream is, OutputStream os) {
final Thread result = new Thread(new StreamPumper(is, os));
result.setDaemon(true);
return result;
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
Index: StreamPumper.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Copies all data from an input stream to an output stream.
*
* @author thomas.haas@softwired-inc.com
*/
public class StreamPumper implements Runnable {
// TODO: make SIZE and SLEEP instance variables.
// TODO: add a status flag to note if an error occured in run.
private final static int SLEEP = 5;
private final static int SIZE = 128;
private InputStream is;
private OutputStream os;
/**
* Create a new stream pumper.
*
* @param is input stream to read data from
* @param os output stream to write data to.
*/
public StreamPumper(InputStream is, OutputStream os) {
this.is = is;
this.os = os;
}
/**
* Copies data from the input stream to the output stream.
*
* Terminates as soon as the input stream is closed or an error occurs.
*/
public void run() {
final byte[] buf = new byte[SIZE];
int length;
try {
while ((length = is.read(buf)) > 0) {
os.write(buf, 0, length);
try {
Thread.sleep(SLEEP);
} catch (InterruptedException e) {}
}
} catch(IOException e) {}
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/types/Commandline.java
Index: Commandline.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.types;
import org.apache.tools.ant.BuildException;
import java.util.Vector;
import java.util.StringTokenizer;
/**
* Commandline objects help handling command lines specifying processes to
* execute.
*
* The class can be used to define a command line as nested elements or as a
* helper to define a command line by an application.
* <p>
* <code>
* <someelement><br>
* <acommandline executable="/executable/to/run"><br>
* <argument value="argument 1" /><br>
* <argument line="argument_1 argument_2 argument_3" /><br>
* <argument value="argument 4" /><br>
* </acommandline><br>
* </someelement><br>
* </code>
* The element <code>someelement</code> must provide a method
* <code>createAcommandline</code> which returns an instance of this class.
*
* @author thomas.haas@softwired-inc.com
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
*/
public class Commandline {
private Vector definition = new Vector();
private String executable = null;
private Argument argument = null;
public Commandline(String to_process) {
super();
String[] tmp = translateCommandline(to_process);
if (tmp != null && tmp.length > 0) {
setExecutable(tmp[0]);
for (int i=1; i<tmp.length; i++) {
addValue(tmp[i]);
}
}
}
public Commandline() {
super();
}
/**
* Used for nested xml command line definitions.
*/
public class Argument {
/**
* Sets a single commandline argument.
*
* @param value a single commandline argument.
*/
public void setValue(String value) {
Commandline.this.addValue(value);
}
/**
* Line to split into several commandline arguments.
*
* @param line line to split into several commandline arguments
*/
public void setLine(String line) {
Commandline.this.addLine(translateCommandline(line));
}
}
/**
* Creates an argument object.
* Each commandline object has at most one instance of the argument class.
* @return the argument object.
*/
public Argument createArgument() {
if (argument == null) {
argument = new Argument();
}
return argument;
}
/**
* Sets the executable to run.
*/
public void setExecutable(String executable) {
if (executable == null || executable.length() == 0) return;
this.executable = executable;
}
public String getExecutable() {
return executable;
}
public void addValue(String value) {
if (value == null || value.length() == 0) return;
definition.addElement(value);
}
public void addLine(String[] line) {
for (int i=0; i < line.length; i++) {
createArgument().setValue(line[i]);
}
}
/**
* Returns the executable and all defined arguments.
*/
public String[] getCommandline() {
if (executable == null) return getArguments();
final String[] args = getArguments();
final String[] result = new String[args.length+1];
result[0] = executable;
System.arraycopy(args, 0, result, 1, args.length);
return result;
}
/**
* Returns all arguments defined by <code>addLine</code>,
* <code>addValue</code> or the argument object.
*/
public String[] getArguments() {
final String [] result;
result = new String[definition.size()];
definition.copyInto(result);
return result;
}
public String toString() {
return toString(getCommandline());
}
public static String toString(String [] line) {
// empty path return empty string
if (line == null || line.length == 0) return "";
// path containing one or more elements
final StringBuffer result = new StringBuffer();
for (int i=0; i < line.length; i++) {
if (i > 0) {
result.append(' ');
}
// try to place quotes around arguments that need them
if (line[i].indexOf("\"") > -1) {
if (line[i].indexOf("\'") > -1) {
throw new BuildException("Can\'t handle single and double quotes in same argument");
} else {
result.append('\'').append(line[i]).append('\'');
}
} else if (line[i].indexOf("\'") > -1
|| line[i].indexOf(" ") > -1) {
result.append('\"').append(line[i]).append('\"');
} else {
result.append(line[i]);
}
}
return result.toString();
}
public static String[] translateCommandline(String to_process) {
if (to_process == null || to_process.length() == 0) {
return new String[0];
}
// parse with a simple finite state machine
final int normal = 0;
final int inQuote = 1;
final int inDoubleQuote = 2;
int state = normal;
StringTokenizer tok = new StringTokenizer(to_process, "\\\"\' ", true);
Vector v = new Vector();
StringBuffer current = new StringBuffer();
while (tok.hasMoreTokens()) {
String nextTok = tok.nextToken();
switch (state) {
case inQuote:
if ("\'".equals(nextTok)) {
state = normal;
} else {
current.append(nextTok);
}
break;
case inDoubleQuote:
if ("\"".equals(nextTok)) {
state = normal;
} else {
current.append(nextTok);
}
break;
default:
if ("\'".equals(nextTok)) {
state = inQuote;
} else if ("\"".equals(nextTok)) {
state = inDoubleQuote;
} else if (" ".equals(nextTok)) {
if (current.length() != 0) {
v.addElement(current.toString());
current.setLength(0);
}
} else if ("\\".equals(nextTok)) {
if (tok.hasMoreTokens()) {
current.append(tok.nextToken());
} else {
throw new BuildException("stray backslash in "
+ to_process);
}
} else {
current.append(nextTok);
}
break;
}
}
if (current.length() != 0) {
v.addElement(current.toString());
}
if (state == inQuote || state == inDoubleQuote) {
throw new BuildException("unbalanced quotes in " + to_process);
}
String[] args = new String[v.size()];
v.copyInto(args);
return args;
}
public int size() {
return definition.size() + (executable == null ? 0 : 1);
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/types/CommandlineJava.java
Index: CommandlineJava.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.types;
import org.apache.tools.ant.Path;
/*
*
* @author thomas.haas@softwired-inc.com
*/
public class CommandlineJava {
private Commandline vmCommand = new Commandline();
private Commandline javaCommand = new Commandline();
private Path classpath = new Path();
private String vmVersion;
public CommandlineJava() {
setVm("java");
setVmversion(org.apache.tools.ant.Project.getJavaVersion());
}
public Commandline.Argument createArgument() {
return javaCommand.createArgument();
}
public Commandline.Argument createVmArgument() {
return vmCommand.createArgument();
}
public void setVm(String vm) {
vmCommand.setExecutable(vm);
}
public void setVmversion(String value) {
vmVersion = value;
}
public void setClassname(String classname) {
javaCommand.setExecutable(classname);
}
public Path createClasspath() {
return classpath;
}
public String getVmversion() {
return vmVersion;
}
public String[] getCommandline() {
int size = vmCommand.size() + javaCommand.size();
if (classpath.size() > 0) {
size += 2;
}
String[] result = new String[size];
System.arraycopy(vmCommand.getCommandline(), 0,
result, 0, vmCommand.size());
if (classpath.size() > 0) {
result[vmCommand.size()] = "-classpath";
result[vmCommand.size()+1] = classpath.toString();
}
System.arraycopy(javaCommand.getCommandline(), 0,
result, result.length-javaCommand.size(),
javaCommand.size());
return result;
}
public String toString() {
return Commandline.toString(getCommandline());
}
public int size() {
int size = vmCommand.size() + javaCommand.size();
if (classpath.size() > 0) {
size += 2;
}
return size;
}
}
1.1 jakarta-ant/src/main/org/apache/tools/ant/types/Environment.java
Index: Environment.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.types;
import org.apache.tools.ant.BuildException;
import java.util.Vector;
/**
* Wrapper for environment variables.
*
* @author <a href="mailto:stefan.bodewig@megabit.net">Stefan Bodewig</a>
*/
public class Environment {
private Vector variables;
public static class Variable {
private String key, value;
public Variable() {
super();
}
public void setKey(String key) {
this.key = key;
}
public void setValue(String value) {
this.value = value;
}
public String getContent() throws BuildException {
if (key == null || value == null) {
throw new BuildException("key and value must be specified for environment variables.");
}
StringBuffer sb = new StringBuffer(key.trim());
sb.append("=").append(value.trim());
return sb.toString();
}
}
public Environment() {
variables = new Vector();
}
public void addVariable(Variable var) {
variables.addElement(var);
}
public String[] getVariables() throws BuildException {
if (variables.size() == 0) {
return null;
}
String[] result = new String[variables.size()];
for (int i=0; i<result.length; i++) {
result[i] = ((Variable) variables.elementAt(i)).getContent();
}
return result;
}
}
1.3 +1 -0 jakarta-ant/src/testcases/org/apache/tools/ant/AllJUnitTests.java
Index: AllJUnitTests.java
===================================================================
RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/AllJUnitTests.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AllJUnitTests.java 2000/07/13 16:35:07 1.2
+++ AllJUnitTests.java 2000/07/19 13:00:44 1.3
@@ -73,6 +73,7 @@
TestSuite suite = new TestSuite(IntrospectionHelperTest.class);
suite.addTest(new TestSuite(EnumeratedAttributeTest.class));
suite.addTest(new TestSuite(PathTest.class));
+ suite.addTest(org.apache.tools.ant.types.AllJUnitTests.suite());
return suite;
}
}
1.2 +4 -4 jakarta-ant/src/testcases/org/apache/tools/ant/IntrospectionHelperTest.java
Index: IntrospectionHelperTest.java
===================================================================
RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/IntrospectionHelperTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- IntrospectionHelperTest.java 2000/07/11 14:15:28 1.1
+++ IntrospectionHelperTest.java 2000/07/19 13:00:44 1.2
@@ -183,8 +183,8 @@
Hashtable h = new Hashtable();
h.put("six", java.lang.String.class);
h.put("thirteen", java.lang.StringBuffer.class);
- h.put("fourteen", java.lang.String.class);
- h.put("fifteen", java.lang.String.class);
+ h.put("fourteen", java.lang.StringBuffer.class);
+ h.put("fifteen", java.lang.StringBuffer.class);
IntrospectionHelper ih = IntrospectionHelper.getHelper(getClass());
Enumeration enum = ih.getNestedElements();
while (enum.hasMoreElements()) {
@@ -216,7 +216,7 @@
return "test";
}
- public String createFifteen() {
+ public StringBuffer createFifteen() {
throw new NullPointerException();
}
@@ -238,7 +238,7 @@
sb.append("test");
}
- public void addFourteen(String s) {
+ public void addFourteen(StringBuffer s) {
throw new NullPointerException();
}
1.1 jakarta-ant/src/testcases/org/apache/tools/ant/types/AllJUnitTests.java
Index: AllJUnitTests.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.types;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Simple class to build a TestSuite out of the individual test classes.
*
* @author Stefan Bodewig <a href="mailto:stefan.bodewig@megabit.net">stefan.bodewig@megabit.net</a>
*/
public class AllJUnitTests extends TestCase {
public AllJUnitTests(String name) {
super(name);
}
public static Test suite() {
TestSuite suite = new TestSuite(CommandlineTest.class);
suite.addTest(new TestSuite(CommandlineJavaTest.class));
return suite;
}
}
1.1 jakarta-ant/src/testcases/org/apache/tools/ant/types/CommandlineJavaTest.java
Index: CommandlineJavaTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.types;
import junit.framework.TestCase;
import junit.framework.AssertionFailedError;
import java.io.File;
/**
* JUnit 3 testcases for org.apache.tools.ant.CommandlineJava
*
* @author Stefan Bodewig <a href="mailto:stefan.bodewig@megabit.net">stefan.bodewig@megabit.net</a>
*/
public class CommandlineJavaTest extends TestCase {
public CommandlineJavaTest(String name) {
super(name);
}
public void testGetCommandline() {
CommandlineJava c = new CommandlineJava();
c.createArgument().setValue("org.apache.tools.ant.CommandlineJavaTest");
c.setClassname("junit.textui.TestRunner");
c.createVmArgument().setValue("-Djava.compiler=NONE");
String[] s = c.getCommandline();
assertEquals("no classpath", 4, s.length);
assertEquals("no classpath", "java", s[0]);
assertEquals("no classpath", "-Djava.compiler=NONE", s[1]);
assertEquals("no classpath", "junit.textui.TestRunner", s[2]);
assertEquals("no classpath",
"org.apache.tools.ant.CommandlineJavaTest", s[3]);
c.createClasspath().setLocation("junit.jar");
c.createClasspath().setLocation("ant.jar");
s = c.getCommandline();
assertEquals("with classpath", 6, s.length);
assertEquals("with classpath", "java", s[0]);
assertEquals("with classpath", "-Djava.compiler=NONE", s[1]);
assertEquals("with classpath", "-classpath", s[2]);
assertEquals("with classpath",
"junit.jar"+java.io.File.pathSeparator+"ant.jar", s[3]);
assertEquals("with classpath", "junit.textui.TestRunner", s[4]);
assertEquals("with classpath",
"org.apache.tools.ant.CommandlineJavaTest", s[5]);
}
}
1.1 jakarta-ant/src/testcases/org/apache/tools/ant/types/CommandlineTest.java
Index: CommandlineTest.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 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", "Tomcat", 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 apache@apache.org.
*
* 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.types;
import org.apache.tools.ant.BuildException;
import junit.framework.TestCase;
import junit.framework.AssertionFailedError;
import java.io.File;
/**
* JUnit 3 testcases for org.apache.tools.ant.CommandLine
*
* @author Stefan Bodewig <a href="mailto:stefan.bodewig@megabit.net">stefan.bodewig@megabit.net</a>
*/
public class CommandlineTest extends TestCase {
public CommandlineTest(String name) {
super(name);
}
public void testTokenizer() {
String[] s = Commandline.translateCommandline("1 2 3");
assertEquals("Simple case", 3, s.length);
for (int i=0; i<3; i++) {
assertEquals(""+(i+1), s[i]);
}
s = Commandline.translateCommandline("");
assertEquals("empty string", 0, s.length);
s = Commandline.translateCommandline(null);
assertEquals("null", 0, s.length);
s = Commandline.translateCommandline("1 \'2\' 3");
assertEquals("Simple case with single quotes", 3, s.length);
assertEquals("Single quotes have been stripped", "2", s[1]);
s = Commandline.translateCommandline("1 \"2\" 3");
assertEquals("Simple case with double quotes", 3, s.length);
assertEquals("Double quotes have been stripped", "2", s[1]);
s = Commandline.translateCommandline("1 \"2 3\" 4");
assertEquals("Case with double quotes and whitespace", 3, s.length);
assertEquals("Double quotes stripped, space included", "2 3", s[1]);
s = Commandline.translateCommandline("1 \"2\'3\" 4");
assertEquals("Case with double quotes around single quote", 3, s.length);
assertEquals("Double quotes stripped, single quote included", "2\'3",
s[1]);
s = Commandline.translateCommandline("1 \'2 3\' 4");
assertEquals("Case with single quotes and whitespace", 3, s.length);
assertEquals("Single quotes stripped, space included", "2 3", s[1]);
s = Commandline.translateCommandline("1 \'2\"3\' 4");
assertEquals("Case with single quotes around double quote", 3, s.length);
assertEquals("Single quotes stripped, double quote included", "2\"3",
s[1]);
s = Commandline.translateCommandline("1 2\\ 3 4");
assertEquals("Case with quoted whitespace", 3, s.length);
assertEquals("space included", "2 3", s[1]);
s = Commandline.translateCommandline("1 2\\\'3 4");
assertEquals("Case with quoted single quote", 3, s.length);
assertEquals("single quote included", "2\'3", s[1]);
s = Commandline.translateCommandline("1 2\\\"3 4");
assertEquals("Case with quoted double quote", 3, s.length);
assertEquals("double quote included", "2\"3", s[1]);
s = Commandline.translateCommandline("1 2\\\\3 4");
assertEquals("Case with quoted backslash", 3, s.length);
assertEquals("backslash included", "2\\3", s[1]);
// now to the expected failures
try {
s = Commandline.translateCommandline("a \\");
fail("stray \\ undetected");
} catch (BuildException be) {
assertEquals("stray backslash in a \\", be.getMessage());
}
try {
s = Commandline.translateCommandline("a \'b c");
fail("unbalanced single quotes undetected");
} catch (BuildException be) {
assertEquals("unbalanced quotes in a \'b c", be.getMessage());
}
try {
s = Commandline.translateCommandline("a \"b c");
fail("unbalanced double quotes undetected");
} catch (BuildException be) {
assertEquals("unbalanced quotes in a \"b c", be.getMessage());
}
}
public void testToString() {
assertEquals("", Commandline.toString(new String[0]));
assertEquals("", Commandline.toString(null));
assertEquals("1 2 3", Commandline.toString(new String[] {"1", "2", "3"}));
assertEquals("1 \"2 3\"", Commandline.toString(new String[] {"1", "2 3"}));
assertEquals("1 \"2\'3\"", Commandline.toString(new String[] {"1", "2\'3"}));
assertEquals("1 \'2\"3\'", Commandline.toString(new String[] {"1", "2\"3"}));
}
}