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>
   * &lt;someelement&gt;<br>
   * &nbsp;&nbsp;&lt;acommandline executable="/executable/to/run"&gt;<br>
   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 1" /&gt;<br>
   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument line="argument_1 argument_2 argument_3" /&gt;<br>
   * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 4" /&gt;<br>
   * &nbsp;&nbsp;&lt;/acommandline&gt;<br>
   * &lt;/someelement&gt;<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"}));
      }
  }