You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by br...@apache.org on 2005/08/05 14:22:17 UTC

svn commit: r230452 [1/3] - in /jakarta/commons/sandbox/exec/trunk: ./ src/ src/bin/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/commons/ src/main/java/org/apache/commons/exec/ src/main/java/org/apache...

Author: brett
Date: Fri Aug  5 05:21:46 2005
New Revision: 230452

URL: http://svn.apache.org/viewcvs?rev=230452&view=rev
Log:
Submitted by: Niklas Gustavsson
initial import of refactored code from the Ant Exec tasks.

Added:
    jakarta/commons/sandbox/exec/trunk/build.properties.sample
    jakarta/commons/sandbox/exec/trunk/build.xml   (with props)
    jakarta/commons/sandbox/exec/trunk/pom.xml   (with props)
    jakarta/commons/sandbox/exec/trunk/src/
    jakarta/commons/sandbox/exec/trunk/src/bin/
    jakarta/commons/sandbox/exec/trunk/src/bin/antRun
    jakarta/commons/sandbox/exec/trunk/src/bin/antRun.bat   (with props)
    jakarta/commons/sandbox/exec/trunk/src/bin/antRun.pl
    jakarta/commons/sandbox/exec/trunk/src/main/
    jakarta/commons/sandbox/exec/trunk/src/main/java/
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineArgument.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineImpl.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Exec.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Execute.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteException.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogOutputStream.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogStreamHandler.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/OS.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ProcessDestroyer.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/StreamPumper.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/TimeoutObserver.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Watchdog.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/Environment.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/EnvironmentVariable.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/environment/OpenVmsEnvironment.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/CommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/CommandLauncherFactory.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/CommandLauncherImpl.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/CommandLauncherProxy.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/Java11CommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/Java13CommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/MacCommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/OS2CommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/PerlScriptCommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/ScriptCommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/VmsCommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/launcher/WinNTCommandLauncher.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/site/
    jakarta/commons/sandbox/exec/trunk/src/site/apt/
    jakarta/commons/sandbox/exec/trunk/src/site/apt/index.apt
    jakarta/commons/sandbox/exec/trunk/src/site/site.xml   (with props)
    jakarta/commons/sandbox/exec/trunk/src/test/
    jakarta/commons/sandbox/exec/trunk/src/test/java/
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/CommandLineTest.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/ExecTest.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/TestUtil.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/environment/
    jakarta/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/environment/EnvironmentTest.java   (with props)
    jakarta/commons/sandbox/exec/trunk/src/test/scripts/
    jakarta/commons/sandbox/exec/trunk/src/test/scripts/test.bat   (with props)
    jakarta/commons/sandbox/exec/trunk/src/test/scripts/test.sh   (with props)
Modified:
    jakarta/commons/sandbox/exec/trunk/   (props changed)

Propchange: jakarta/commons/sandbox/exec/trunk/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Aug  5 05:21:46 2005
@@ -0,0 +1,2 @@
+target
+build.properties

Added: jakarta/commons/sandbox/exec/trunk/build.properties.sample
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/build.properties.sample?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/build.properties.sample (added)
+++ jakarta/commons/sandbox/exec/trunk/build.properties.sample Fri Aug  5 05:21:46 2005
@@ -0,0 +1 @@
+maven.repo.local=c:/home/brett/repository-m2

Added: jakarta/commons/sandbox/exec/trunk/build.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/build.xml?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/build.xml (added)
+++ jakarta/commons/sandbox/exec/trunk/build.xml Fri Aug  5 05:21:46 2005
@@ -0,0 +1,77 @@
+<project name="exec" default="jar" basedir=".">
+  <property file="build.properties" />
+  <property name="maven.build.output" value="target/classes"/>
+  <property name="maven.build.directory" value="target"/>
+  <property name="maven.build.final.name" value="exec-1.0-SNAPSHOT"/>
+  <property name="maven.test.reports" value="${maven.build.directory}/test-reports"/>
+  <property name="maven.test.output" value="target/test-classes"/>
+  <property name="maven.repo.local" value="${user.home}/.m2/repository"/>
+  <path id="build.classpath">
+    <fileset dir="${maven.repo.local}">
+      <include name="commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar"/>
+    </fileset>
+  </path>
+  <target name="clean" description="Clean the output directory">
+    <delete dir="${maven.build.directory}"/>
+  </target>
+  <target name="compile" depends="get-deps" description="Compile the code">
+    <mkdir dir="${maven.build.output}"/>
+    <javac destdir="${maven.build.output}" excludes="**/package.html" debug="true" deprecation="true" optimize="false">
+      <src>
+        <pathelement location="src/main/java"/>
+      </src>
+      <classpath refid="build.classpath"/>
+    </javac>
+  </target>
+  <target name="jar" depends="compile,test" description="Clean the JAR">
+    <jar jarfile="${maven.build.directory}/${maven.build.final.name}.jar" basedir="${maven.build.output}" excludes="**/package.html"/>
+  </target>
+  <target name="compile-tests" depends="junit-present, compile" description="Compile the test code" if="junit.present">
+    <mkdir dir="${maven.test.output}"/>
+    <javac destdir="${maven.test.output}" excludes="**/package.html" debug="true" deprecation="true" optimize="false">
+      <src>
+        <pathelement location="src/test/java"/>
+      </src>
+      <classpath>
+        <path refid="build.classpath"/>
+        <pathelement location="${maven.build.output}"/>
+      </classpath>
+    </javac>
+  </target>
+  <target name="test" depends="junit-present, compile-tests" if="junit.present" description="Run the test cases">
+    <mkdir dir="${maven.test.reports}"/>
+    <junit printSummary="yes" haltonerror="true" haltonfailure="true" fork="true" dir=".">
+      <sysproperty key="basedir" value="."/>
+      <formatter type="xml"/>
+      <formatter type="plain" usefile="false"/>
+      <classpath>
+        <path refid="build.classpath"/>
+        <pathelement location="${maven.build.output}"/>
+        <pathelement location="${maven.test.output}"/>
+      </classpath>
+      <batchtest>
+        <fileset dir="src/test/java">
+          <include name="**/*Test.java"/>
+          <exclude name="**/*Abstract*Test.java"/>
+        </fileset>
+      </batchtest>
+    </junit>
+  </target>
+  <target name="test-junit-present">
+    <available classname="junit.framework.Test" property="junit.present"/>
+  </target>
+  <target name="junit-present" depends="test-junit-present" unless="junit.present">
+    <echo>================================= WARNING ================================</echo>
+    <echo> Junit isn't present in your $ANT_HOME/lib directory. Tests not executed. </echo>
+    <echo>==========================================================================</echo>
+  </target>
+  <target name="test-offline">
+    <condition property="maven.mode.offline">
+      <equals arg1="${build.sysclasspath}" arg2="only"/>
+    </condition>
+  </target>
+  <target name="get-deps" depends="test-offline" description="Download all dependencies" unless="maven.mode.offline">
+    <mkdir dir="${maven.repo.local}"/>
+    <get src="http://repo1.maven.org/maven2/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar" dest="${maven.repo.local}/commons-logging/commons-logging-api/1.0.4/commons-logging-api-1.0.4.jar" usetimestamp="true" ignoreerrors="true"/>
+  </target>
+</project>

Propchange: jakarta/commons/sandbox/exec/trunk/build.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/build.xml
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/pom.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/pom.xml?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/pom.xml (added)
+++ jakarta/commons/sandbox/exec/trunk/pom.xml Fri Aug  5 05:21:46 2005
@@ -0,0 +1,45 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.commons</groupId>
+  <artifactId>exec</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <name>Commons Exec</name>
+  <url>http://jakarta.apache.org/commons/sandbox/exec/</url>
+  <dependencies>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging-api</artifactId>
+      <version>1.0.4</version>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>3.8.1</version>
+        <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <developers>
+    <developer>
+      <id>brett</id>
+      <name>Brett Porter</name>
+      <email>brett AT apache DOT org</email>
+      <organization>Apache</organization>
+      <timezone>+10</timezone>
+    </developer>
+  </developers>
+  <contributors>
+    <contributor>
+      <name>Niklas Gustavsson</name>
+      <email>niklas AT protocol7 DOT com</email>
+    </contributor>
+  </contributors>
+  <!-- TODO: these will be moved to a commons parent eventually -->
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>

Propchange: jakarta/commons/sandbox/exec/trunk/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/pom.xml
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/bin/antRun
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/bin/antRun?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/bin/antRun (added)
+++ jakarta/commons/sandbox/exec/trunk/src/bin/antRun Fri Aug  5 05:21:46 2005
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+#
+#  Copyright  2001-2002,2004 The Apache Software Foundation
+# 
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+# 
+#       http://www.apache.org/licenses/LICENSE-2.0
+# 
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+# 
+#
+
+# Args: DIR command
+cd "$1"
+CMD="$2"
+shift
+shift
+
+exec "$CMD" "$@"

Added: jakarta/commons/sandbox/exec/trunk/src/bin/antRun.bat
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/bin/antRun.bat?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/bin/antRun.bat (added)
+++ jakarta/commons/sandbox/exec/trunk/src/bin/antRun.bat Fri Aug  5 05:21:46 2005
@@ -0,0 +1,45 @@
+@echo off
+
+REM
+REM Copyright  2001-2002,2004 The Apache Software Foundation
+REM
+REM  Licensed under the Apache License, Version 2.0 (the "License");
+REM  you may not use this file except in compliance with the License.
+REM  You may obtain a copy of the License at
+REM
+REM      http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM  Unless required by applicable law or agreed to in writing, software
+REM  distributed under the License is distributed on an "AS IS" BASIS,
+REM  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM  See the License for the specific language governing permissions and
+REM  limitations under the License.
+REM
+REM
+
+if "%OS%"=="Windows_NT" @setlocal
+
+if ""%1""=="""" goto runCommand
+
+rem Change drive and directory to %1
+if "%OS%"=="Windows_NT" cd /d ""%1""
+if not "%OS%"=="Windows_NT" cd ""%1""
+shift
+
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of agruments (up to the command line limit, anyway).
+set ANT_RUN_CMD=%1
+if ""%1""=="""" goto runCommand
+shift
+:loop
+if ""%1""=="""" goto runCommand
+set ANT_RUN_CMD=%ANT_RUN_CMD% %1
+shift
+goto loop
+
+:runCommand
+rem echo %ANT_RUN_CMD%
+%ANT_RUN_CMD%
+
+if "%OS%"=="Windows_NT" @endlocal
+

Propchange: jakarta/commons/sandbox/exec/trunk/src/bin/antRun.bat
------------------------------------------------------------------------------
    svn:eol-style = CRLF

Propchange: jakarta/commons/sandbox/exec/trunk/src/bin/antRun.bat
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/bin/antRun.pl
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/bin/antRun.pl?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/bin/antRun.pl (added)
+++ jakarta/commons/sandbox/exec/trunk/src/bin/antRun.pl Fri Aug  5 05:21:46 2005
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+#
+# Copyright 2001,2003-2004 The Apache Software Foundation
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+#######################################################################
+#
+# antRun.pl
+#
+# wrapper script for invoking commands on a platform with Perl installed
+# this is akin to antRun.bat, and antRun the SH script 
+#
+# created:         2001-10-18
+# author:          Jeff Tulley jtulley@novell.com 
+#######################################################################
+#be fussy about variables
+use strict;
+
+#turn warnings on during dev; generates a few spurious uninitialised var access warnings
+#use warnings;
+
+#and set $debug to 1 to turn on trace info (currently unused)
+my $debug=1;
+
+#######################################################################
+# change drive and directory to "%1"
+my $ANT_RUN_CMD = @ARGV[0];
+
+# assign current run command to "%2"
+chdir (@ARGV[0]) || die "Can't cd to $ARGV[0]: $!\n";
+if ($^O eq "NetWare") {
+    # There is a bug in Perl 5 on NetWare, where chdir does not
+    # do anything.  On NetWare, the following path-prefixed form should 
+    # always work. (afaict)
+    $ANT_RUN_CMD .= "/".@ARGV[1];
+}
+else {
+    $ANT_RUN_CMD = @ARGV[1];
+}
+
+# dispose of the first two arguments, leaving only the command's args.
+shift;
+shift;
+
+# run the command
+my $returnValue = system $ANT_RUN_CMD, @ARGV;
+if ($returnValue eq 0) {
+    exit 0;
+}
+else {
+    # only 0 and 1 are widely recognized as exit values
+    # so change the exit value to 1
+    exit 1;
+}

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,72 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+/**
+ * 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.
+ */
+public interface CommandLine {
+
+    /**
+     * Sets the executable to run. All file separators in the string are
+     * converted to the platform specific value
+     */
+    void setExecutable(final String executable);
+
+    /**
+     * Get the executable.
+     * 
+     * @return the program to run -null if not yet set
+     */
+    String getExecutable();
+
+    /**
+     * Append the arguments to the existing command.
+     * 
+     * @param line
+     *            an array of arguments to append
+     */
+    void addArguments(final String[] line);
+
+    void addArgument(final String arg);
+
+    /**
+     * Returns the executable and all defined arguments.
+     */
+    String[] getCommandline();
+
+    /**
+     * Returns all arguments defined by <code>addLine</code>,
+     * <code>addValue</code> or the argument object.
+     */
+    String[] getArguments();
+
+    /**
+     * Clear out the whole command line.
+     */
+    void clear();
+
+    /**
+     * Clear out the arguments but leave the executable in place for another
+     * operation.
+     */
+    void clearArgs();
+
+}
\ No newline at end of file

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLine.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineArgument.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineArgument.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineArgument.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineArgument.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,59 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.File;
+
+/**
+ * Used for nested xml command line definitions.
+ */
+public class CommandLineArgument {
+
+    private String[] parts;
+
+    public CommandLineArgument(final String value) {
+        if (value == null) {
+            throw new IllegalArgumentException("value can not be null");
+        }
+
+        parts = new String[] {value};
+    }
+
+    public CommandLineArgument(final String[] values) {
+        if (values == null) {
+            throw new IllegalArgumentException("values can not be null");
+        }
+
+        parts = values;
+    }
+
+    public CommandLineArgument(final File file) {
+        if (file == null) {
+            throw new IllegalArgumentException("file can not be null");
+        }
+
+        parts = new String[] {file.getAbsolutePath()};
+    }
+
+    /**
+     * Returns the parts this CommandLineArgument consists of.
+     */
+    public String[] getParts() {
+        return parts;
+    }
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineArgument.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineArgument.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineImpl.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineImpl.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineImpl.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,341 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * 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.
+ */
+public class CommandLineImpl implements Cloneable, CommandLine {
+
+    /**
+     * The arguments of the command.
+     */
+    private Vector arguments = new Vector();
+
+    /**
+     * The program to execute.
+     */
+    private String executable = null;
+
+    /**
+     * Create a command line from a string.
+     * 
+     * @param toProcess
+     *            the line: the first element becomes the executable, the rest
+     *            the arguments
+     */
+    public CommandLineImpl(final String toProcess) {
+        super();
+        String[] tmp = translateCommandline(toProcess);
+        if (tmp != null && tmp.length > 0) {
+            setExecutable(tmp[0]);
+            for (int i = 1; i < tmp.length; i++) {
+                createArgument(tmp[i]);
+            }
+        }
+    }
+
+    /**
+     * Create an empty command line.
+     */
+    public CommandLineImpl() {
+        super();
+    }
+
+    /**
+     * Creates an argument object.
+     * <p>
+     * Each commandline object has at most one instance of the argument class.
+     * This method calls <code>this.createArgument(false)</code>.
+     * </p>
+     * 
+     * @see #createArgument(boolean)
+     * @return the argument object.
+     */
+    private CommandLineArgument createArgument(final String value) {
+        CommandLineArgument argument = new CommandLineArgument(value);
+        arguments.addElement(argument);
+        return argument;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#setExecutable(java.lang.String)
+     */
+    public void setExecutable(final String executable) {
+        if (executable == null || executable.length() == 0) {
+            return;
+        }
+        this.executable = executable.replace('/', File.separatorChar).replace(
+                '\\', File.separatorChar);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#getExecutable()
+     */
+    public String getExecutable() {
+        return executable;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#addArguments(java.lang.String[])
+     */
+    public void addArguments(final String[] line) {
+        for (int i = 0; i < line.length; i++) {
+            createArgument(line[i]);
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#addArgument(java.lang.String)
+     */
+    public void addArgument(final String arg) {
+        createArgument(arg);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#getCommandline()
+     */
+    public String[] getCommandline() {
+        List commands = new LinkedList();
+        ListIterator list = commands.listIterator();
+        addCommandToList(list);
+        final String[] result = new String[commands.size()];
+        return (String[]) commands.toArray(result);
+    }
+
+    /**
+     * Add the entire command, including (optional) executable to a list.
+     * 
+     * @param list
+     */
+    private void addCommandToList(final ListIterator list) {
+        if (executable != null) {
+            list.add(executable);
+        }
+        addArgumentsToList(list);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#getArguments()
+     */
+    public String[] getArguments() {
+        List result = new ArrayList(arguments.size() * 2);
+        addArgumentsToList(result.listIterator());
+        String[] res = new String[result.size()];
+        return (String[]) result.toArray(res);
+    }
+
+    /**
+     * append all the arguments to the tail of a supplied list
+     * 
+     * @param list
+     */
+    private void addArgumentsToList(final ListIterator list) {
+        for (int i = 0; i < arguments.size(); i++) {
+            CommandLineArgument arg = (CommandLineArgument) arguments
+                    .elementAt(i);
+            String[] s = arg.getParts();
+            if (s != null) {
+                for (int j = 0; j < s.length; j++) {
+                    list.add(s[j]);
+                }
+            }
+        }
+    }
+
+    /**
+     * Stringify operator returns the command line as a string.
+     * 
+     * @return the command line
+     */
+    public String toString() {
+        return toString(getCommandline());
+    }
+
+    /**
+     * Put quotes around the given String if necessary.
+     * <p>
+     * If the argument doesn't include spaces or quotes, return it as is. If it
+     * contains double quotes, use single quotes - else surround the argument by
+     * double quotes.
+     * </p>
+     * 
+     */
+    public static String quoteArgument(final String argument) {
+        if (argument.indexOf("\"") > -1) {
+            if (argument.indexOf("\'") > -1) {
+                throw new IllegalArgumentException(
+                        "Can\'t handle single and double"
+                        + " quotes in same argument");
+            } else {
+                return '\'' + argument + '\'';
+            }
+        } else if (argument.indexOf("\'") > -1 || argument.indexOf(" ") > -1) {
+            return '\"' + argument + '\"';
+        } else {
+            return argument;
+        }
+    }
+
+    /**
+     * Quotes the parts of the given array in way that makes them usable as
+     * command line arguments.
+     * 
+     * @return empty string for null or no command, else every argument split by
+     *         spaces and quoted by quoting rules
+     */
+    public static String toString(final 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(' ');
+            }
+            result.append(quoteArgument(line[i]));
+        }
+        return result.toString();
+    }
+
+    /**
+     * Crack a command line.
+     * 
+     * @param toProcess
+     *            the command line to process
+     * @return the command line broken into strings. An empty or null toProcess
+     *         parameter results in a zero sized array
+     */
+    public static String[] translateCommandline(final String toProcess) {
+        if (toProcess == null || toProcess.length() == 0) {
+            // no command? no string
+            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(toProcess, "\"\' ", true);
+        Vector v = new Vector();
+        StringBuffer current = new StringBuffer();
+        boolean lastTokenHasBeenQuoted = false;
+
+        while (tok.hasMoreTokens()) {
+            String nextTok = tok.nextToken();
+            switch (state) {
+            case inQuote:
+                if ("\'".equals(nextTok)) {
+                    lastTokenHasBeenQuoted = true;
+                    state = normal;
+                } else {
+                    current.append(nextTok);
+                }
+                break;
+            case inDoubleQuote:
+                if ("\"".equals(nextTok)) {
+                    lastTokenHasBeenQuoted = true;
+                    state = normal;
+                } else {
+                    current.append(nextTok);
+                }
+                break;
+            default:
+                if ("\'".equals(nextTok)) {
+                    state = inQuote;
+                } else if ("\"".equals(nextTok)) {
+                    state = inDoubleQuote;
+                } else if (" ".equals(nextTok)) {
+                    if (lastTokenHasBeenQuoted || current.length() != 0) {
+                        v.addElement(current.toString());
+                        current = new StringBuffer();
+                    }
+                } else {
+                    current.append(nextTok);
+                }
+                lastTokenHasBeenQuoted = false;
+                break;
+            }
+        }
+
+        if (lastTokenHasBeenQuoted || current.length() != 0) {
+            v.addElement(current.toString());
+        }
+
+        if (state == inQuote || state == inDoubleQuote) {
+            throw new IllegalArgumentException(
+                    "Unbalanced quotes in " + toProcess);
+        }
+
+        String[] args = new String[v.size()];
+        v.copyInto(args);
+        return args;
+    }
+
+    /**
+     * size operator. This actually creates the command line, so it is not a
+     * zero cost operation.
+     * 
+     * @return number of elements in the command, including the executable
+     */
+    public int size() {
+        return getCommandline().length;
+    }
+
+    /**
+     * Generate a deep clone of the contained object.
+     * 
+     * @return a clone of the contained object
+     * @throws CloneNotSupportedException 
+     */
+    public Object clone() throws CloneNotSupportedException {
+        CommandLineImpl c = (CommandLineImpl) super.clone();
+        c.arguments = (Vector) arguments.clone();
+        return c;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#clear()
+     */
+    public void clear() {
+        executable = null;
+        arguments.removeAllElements();
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.exec.CommandLineIn#clearArgs()
+     */
+    public void clearArgs() {
+        arguments.removeAllElements();
+    }
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/CommandLineImpl.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Exec.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Exec.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Exec.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Exec.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,442 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.exec.environment.Environment;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Executes a given command if the os platform is appropriate.
+ */
+public class Exec {
+    private static Log log = LogFactory.getLog(Exec.class);
+
+    private File dir;
+
+    private boolean newEnvironment = false;
+
+    private Long timeout = null;
+
+    private String executable;
+
+    private boolean resolveExecutable = false;
+
+    private boolean spawn = false;
+
+    private boolean incompatibleWithSpawn = false;
+
+    /**
+     * Controls whether the VM (1.3 and above) is used to execute the command.
+     */
+    private boolean vmLauncher = true;
+
+    public Exec() {
+        // default cnstr
+    }
+
+    /**
+     * Set whether or not you want the process to be spawned default is not
+     * spawned.
+     * 
+     * @param spawn
+     *            if true you do not want to wait for the end of the process
+     */
+    public void setSpawn(final boolean spawn) {
+        this.spawn = spawn;
+    }
+
+    /**
+     * Timeout in milliseconds after which the process will be killed.
+     * 
+     * @param value
+     *            timeout in milliseconds
+     */
+    public void setTimeout(final Long value) {
+        timeout = value;
+        incompatibleWithSpawn = true;
+    }
+
+    /**
+     * Timeout in milliseconds after which the process will be killed.
+     * 
+     * @param value
+     *            timeout in milliseconds
+     */
+    public void setTimeout(final Integer value) {
+        if (value == null) {
+            timeout = null;
+        } else {
+            setTimeout(new Long(value.intValue()));
+        }
+        incompatibleWithSpawn = true;
+    }
+
+    /**
+     * Set the working directory of the process.
+     * 
+     * @param d
+     *            the working directory of the process
+     */
+    public void setDir(final File d) {
+        this.dir = d;
+    }
+
+    /**
+     * Do not propagate old environment when new environment variables are
+     * specified.
+     * 
+     * @param newenv
+     *            if true, do not propagate old environment when new environment
+     *            variables are specified.
+     */
+    public void setNewEnvironment(final boolean newenv) {
+        newEnvironment = newenv;
+    }
+
+    /**
+     * Sets a flag indicating whether to attempt to resolve the executable to a
+     * file.
+     * 
+     * @param resolveExecutable
+     *            if true, attempt to resolve the path of the executable
+     */
+    public void setResolveExecutable(final boolean resolveExecutable) {
+        this.resolveExecutable = resolveExecutable;
+    }
+
+    /**
+     * Indicates whether to attempt to resolve the executable to a file.
+     */
+    public boolean isResolveExecutable() {
+        return resolveExecutable;
+    }
+
+    /**
+     * The method attempts to figure out where the executable is so that we can
+     * feed the full path. We first try basedir, then the exec dir, and then
+     * fallback to the straight executable name (i.e. on thier path).
+     * 
+     * @param exec
+     *            the name of the executable
+     * @param searchPath
+     *            if true, the excutable will be looked up in the PATH
+     *            environment and the absolute path is returned.
+     * @return the executable as a full path if it can be determined.
+     */
+    protected String resolveExecutable(final String exec,
+            final boolean searchPath) {
+        if (!resolveExecutable) {
+            return exec;
+        }
+
+        // try to find the executable
+        File executableFile = new File(exec);
+        if (executableFile.exists()) {
+            return executableFile.getAbsolutePath();
+        }
+
+        // FileUtils fileUtils = FileUtils.newFileUtils();
+        // now try to resolve against the dir if given
+        if (dir != null) {
+            executableFile = new File(dir, exec);
+            if (executableFile.exists()) {
+                return executableFile.getAbsolutePath();
+            }
+        }
+
+        // couldn't find it - must be on path
+        if (searchPath) {
+            // Vector env = Execute.getProcEnvironment();
+            // Enumeration e = env.elements();
+
+            // TODO should this be implemented?
+
+            /*
+             * Path p = null; while (e.hasMoreElements()) { String line =
+             * (String) e.nextElement(); if (line.startsWith("PATH=") ||
+             * line.startsWith("Path=")) { p = new Path(getProject(),
+             * line.substring(5)); break; } }
+             */
+
+            /*
+             * if (p != null) { String[] dirs = p.list(); for (int i = 0; i <
+             * dirs.length; i++) { executableFile = new File(dirs[i], exec); if
+             * (executableFile.exists()) { return
+             * executableFile.getAbsolutePath(); } } }
+             */
+        }
+
+        // searchPath is false, or no PATH or not found - keep our
+        // fingers crossed.
+        return exec;
+    }
+
+    /**
+     * Do the work.
+     * 
+     * @throws IOException
+     *             in a number of circumstances :
+     *             <ul>
+     *             <li>if failIfExecFails is set to true and the process cannot
+     *             be started</li>
+     *             <li>the java13command launcher can send build exceptions</li>
+     *             <li>this list is not exhaustive or limitative</li>
+     *             </ul>
+     */
+    public void execute(final CommandLine cl) throws IOException {
+        execute(cl, null, new LogOutputStream(1), new LogOutputStream(2));
+    }
+
+    public void execute(final CommandLine cl, final Environment env)
+            throws IOException {
+        execute(cl, env, new LogOutputStream(1), new LogOutputStream(2));
+    }
+
+    public void execute(final CommandLine cl, final OutputStream out,
+            final OutputStream error) throws IOException {
+        execute(cl, null, out, error);
+
+    }
+
+    public void execute(final CommandLine cmdl, final Environment env,
+            final OutputStream out, final OutputStream error)
+            throws IOException {
+        File savedDir = dir; // possibly altered in prepareExec
+
+        Environment environment;
+        if (env == null) {
+            environment = Environment.createEnvironment();
+        } else {
+            environment = env;
+        }
+
+        cmdl.setExecutable(resolveExecutable(executable, false));
+        checkConfiguration(cmdl);
+
+        try {
+            Execute exe = prepareExec(environment, out, error);
+            runExec(exe, cmdl);
+        } finally {
+            dir = savedDir;
+        }
+    }
+
+    public void execute(final CommandLine cmdl, final Environment env,
+            final InputStream in, final OutputStream out,
+            final OutputStream error) throws ExecuteException {
+        File savedDir = dir; // possibly altered in prepareExec
+
+        Environment environment;
+        if (env == null) {
+            environment = Environment.createEnvironment();
+        } else {
+            environment = env;
+        }
+
+        cmdl.setExecutable(resolveExecutable(executable, false));
+        checkConfiguration(cmdl);
+
+        try {
+            Execute exe = prepareExec(environment, in, out, error);
+            runExec(exe, cmdl);
+        } finally {
+            dir = savedDir;
+        }
+    }
+
+    /**
+     * Has the user set all necessary attributes?
+     * 
+     * @throws ExecuteException
+     *             if there are missing required parameters
+     */
+    protected void checkConfiguration(final CommandLine cmdl)
+            throws ExecuteException {
+        if (cmdl.getExecutable() == null) {
+            throw new ExecuteException("No executable specified");
+        }
+        if (dir != null && !dir.exists()) {
+            throw new ExecuteException("The directory you specified does not "
+                    + "exist");
+        }
+        if (dir != null && !dir.isDirectory()) {
+            throw new ExecuteException("The directory you specified is not a "
+                    + "directory");
+        }
+        if (spawn && incompatibleWithSpawn) {
+            throw new ExecuteException("Spawn also does not allow timeout");
+        }
+        // setupRedirector();
+    }
+
+    /**
+     * Set up properties on the redirector that we needed to store locally.
+     */
+    /*
+     * protected void setupRedirector() { redirector.setInput(input);
+     * redirector.setInputString(inputString); redirector.setOutput(output);
+     * redirector.setError(error); }
+     */
+
+    /**
+     * Sets a flag indicating if we want to launch new process with VM,
+     * otherwise use the OS's shell. Default value of the flag is true.
+     * 
+     * @param vmLauncher
+     *            true if we want to launch new process with VM, false if we
+     *            want to use the OS's shell.
+     */
+    public void setVMLauncher(final boolean vmLauncher) {
+        this.vmLauncher = vmLauncher;
+    }
+
+    /**
+     * Create an Execute instance with the correct working directory set.
+     * 
+     * @param error
+     * @param out
+     * @return an instance of the Execute class
+     * @throws ExecuteException
+     *             under unknown circumstances.
+     */
+    protected Execute prepareExec(final Environment env,
+            final OutputStream out, final OutputStream error)
+            throws ExecuteException {
+        return prepareExec(env, null, out, error);
+    }
+
+    protected Execute prepareExec(final Environment env, final InputStream in,
+            final OutputStream out, final OutputStream error)
+            throws ExecuteException {
+        // default directory to the current directory
+        /*if (dir == null) {
+            // TODO does this work on all platforms?
+            dir = new File(".");
+        }*/
+
+        Execute exe = new Execute(createHandler(in, out, error),
+                createWatchdog());
+
+        exe.setWorkingDirectory(dir);
+        exe.setVMLauncher(vmLauncher);
+
+        exe.setNewEnvironment(newEnvironment);
+        exe.setEnvironment(env.getVariables());
+        return exe;
+    }
+
+    /**
+     * A Utility method for this classes and subclasses to run an Execute
+     * instance (an external command).
+     * 
+     * @param exe
+     *            instance of the execute class
+     * @throws IOException
+     *             in case of problem to attach to the stdin/stdout/stderr
+     *             streams of the process
+     */
+    protected final void runExecute(final Execute exe) throws IOException {
+        int returnCode = -1; // assume the worst
+
+        if (!spawn) {
+            returnCode = exe.execute();
+
+            // test for and handle a forced process death
+            if (exe.killedProcess()) {
+                throw new ExecuteException("Timeout: killed the sub-process");
+            }
+
+            // redirector.complete();
+            if (Execute.isFailure(returnCode)) {
+                throw new ExecuteException(exe.getCommandline().getExecutable()
+                        + " returned: " + returnCode);
+            }
+        } else {
+            exe.spawn();
+        }
+    }
+
+    /**
+     * Run the command using the given Execute instance. This may be overridden
+     * by subclasses
+     * 
+     * @param exe
+     *            instance of Execute to run
+     * @throws ExecuteException
+     *             if the new process could not be started only if
+     *             failIfExecFails is set to true (the default)
+     */
+    protected void runExec(final Execute exe, final CommandLine cmdl)
+            throws ExecuteException {
+        // show the command
+        log.debug(cmdl.toString());
+
+        exe.setCommandline(cmdl);
+        try {
+            runExecute(exe);
+        } catch (IOException e) {
+            throw new ExecuteException("Execute failed: " + e.toString(), e);
+        } finally {
+            // close the output file if required
+            logFlush();
+        }
+    }
+
+    /**
+     * Create the StreamHandler to use with our Execute instance.
+     * 
+     * @param error
+     * @param out
+     * @return instance of ExecuteStreamHandler
+     * @throws ExecuteException
+     *             under unknown circumstances
+     */
+    protected ExecuteStreamHandler createHandler(final InputStream in,
+            final OutputStream out, final OutputStream error)
+            throws ExecuteException {
+        return new PumpStreamHandler(out, error, in);
+    }
+
+    /**
+     * Create the Watchdog to kill a runaway process.
+     * 
+     * @return instance of ExecuteWatchdog
+     * @throws ExecuteException
+     *             under unknown circumstances
+     */
+    protected ExecuteWatchdog createWatchdog() throws ExecuteException {
+        if (timeout == null) {
+            return null;
+        }
+
+        return new ExecuteWatchdog(timeout.longValue());
+    }
+
+    /**
+     * Flush the output stream - if there is one.
+     */
+    protected void logFlush() {
+    }
+
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Exec.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Exec.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Execute.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Execute.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Execute.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Execute.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,495 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.exec.environment.Environment;
+import org.apache.commons.exec.launcher.CommandLauncher;
+import org.apache.commons.exec.launcher.CommandLauncherFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Runs an external program.
+ */
+public class Execute {
+
+    private static Log LOG = LogFactory.getLog(Execute.class);
+
+    /** Invalid exit code. * */
+    public static final int INVALID = Integer.MAX_VALUE;
+
+    private CommandLine cmdl = null;
+
+    private Environment environment = null;
+
+    private int exitValue = INVALID;
+
+    private ExecuteStreamHandler streamHandler = new LogStreamHandler(1, 1);
+
+    private ExecuteWatchdog watchdog;
+
+    private File workingDirectory = null;
+
+    private boolean newEnvironment = false;
+
+    /** Controls whether the VM is used to launch commands, where possible */
+    private boolean useVMLauncher = true;
+
+    private static String userWorkingDirectory = System.getProperty("user.dir");
+
+    private static CommandLauncher vmLauncher = CommandLauncherFactory
+            .createVMLauncher();
+
+    private static CommandLauncher shellLauncher = CommandLauncherFactory
+            .createShellLauncher();
+
+    /** Used to destroy processes when the VM exits. */
+    private static ProcessDestroyer processDestroyer = new ProcessDestroyer();
+
+    /**
+     * ByteArrayOutputStream#toString doesn't seem to work reliably on OS/390,
+     * at least not the way we use it in the execution context.
+     * 
+     * @param bos
+     *            the output stream that one wants to read
+     * @return the output stream as a string, read with special encodings in the
+     *         case of z/os and os/400
+     */
+    public static String toString(final ByteArrayOutputStream bos) {
+        if (OS.isFamilyZOS()) {
+            try {
+                return bos.toString("Cp1047");
+            } catch (java.io.UnsupportedEncodingException e) {
+                // no-op default encoding used
+            }
+        } else if (OS.isFamilyOS400()) {
+            try {
+                return bos.toString("Cp500");
+            } catch (java.io.UnsupportedEncodingException e) {
+                // no-op default encoding used
+            }
+        }
+        return bos.toString();
+    }
+
+    /**
+     * 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.
+     */
+    public Execute(final ExecuteStreamHandler streamHandler) {
+        this(streamHandler, 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(final ExecuteStreamHandler streamHandler,
+            final ExecuteWatchdog watchdog) {
+        setStreamHandler(streamHandler);
+        this.watchdog = watchdog;
+    }
+
+    public void setStreamHandler(final ExecuteStreamHandler streamHandler) {
+        this.streamHandler = streamHandler;
+    }
+
+    /**
+     * Returns the command line used to create a subprocess.
+     * 
+     * @return the command line used to create a subprocess
+     */
+    public CommandLine getCommandline() {
+        return cmdl;
+    }
+
+    /**
+     * Sets the command line of the subprocess to launch.
+     * 
+     * @param commandline
+     *            the command line of the subprocess to launch
+     */
+    public void setCommandline(final CommandLine commandline) {
+        cmdl = commandline;
+    }
+
+    /**
+     * Set whether to propagate the default environment or not.
+     * 
+     * @param newenv
+     *            whether to propagate the process environment.
+     */
+    public void setNewEnvironment(final boolean newenv) {
+        newEnvironment = newenv;
+    }
+
+    /**
+     * Returns the environment used to create a subprocess.
+     * 
+     * @return the environment used to create a subprocess
+     */
+    public Environment getEnvironment() {
+        if (environment == null || newEnvironment) {
+            return environment;
+        }
+        return patchEnvironment();
+    }
+
+    /**
+     * Sets the environment variables for the subprocess to launch.
+     * 
+     * @param envVars
+     *            array of Strings, each element of which has an environment
+     *            variable settings in format <em>key=value</em>
+     */
+    public void setEnvironment(final String[] envVars) {
+        this.environment = Environment.createEnvironment(envVars);
+    }
+
+    /**
+     * Sets the environment variables for the subprocess to launch.
+     * 
+     * @param env
+     *            environment to set
+     */
+    public void setEnvironment(final Environment env) {
+        this.environment = env;
+    }
+
+    /**
+     * Sets the working directory of the process to execute.
+     * <p>
+     * This is emulated using the antRun scripts unless the OS is Windows NT in
+     * which case a cmd.exe is spawned, or MRJ and setting user.dir works, or
+     * JDK 1.3 and there is official support in java.lang.Runtime.
+     * 
+     * @param wd
+     *            the working directory of the process.
+     */
+    public void setWorkingDirectory(final File wd) {
+        if (wd == null || wd.getAbsolutePath().equals(userWorkingDirectory)) {
+            workingDirectory = null;
+        } else {
+            workingDirectory = wd;
+        }
+    }
+
+    /**
+     * Launch this execution through the VM, where possible, rather than through
+     * the OS's shell. In some cases and operating systems using the shell will
+     * allow the shell to perform additional processing such as associating an
+     * executable with a script, etc
+     * 
+     * @param useVMLauncher
+     *            true if exec should launch through the VM, false if the shell
+     *            should be used to launch the command.
+     */
+    public void setVMLauncher(final boolean useVMLauncher) {
+        this.useVMLauncher = useVMLauncher;
+    }
+
+    /**
+     * Creates a process that runs a command.
+     * 
+     * @param command
+     *            the command to run
+     * @param env
+     *            the environment for the command
+     * @param dir
+     *            the working directory for the command
+     * @param useVM
+     *            use the built-in exec command for JDK 1.3 if available.
+     * @return the process started
+     * @throws IOException
+     *             forwarded from the particular launcher used
+     */
+    public static Process launch(final CommandLine command,
+            final Environment env, final File dir, final boolean useVM)
+            throws IOException {
+        CommandLauncher launcher;
+        if (vmLauncher != null) {
+            launcher = vmLauncher;
+        } else {
+            launcher = shellLauncher;
+        }
+
+        if (!useVM) {
+            launcher = shellLauncher;
+        }
+
+        if (dir != null && !dir.exists()) {
+            throw new IOException(dir + " doesn't exist.");
+        }
+        return launcher.exec(command, env, dir);
+    }
+
+    /**
+     * 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.IOException
+     *                The exception is thrown, if launching of the subprocess
+     *                failed
+     */
+    public int execute() throws IOException {
+        if (workingDirectory != null && !workingDirectory.exists()) {
+            throw new IOException(workingDirectory + " doesn't exist.");
+        }
+
+        final Process process = launch(getCommandline(), getEnvironment(),
+                workingDirectory, useVMLauncher);
+
+        try {
+            streamHandler.setProcessInputStream(process.getOutputStream());
+            streamHandler.setProcessOutputStream(process.getInputStream());
+            streamHandler.setProcessErrorStream(process.getErrorStream());
+        } catch (IOException e) {
+            process.destroy();
+            throw e;
+        }
+        streamHandler.start();
+
+        try {
+            // add the process to the list of those to destroy if the VM exits
+            //
+            processDestroyer.add(process);
+
+            if (watchdog != null) {
+                watchdog.start(process);
+            }
+            waitFor(process);
+
+            if (watchdog != null) {
+                watchdog.stop();
+            }
+            streamHandler.stop();
+            closeStreams(process);
+
+            if (watchdog != null) {
+                watchdog.checkException();
+            }
+            return getExitValue();
+        } finally {
+            // remove the process to the list of those to destroy if the VM
+            // exits
+            //
+            processDestroyer.remove(process);
+        }
+    }
+
+    /**
+     * Starts a process defined by the command line. Ant will not wait for this
+     * process, nor log its output
+     * 
+     * @throws java.io.IOException
+     *             The exception is thrown, if launching of the subprocess
+     *             failed
+     */
+    public void spawn() throws IOException {
+        if (workingDirectory != null && !workingDirectory.exists()) {
+            throw new ExecuteException(workingDirectory + " doesn't exist.");
+        }
+        final Process process = launch(getCommandline(), getEnvironment(),
+                workingDirectory, useVMLauncher);
+        if (OS.isFamilyWindows()) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                LOG.debug("interruption in the sleep after "
+                        + "having spawned a process");
+            }
+        }
+
+        OutputStream dummyOut = new OutputStream() {
+            public void write(final int b) throws IOException {
+            }
+        };
+
+        ExecuteStreamHandler streamHandler = new PumpStreamHandler(dummyOut);
+        streamHandler.setProcessErrorStream(process.getErrorStream());
+        streamHandler.setProcessOutputStream(process.getInputStream());
+        streamHandler.start();
+        process.getOutputStream().close();
+
+        LOG.debug("spawned process " + process.toString());
+    }
+
+    /**
+     * Wait for a given process.
+     * 
+     * @param process
+     *            the process one wants to wait for
+     */
+    protected void waitFor(final Process process) {
+        try {
+            process.waitFor();
+            setExitValue(process.exitValue());
+        } catch (InterruptedException e) {
+            process.destroy();
+        }
+    }
+
+    /**
+     * Set the exit value.
+     * 
+     * @param value
+     *            exit value of the process
+     */
+    protected void setExitValue(final int value) {
+        exitValue = value;
+    }
+
+    /**
+     * Query the exit value of the process.
+     * 
+     * @return the exit value or Execute.INVALID if no exit value has been
+     *         received
+     */
+    public int getExitValue() {
+        return exitValue;
+    }
+
+    /**
+     * Checks whether <code>exitValue</code> signals a failure on the current
+     * system (OS specific).
+     * <p>
+     * <b>Note</b> that this method relies on the conventions of the OS, it
+     * will return false results if the application you are running doesn't
+     * follow these conventions. One notable exception is the Java VM provided
+     * by HP for OpenVMS - it will return 0 if successful (like on any other
+     * platform), but this signals a failure on OpenVMS. So if you execute a new
+     * Java VM on OpenVMS, you cannot trust this method.
+     * </p>
+     * 
+     * @param exitValue
+     *            the exit value (return code) to be checked
+     * @return <code>true</code> if <code>exitValue</code> signals a failure
+     */
+    public static boolean isFailure(final int exitValue) {
+        if (OS.isFamilyOpenVms()) {
+            // even exit value signals failure
+            return (exitValue % 2) == 0;
+        } else {
+            // non zero exit value signals failure
+            return exitValue != 0;
+        }
+    }
+
+    /**
+     * Test for an untimely death of the process.
+     * 
+     * @return true if a watchdog had to kill the process
+     */
+    public boolean killedProcess() {
+        return watchdog != null && watchdog.killedProcess();
+    }
+
+    /**
+     * Patch the current environment with the new values from the user.
+     * 
+     * @return the patched environment
+     */
+    private Environment patchEnvironment() {
+        // On OpenVMS Runtime#exec() doesn't support the environment array,
+        // so we only return the new values which then will be set in
+        // the generated DCL script, inheriting the parent process environment
+        if (OS.isFamilyOpenVms()) {
+            return environment;
+        }
+
+        Environment osEnv = (Environment) Environment.getProcEnvironment()
+                .clone();
+
+        osEnv.putAll(environment);
+
+        return osEnv;
+    }
+
+    /**
+     * A utility method that runs an external command. Writes the output and
+     * error streams of the command to the project log.
+     * 
+     * @param cmdline
+     *            The command to execute.
+     * @throws ExecuteException
+     *             if the command does not return 0.
+     */
+    public static void runCommand(final CommandLine cmdline)
+            throws ExecuteException {
+        try {
+            LOG.debug(cmdline);
+            Execute exe = new Execute(new LogStreamHandler(999, 999));
+
+            exe.setCommandline(cmdline);
+            int retval = exe.execute();
+            if (isFailure(retval)) {
+                throw new ExecuteException(cmdline.getExecutable()
+                        + " failed with return code " + retval);
+            }
+        } catch (java.io.IOException exc) {
+            throw new ExecuteException("Could not launch "
+                    + cmdline.getExecutable() + ": " + exc);
+        }
+    }
+
+    /**
+     * Close the streams belonging to the given Process.
+     * 
+     * @param process
+     *            the <CODE>Process</CODE>.
+     */
+    public static void closeStreams(final Process process) {
+        try {
+            process.getInputStream().close();
+        } catch (IOException eyeOhEx) {
+            // ignore error
+        }
+        try {
+            process.getOutputStream().close();
+        } catch (IOException eyeOhEx) {
+            // ignore error
+        }
+        try {
+            process.getErrorStream().close();
+        } catch (IOException eyeOhEx) {
+            // ignore error
+        }
+    }
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Execute.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Execute.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteException.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteException.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteException.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteException.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,91 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.IOException;
+
+public class ExecuteException extends IOException {
+
+    /**
+     * Comment for <code>serialVersionUID</code>.
+     */
+    private static final long serialVersionUID = 3256443620654331699L;
+
+    /**
+     * Construct a new exception with <code>null</code> as its detail message.
+     */
+    public ExecuteException() {
+
+        super();
+
+    }
+
+    /**
+     * Construct a new exception with the specified detail message.
+     * 
+     * @param message
+     *            The detail message
+     */
+    public ExecuteException(final String message) {
+
+        super(message);
+
+    }
+
+    /**
+     * Construct a new exception with the specified cause and a derived detail
+     * message.
+     * 
+     * @param cause
+     *            The underlying cause
+     */
+    public ExecuteException(final Throwable cause) {
+
+        this((cause == null) ? null : cause.toString(), cause);
+
+    }
+
+    /**
+     * Construct a new exception with the specified detail message and cause.
+     * 
+     * @param message
+     *            The detail message
+     * @param cause
+     *            The underlying cause
+     */
+    public ExecuteException(final String message, final Throwable cause) {
+
+        super(message + " (Caused by " + cause + ")");
+        this.cause = cause; // Two-argument version requires JDK 1.4 or later
+
+    }
+
+    /**
+     * The underlying cause of this exception.
+     */
+    private Throwable cause = null;
+
+    /**
+     * Return the underlying cause of this exception (if any).
+     */
+    public Throwable getCause() {
+
+        return (this.cause);
+
+    }
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteException.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,64 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Used by <code>Execute</code> to handle input and output stream of
+ * subprocesses.
+ */
+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
+     */
+    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
+     */
+    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
+     */
+    void setProcessOutputStream(InputStream is) throws IOException;
+
+    /**
+     * Start handling of the streams.
+     */
+    void start() throws IOException;
+
+    /**
+     * Stop handling of the streams - will not be restarted.
+     */
+    void stop();
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,177 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.IOException;
+
+/**
+ * Destroys a process running for too long. For example:
+ * 
+ * <pre>
+ * ExecuteWatchdog watchdog = new ExecuteWatchdog(30000);
+ * Execute exec = new Execute(myloghandler, watchdog);
+ * exec.setCommandLine(mycmdline);
+ * int exitvalue = exec.execute();
+ * if (Execute.isFailure(exitvalue) &amp;&amp; watchdog.killedProcess()) {
+ *     // it was killed on purpose by the watchdog
+ * }
+ * </pre>
+ * 
+ * @see org.apache.commons.exec.Execute
+ * @see org.apache.commons.exec.Watchdog
+ */
+public class ExecuteWatchdog implements TimeoutObserver {
+
+    /** The process to execute and watch for duration. */
+    private Process process;
+
+    /** Say whether or not the watchdog is currently monitoring a process. */
+    private boolean watch = false;
+
+    /** Exception that might be thrown during the process execution. */
+    private Exception caught = null;
+
+    /** Say whether or not the process was killed due to running overtime. */
+    private boolean killedProcess = false;
+
+    /** Will tell us whether timeout has occurred. */
+    private Watchdog watchdog;
+
+    /**
+     * Creates a new watchdog with a given timeout.
+     * 
+     * @param timeout
+     *            the timeout for the process in milliseconds. It must be
+     *            greater than 0.
+     */
+    public ExecuteWatchdog(final long timeout) {
+        watchdog = new Watchdog(timeout);
+        watchdog.addTimeoutObserver(this);
+    }
+
+    /**
+     * @see #ExecuteWatchdog(long)
+     * @deprecated Use constructor with a long type instead. (1.4.x
+     *             compatibility)
+     */
+    public ExecuteWatchdog(final int timeout) {
+        this((long) timeout);
+    }
+
+    /**
+     * Watches the given process and terminates it, if it runs for too long. All
+     * information from the previous run are reset.
+     * 
+     * @param process
+     *            the process to monitor. It cannot be <tt>null</tt>
+     * @throws IllegalStateException
+     *             if a process is still being monitored.
+     */
+    public synchronized void start(final Process process) {
+        if (process == null) {
+            throw new NullPointerException("process is null.");
+        }
+        if (this.process != null) {
+            throw new IllegalStateException("Already running.");
+        }
+        this.caught = null;
+        this.killedProcess = false;
+        this.watch = true;
+        this.process = process;
+        watchdog.start();
+    }
+
+    /**
+     * Stops the watcher. It will notify all threads possibly waiting on this
+     * object.
+     */
+    public synchronized void stop() {
+        watchdog.stop();
+        watch = false;
+        process = null;
+    }
+
+    /**
+     * Called after watchdog has finished.
+     */
+    public void timeoutOccured(final Watchdog w) {
+        try {
+            try {
+                // We must check if the process was not stopped
+                // before being here
+                process.exitValue();
+            } catch (IllegalThreadStateException itse) {
+                // the process is not terminated, if this is really
+                // a timeout and not a manual stop then kill it.
+                if (watch) {
+                    killedProcess = true;
+                    process.destroy();
+                }
+            }
+        } catch (Exception e) {
+            caught = e;
+        } finally {
+            cleanUp();
+        }
+    }
+
+    /**
+     * reset the monitor flag and the process.
+     */
+    protected void cleanUp() {
+        watch = false;
+        process = null;
+    }
+
+    /**
+     * This method will rethrow the exception that was possibly caught during
+     * the run of the process. It will only remains valid once the process has
+     * been terminated either by 'error', timeout or manual intervention.
+     * Information will be discarded once a new process is ran.
+     * 
+     * @throws IOException
+     *             a wrapped exception over the one that was silently swallowed
+     *             and stored during the process run.
+     */
+    public void checkException() throws IOException {
+        if (caught != null) {
+            throw new ExecuteException("Exception in ExecuteWatchdog.run: "
+                    + caught.getMessage(), caught);
+        }
+    }
+
+    /**
+     * Indicates whether or not the watchdog is still monitoring the process.
+     * 
+     * @return <tt>true</tt> if the process is still running, otherwise
+     *         <tt>false</tt>.
+     */
+    public boolean isWatching() {
+        return watch;
+    }
+
+    /**
+     * Indicates whether the last process run was killed on timeout or not.
+     * 
+     * @return <tt>true</tt> if the process was killed otherwise
+     *         <tt>false</tt>.
+     */
+    public boolean killedProcess() {
+        return killedProcess;
+    }
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogOutputStream.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogOutputStream.java?rev=230452&view=auto
==============================================================================
--- jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogOutputStream.java (added)
+++ jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogOutputStream.java Fri Aug  5 05:21:46 2005
@@ -0,0 +1,172 @@
+/* 
+ * Copyright 2005  The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.commons.exec;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 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.
+ */
+public class LogOutputStream extends OutputStream {
+
+    private static Log log = LogFactory.getLog(LogOutputStream.class);
+
+    /** Initial buffer size. */
+    private static final int INTIAL_SIZE = 132;
+
+    /** Carriage return */
+    private static final int CR = 0x0d;
+
+    /** Linefeed */
+    private static final int LF = 0x0a;
+
+    private ByteArrayOutputStream buffer = new ByteArrayOutputStream(
+            INTIAL_SIZE);
+
+    private boolean skip = false;
+
+    private int level = 999;
+
+    /**
+     * 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(final int level) {
+        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(final int cc) throws IOException {
+        final byte c = (byte) cc;
+        if ((c == '\n') || (c == '\r')) {
+            if (!skip) {
+                processBuffer();
+            }
+        } else {
+            buffer.write(cc);
+        }
+        skip = (c == '\r');
+    }
+
+    /**
+     * Flush this log stream
+     */
+    public void flush() {
+        if (buffer.size() > 0) {
+            processBuffer();
+        }
+    }
+
+    /**
+     * 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(final String line) {
+        processLine(line, level);
+    }
+
+    /**
+     * Logs a line to the log system of ant.
+     * 
+     * @param line
+     *            the line to log.
+     */
+    protected void processLine(final String line, final int level) {
+        log.debug(line);
+    }
+
+    /**
+     * Writes all remaining
+     */
+    public void close() throws IOException {
+        if (buffer.size() > 0) {
+            processBuffer();
+        }
+        super.close();
+    }
+
+    public int getMessageLevel() {
+        return level;
+    }
+
+    /**
+     * Write a block of characters to the output stream
+     * 
+     * @param b
+     *            the array containing the data
+     * @param off
+     *            the offset into the array where data starts
+     * @param len
+     *            the length of block
+     * @throws IOException
+     *             if the data cannot be written into the stream.
+     */
+    public void write(final byte[] b, final int off, final int len)
+            throws IOException {
+        // find the line breaks and pass other chars through in blocks
+        int offset = off;
+        int blockStartOffset = offset;
+        int remaining = len;
+        while (remaining > 0) {
+            while (remaining > 0 && b[offset] != LF && b[offset] != CR) {
+                offset++;
+                remaining--;
+            }
+            // either end of buffer or a line separator char
+            int blockLength = offset - blockStartOffset;
+            if (blockLength > 0) {
+                buffer.write(b, blockStartOffset, blockLength);
+            }
+            while (remaining > 0 && (b[offset] == LF || b[offset] == CR)) {
+                write(b[offset]);
+                offset++;
+                remaining--;
+            }
+            blockStartOffset = offset;
+        }
+    }
+
+}

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/LogOutputStream.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org