From bce6c8db00fd4ba46391572d331a1db16ff56270 Mon Sep 17 00:00:00 2001 From: Peter Donald Date: Wed, 19 Dec 2001 11:48:26 +0000 Subject: [PATCH] Move command launchers to top level classes. Inner classes are evil. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270266 13f79535-47bb-0310-9956-ffa450edef68 --- .../ant/taskdefs/exec/CommandLauncher.java | 66 +++++++++++++++ .../taskdefs/exec/CommandLauncherProxy.java | 44 ++++++++++ .../taskdefs/exec/Java11CommandLauncher.java | 48 +++++++++++ .../taskdefs/exec/Java13CommandLauncher.java | 83 +++++++++++++++++++ .../ant/taskdefs/exec/MacCommandLauncher.java | 56 +++++++++++++ .../exec/PerlScriptCommandLauncher.java | 78 +++++++++++++++++ .../taskdefs/exec/ScriptCommandLauncher.java | 77 +++++++++++++++++ .../taskdefs/exec/WinNTCommandLauncher.java | 68 +++++++++++++++ .../ant/taskdefs/exec/CommandLauncher.java | 66 +++++++++++++++ .../taskdefs/exec/CommandLauncherProxy.java | 44 ++++++++++ .../taskdefs/exec/Java11CommandLauncher.java | 48 +++++++++++ .../taskdefs/exec/Java13CommandLauncher.java | 83 +++++++++++++++++++ .../ant/taskdefs/exec/MacCommandLauncher.java | 56 +++++++++++++ .../exec/PerlScriptCommandLauncher.java | 78 +++++++++++++++++ .../taskdefs/exec/ScriptCommandLauncher.java | 77 +++++++++++++++++ .../taskdefs/exec/WinNTCommandLauncher.java | 68 +++++++++++++++ 16 files changed, 1040 insertions(+) create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java create mode 100644 proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java create mode 100644 proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java new file mode 100644 index 000000000..7fd7723b1 --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Commandline; +import org.apache.myrmidon.api.TaskException; +import java.io.IOException; +import java.io.File; + +/** + * A command launcher for a particular JVM/OS platform. This class is a + * general purpose command launcher which can only launch commands in the + * current working directory. + */ +class CommandLauncher +{ + /** + * Launches the given command in a new process. + * + * @param project The project that the command is part of + * @param cmd The command to execute + * @param env The environment for the new process. If null, the + * environment of the current proccess is used. + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env ) + throws IOException, TaskException + { + if( project != null ) + { + project.log( "Execute:CommandLauncher: " + + Commandline.toString( cmd ), Project.MSG_DEBUG ); + } + return Runtime.getRuntime().exec( cmd, env ); + } + + /** + * Launches the given command in a new process, in the given working + * directory. + * + * @param project The project that the command is part of + * @param cmd The command to execute + * @param env The environment for the new process. If null, the + * environment of the current proccess is used. + * @param workingDir The directory to start the command in. If null, the + * current directory is used + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + throw new IOException( "Cannot execute a process in different directory under this JVM" ); + } +} diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java new file mode 100644 index 000000000..dd1e4ed79 --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import java.io.IOException; + +/** + * A command launcher that proxies another command launcher. Sub-classes + * override exec(args, env, workdir) + */ +class CommandLauncherProxy + extends CommandLauncher +{ + + private CommandLauncher _launcher; + + CommandLauncherProxy( CommandLauncher launcher ) + { + _launcher = launcher; + } + + /** + * Launches the given command in a new process. Delegates this method to + * the proxied launcher + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env ) + throws IOException, TaskException + { + return _launcher.exec( project, cmd, env ); + } +} diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java new file mode 100644 index 000000000..d40b82722 --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Commandline; +import org.apache.myrmidon.api.TaskException; +import java.io.IOException; + +/** + * A command launcher for JDK/JRE 1.1 under Windows. Fixes quoting problems + * in Runtime.exec(). Can only launch commands in the current working + * directory + */ +class Java11CommandLauncher + extends CommandLauncher +{ + /** + * Launches the given command in a new process. Needs to quote arguments + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env ) + throws IOException, TaskException + { + // Need to quote arguments with spaces, and to escape quote characters + String[] newcmd = new String[ cmd.length ]; + for( int i = 0; i < cmd.length; i++ ) + { + newcmd[ i ] = Commandline.quoteArgument( cmd[ i ] ); + } + if( project != null ) + { + project.log( "Execute:Java11CommandLauncher: " + + Commandline.toString( newcmd ), Project.MSG_DEBUG ); + } + return Runtime.getRuntime().exec( newcmd, env ); + } +} diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java new file mode 100644 index 000000000..e67045584 --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.io.File; +import java.io.IOException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Commandline; +import org.apache.myrmidon.api.TaskException; + +/** + * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in + * Runtime.exec() command + * + * @author RT + */ +class Java13CommandLauncher + extends CommandLauncher +{ + + private Method _execWithCWD; + + public Java13CommandLauncher() + throws NoSuchMethodException + { + // Locate method Runtime.exec(String[] cmdarray, String[] envp, File dir) + _execWithCWD = Runtime.class.getMethod( "exec", new Class[]{String[].class, String[].class, File.class} ); + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + try + { + if( project != null ) + { + project.log( "Execute:Java13CommandLauncher: " + + Commandline.toString( cmd ), Project.MSG_DEBUG ); + } + Object[] arguments = {cmd, env, workingDir}; + return (Process)_execWithCWD.invoke( Runtime.getRuntime(), arguments ); + } + catch( InvocationTargetException exc ) + { + Throwable realexc = exc.getTargetException(); + if( realexc instanceof ThreadDeath ) + { + throw (ThreadDeath)realexc; + } + else if( realexc instanceof IOException ) + { + throw (IOException)realexc; + } + else + { + throw new TaskException( "Unable to execute command", realexc ); + } + } + catch( Exception exc ) + { + // IllegalAccess, IllegalArgument, ClassCast + throw new TaskException( "Unable to execute command", exc ); + } + } +} diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java new file mode 100644 index 000000000..b0e2b43c5 --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher for Mac that uses a dodgy mechanism to change working + * directory before launching commands. + */ +class MacCommandLauncher + extends CommandLauncherProxy +{ + MacCommandLauncher( CommandLauncher launcher ) + { + super( launcher ); + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + + System.getProperties().put( "user.dir", workingDir.getAbsolutePath() ); + try + { + return exec( project, cmd, env ); + } + finally + { + System.getProperties().put( "user.dir", Execute.antWorkingDirectory ); + } + } +} diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java new file mode 100644 index 000000000..18a27d891 --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import org.apache.avalon.excalibur.io.FileUtil; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher that uses an auxiliary perl script to launch commands + * in directories other than the current working directory. + */ +class PerlScriptCommandLauncher + extends CommandLauncherProxy +{ + private String _script; + + PerlScriptCommandLauncher( String script, CommandLauncher launcher ) + { + super( launcher ); + _script = script; + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( project == null ) + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + throw new IOException( "Cannot locate antRun script: No project provided" ); + } + + // Locate the auxiliary script + String antHome = project.getProperty( "ant.home" ); + if( antHome == null ) + { + throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); + } + String antRun = FileUtil. + resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); + + // Build the command + File commandDir = workingDir; + if( workingDir == null && project != null ) + { + commandDir = project.getBaseDir(); + } + + String[] newcmd = new String[ cmd.length + 3 ]; + newcmd[ 0 ] = "perl"; + newcmd[ 1 ] = antRun; + newcmd[ 2 ] = commandDir.getAbsolutePath(); + System.arraycopy( cmd, 0, newcmd, 3, cmd.length ); + + return exec( project, newcmd, env ); + } +} diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java new file mode 100644 index 000000000..3f195f308 --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import org.apache.avalon.excalibur.io.FileUtil; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher that uses an auxiliary script to launch commands in + * directories other than the current working directory. + */ +class ScriptCommandLauncher + extends CommandLauncherProxy +{ + private String _script; + + ScriptCommandLauncher( String script, CommandLauncher launcher ) + { + super( launcher ); + _script = script; + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( project == null ) + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + throw new IOException( "Cannot locate antRun script: No project provided" ); + } + + // Locate the auxiliary script + String antHome = project.getProperty( "ant.home" ); + if( antHome == null ) + { + throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); + } + String antRun = FileUtil. + resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); + + // Build the command + File commandDir = workingDir; + if( workingDir == null && project != null ) + { + commandDir = project.getBaseDir(); + } + + String[] newcmd = new String[ cmd.length + 2 ]; + newcmd[ 0 ] = antRun; + newcmd[ 1 ] = commandDir.getAbsolutePath(); + System.arraycopy( cmd, 0, newcmd, 2, cmd.length ); + + return exec( project, newcmd, env ); + } +} diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java new file mode 100644 index 000000000..ef0a0d19e --- /dev/null +++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher for Windows 2000/NT that uses 'cmd.exe' when launching + * commands in directories other than the current working directory. + */ +class WinNTCommandLauncher + extends CommandLauncherProxy +{ + WinNTCommandLauncher( CommandLauncher launcher ) + { + super( launcher ); + } + + /** + * Launches the given command in a new process, in the given working + * directory. + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + File commandDir = workingDir; + if( workingDir == null ) + { + if( project != null ) + { + commandDir = project.getBaseDir(); + } + else + { + return exec( project, cmd, env ); + } + } + + // Use cmd.exe to change to the specified directory before running + // the command + final int preCmdLength = 6; + String[] newcmd = new String[ cmd.length + preCmdLength ]; + newcmd[ 0 ] = "cmd"; + newcmd[ 1 ] = "/c"; + newcmd[ 2 ] = "cd"; + newcmd[ 3 ] = "/d"; + newcmd[ 4 ] = commandDir.getAbsolutePath(); + newcmd[ 5 ] = "&&"; + System.arraycopy( cmd, 0, newcmd, preCmdLength, cmd.length ); + + return exec( project, newcmd, env ); + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java new file mode 100644 index 000000000..7fd7723b1 --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncher.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Commandline; +import org.apache.myrmidon.api.TaskException; +import java.io.IOException; +import java.io.File; + +/** + * A command launcher for a particular JVM/OS platform. This class is a + * general purpose command launcher which can only launch commands in the + * current working directory. + */ +class CommandLauncher +{ + /** + * Launches the given command in a new process. + * + * @param project The project that the command is part of + * @param cmd The command to execute + * @param env The environment for the new process. If null, the + * environment of the current proccess is used. + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env ) + throws IOException, TaskException + { + if( project != null ) + { + project.log( "Execute:CommandLauncher: " + + Commandline.toString( cmd ), Project.MSG_DEBUG ); + } + return Runtime.getRuntime().exec( cmd, env ); + } + + /** + * Launches the given command in a new process, in the given working + * directory. + * + * @param project The project that the command is part of + * @param cmd The command to execute + * @param env The environment for the new process. If null, the + * environment of the current proccess is used. + * @param workingDir The directory to start the command in. If null, the + * current directory is used + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + throw new IOException( "Cannot execute a process in different directory under this JVM" ); + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java new file mode 100644 index 000000000..dd1e4ed79 --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/CommandLauncherProxy.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import java.io.IOException; + +/** + * A command launcher that proxies another command launcher. Sub-classes + * override exec(args, env, workdir) + */ +class CommandLauncherProxy + extends CommandLauncher +{ + + private CommandLauncher _launcher; + + CommandLauncherProxy( CommandLauncher launcher ) + { + _launcher = launcher; + } + + /** + * Launches the given command in a new process. Delegates this method to + * the proxied launcher + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env ) + throws IOException, TaskException + { + return _launcher.exec( project, cmd, env ); + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java new file mode 100644 index 000000000..d40b82722 --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java11CommandLauncher.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Commandline; +import org.apache.myrmidon.api.TaskException; +import java.io.IOException; + +/** + * A command launcher for JDK/JRE 1.1 under Windows. Fixes quoting problems + * in Runtime.exec(). Can only launch commands in the current working + * directory + */ +class Java11CommandLauncher + extends CommandLauncher +{ + /** + * Launches the given command in a new process. Needs to quote arguments + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env ) + throws IOException, TaskException + { + // Need to quote arguments with spaces, and to escape quote characters + String[] newcmd = new String[ cmd.length ]; + for( int i = 0; i < cmd.length; i++ ) + { + newcmd[ i ] = Commandline.quoteArgument( cmd[ i ] ); + } + if( project != null ) + { + project.log( "Execute:Java11CommandLauncher: " + + Commandline.toString( newcmd ), Project.MSG_DEBUG ); + } + return Runtime.getRuntime().exec( newcmd, env ); + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java new file mode 100644 index 000000000..e67045584 --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Java13CommandLauncher.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.io.File; +import java.io.IOException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.Commandline; +import org.apache.myrmidon.api.TaskException; + +/** + * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in + * Runtime.exec() command + * + * @author RT + */ +class Java13CommandLauncher + extends CommandLauncher +{ + + private Method _execWithCWD; + + public Java13CommandLauncher() + throws NoSuchMethodException + { + // Locate method Runtime.exec(String[] cmdarray, String[] envp, File dir) + _execWithCWD = Runtime.class.getMethod( "exec", new Class[]{String[].class, String[].class, File.class} ); + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + try + { + if( project != null ) + { + project.log( "Execute:Java13CommandLauncher: " + + Commandline.toString( cmd ), Project.MSG_DEBUG ); + } + Object[] arguments = {cmd, env, workingDir}; + return (Process)_execWithCWD.invoke( Runtime.getRuntime(), arguments ); + } + catch( InvocationTargetException exc ) + { + Throwable realexc = exc.getTargetException(); + if( realexc instanceof ThreadDeath ) + { + throw (ThreadDeath)realexc; + } + else if( realexc instanceof IOException ) + { + throw (IOException)realexc; + } + else + { + throw new TaskException( "Unable to execute command", realexc ); + } + } + catch( Exception exc ) + { + // IllegalAccess, IllegalArgument, ClassCast + throw new TaskException( "Unable to execute command", exc ); + } + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java new file mode 100644 index 000000000..b0e2b43c5 --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/MacCommandLauncher.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher for Mac that uses a dodgy mechanism to change working + * directory before launching commands. + */ +class MacCommandLauncher + extends CommandLauncherProxy +{ + MacCommandLauncher( CommandLauncher launcher ) + { + super( launcher ); + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + + System.getProperties().put( "user.dir", workingDir.getAbsolutePath() ); + try + { + return exec( project, cmd, env ); + } + finally + { + System.getProperties().put( "user.dir", Execute.antWorkingDirectory ); + } + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java new file mode 100644 index 000000000..18a27d891 --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/PerlScriptCommandLauncher.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import org.apache.avalon.excalibur.io.FileUtil; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher that uses an auxiliary perl script to launch commands + * in directories other than the current working directory. + */ +class PerlScriptCommandLauncher + extends CommandLauncherProxy +{ + private String _script; + + PerlScriptCommandLauncher( String script, CommandLauncher launcher ) + { + super( launcher ); + _script = script; + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( project == null ) + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + throw new IOException( "Cannot locate antRun script: No project provided" ); + } + + // Locate the auxiliary script + String antHome = project.getProperty( "ant.home" ); + if( antHome == null ) + { + throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); + } + String antRun = FileUtil. + resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); + + // Build the command + File commandDir = workingDir; + if( workingDir == null && project != null ) + { + commandDir = project.getBaseDir(); + } + + String[] newcmd = new String[ cmd.length + 3 ]; + newcmd[ 0 ] = "perl"; + newcmd[ 1 ] = antRun; + newcmd[ 2 ] = commandDir.getAbsolutePath(); + System.arraycopy( cmd, 0, newcmd, 3, cmd.length ); + + return exec( project, newcmd, env ); + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java new file mode 100644 index 000000000..3f195f308 --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/ScriptCommandLauncher.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import org.apache.avalon.excalibur.io.FileUtil; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher that uses an auxiliary script to launch commands in + * directories other than the current working directory. + */ +class ScriptCommandLauncher + extends CommandLauncherProxy +{ + private String _script; + + ScriptCommandLauncher( String script, CommandLauncher launcher ) + { + super( launcher ); + _script = script; + } + + /** + * Launches the given command in a new process, in the given working + * directory + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + if( project == null ) + { + if( workingDir == null ) + { + return exec( project, cmd, env ); + } + throw new IOException( "Cannot locate antRun script: No project provided" ); + } + + // Locate the auxiliary script + String antHome = project.getProperty( "ant.home" ); + if( antHome == null ) + { + throw new IOException( "Cannot locate antRun script: Property 'ant.home' not found" ); + } + String antRun = FileUtil. + resolveFile( project.getBaseDir(), antHome + File.separator + _script ).toString(); + + // Build the command + File commandDir = workingDir; + if( workingDir == null && project != null ) + { + commandDir = project.getBaseDir(); + } + + String[] newcmd = new String[ cmd.length + 2 ]; + newcmd[ 0 ] = antRun; + newcmd[ 1 ] = commandDir.getAbsolutePath(); + System.arraycopy( cmd, 0, newcmd, 2, cmd.length ); + + return exec( project, newcmd, env ); + } +} diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java new file mode 100644 index 000000000..ef0a0d19e --- /dev/null +++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/WinNTCommandLauncher.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) The Apache Software Foundation. All rights reserved. + * + * This software is published under the terms of the Apache Software License + * version 1.1, a copy of which has been included with this distribution in + * the LICENSE.txt file. + */ +package org.apache.tools.ant.taskdefs.exec; + +import org.apache.tools.ant.Project; +import org.apache.myrmidon.api.TaskException; +import java.io.File; +import java.io.IOException; + +/** + * A command launcher for Windows 2000/NT that uses 'cmd.exe' when launching + * commands in directories other than the current working directory. + */ +class WinNTCommandLauncher + extends CommandLauncherProxy +{ + WinNTCommandLauncher( CommandLauncher launcher ) + { + super( launcher ); + } + + /** + * Launches the given command in a new process, in the given working + * directory. + * + * @param project Description of Parameter + * @param cmd Description of Parameter + * @param env Description of Parameter + * @param workingDir Description of Parameter + * @return Description of the Returned Value + * @exception IOException Description of Exception + */ + public Process exec( Project project, String[] cmd, String[] env, File workingDir ) + throws IOException, TaskException + { + File commandDir = workingDir; + if( workingDir == null ) + { + if( project != null ) + { + commandDir = project.getBaseDir(); + } + else + { + return exec( project, cmd, env ); + } + } + + // Use cmd.exe to change to the specified directory before running + // the command + final int preCmdLength = 6; + String[] newcmd = new String[ cmd.length + preCmdLength ]; + newcmd[ 0 ] = "cmd"; + newcmd[ 1 ] = "/c"; + newcmd[ 2 ] = "cd"; + newcmd[ 3 ] = "/d"; + newcmd[ 4 ] = commandDir.getAbsolutePath(); + newcmd[ 5 ] = "&&"; + System.arraycopy( cmd, 0, newcmd, preCmdLength, cmd.length ); + + return exec( project, newcmd, env ); + } +}