Browse Source

Move inner classes to top level classes.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270269 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
eff18a7fed
2 changed files with 136 additions and 978 deletions
  1. +68
    -489
      proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Execute.java
  2. +68
    -489
      proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Execute.java

+ 68
- 489
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/exec/Execute.java View File

@@ -12,11 +12,8 @@ import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale; import java.util.Locale;
import java.util.Vector; import java.util.Vector;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.Os; import org.apache.myrmidon.framework.Os;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
@@ -35,29 +32,29 @@ public class Execute
*/ */
public final static int INVALID = Integer.MAX_VALUE; public final static int INVALID = Integer.MAX_VALUE;


private static String antWorkingDirectory = System.getProperty( "user.dir" );
private static CommandLauncher vmLauncher;
private static CommandLauncher shellLauncher;
private static Vector procEnvironment;
private static String c_antWorkingDirectory = System.getProperty( "user.dir" );
private static CommandLauncher c_vmLauncher;
private static CommandLauncher c_shellLauncher;
private static Vector c_procEnvironment;


/** /**
* Used to destroy processes when the VM exits. * Used to destroy processes when the VM exits.
*/ */
private static ProcessDestroyer processDestroyer = new ProcessDestroyer();
private static ProcessDestroyer c_processDestroyer = new ProcessDestroyer();


private String[] cmdl = null;
private String[] env = null;
private int exitValue = INVALID;
private File workingDirectory = null;
private Project project = null;
private boolean newEnvironment = false;
private String[] m_command;
private String[] m_environment;
private int m_exitValue = INVALID;
private File m_workingDirectory;
private Project m_project;
private boolean m_newEnvironment;


/** /**
* Controls whether the VM is used to launch commands, where possible * Controls whether the VM is used to launch commands, where possible
*/ */
private boolean useVMLauncher = true;
private ExecuteStreamHandler streamHandler;
private ExecuteWatchdog watchdog;
private boolean m_useVMLauncher = true;
private ExecuteStreamHandler m_streamHandler;
private ExecuteWatchdog m_watchdog;


/** /**
* Builds a command launcher for the OS and JVM we are running under * Builds a command launcher for the OS and JVM we are running under
@@ -70,7 +67,7 @@ public class Execute
// Try using a JDK 1.3 launcher // Try using a JDK 1.3 launcher
try try
{ {
vmLauncher = new Java13CommandLauncher();
c_vmLauncher = new Java13CommandLauncher();
} }
catch( NoSuchMethodException exc ) catch( NoSuchMethodException exc )
{ {
@@ -80,12 +77,12 @@ public class Execute
if( Os.isFamily( "mac" ) ) if( Os.isFamily( "mac" ) )
{ {
// Mac // Mac
shellLauncher = new MacCommandLauncher( new CommandLauncher() );
c_shellLauncher = new MacCommandLauncher( new CommandLauncher() );
} }
else if( Os.isFamily( "os/2" ) ) else if( Os.isFamily( "os/2" ) )
{ {
// OS/2 - use same mechanism as Windows 2000 // OS/2 - use same mechanism as Windows 2000
shellLauncher = new WinNTCommandLauncher( new CommandLauncher() );
c_shellLauncher = new WinNTCommandLauncher( new CommandLauncher() );
} }
else if( Os.isFamily( "windows" ) ) else if( Os.isFamily( "windows" ) )
{ {
@@ -110,15 +107,15 @@ public class Execute
if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 ) if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 )
{ {
// Windows 2000/NT // Windows 2000/NT
shellLauncher = new WinNTCommandLauncher( baseLauncher );
c_shellLauncher = new WinNTCommandLauncher( baseLauncher );
} }
else else
{ {
// Windows 98/95 - need to use an auxiliary script // Windows 98/95 - need to use an auxiliary script
shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher );
c_shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher );
} }
} }
else if( ( new Os( "netware" ) ).eval() )
else if( (new Os( "netware" )).eval() )
{ {
// NetWare. Need to determine which JDK we're running in // NetWare. Need to determine which JDK we're running in
CommandLauncher baseLauncher; CommandLauncher baseLauncher;
@@ -133,12 +130,12 @@ public class Execute
baseLauncher = new CommandLauncher(); baseLauncher = new CommandLauncher();
} }


shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher );
c_shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher );
} }
else else
{ {
// Generic // Generic
shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() );
c_shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() );
} }
} }
catch( TaskException e ) catch( TaskException e )
@@ -177,8 +174,8 @@ public class Execute
*/ */
public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog ) public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog )
{ {
this.streamHandler = streamHandler;
this.watchdog = watchdog;
this.m_streamHandler = streamHandler;
this.m_watchdog = watchdog;
} }


/** /**
@@ -189,10 +186,10 @@ public class Execute
public static synchronized Vector getProcEnvironment() public static synchronized Vector getProcEnvironment()
throws TaskException throws TaskException
{ {
if( procEnvironment != null )
return procEnvironment;
if( c_procEnvironment != null )
return c_procEnvironment;


procEnvironment = new Vector();
c_procEnvironment = new Vector();
try try
{ {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -211,7 +208,7 @@ public class Execute
String var = null; String var = null;
String line; String line;
String lineSep = System.getProperty( "line.separator" ); String lineSep = System.getProperty( "line.separator" );
while( ( line = in.readLine() ) != null )
while( (line = in.readLine()) != null )
{ {
if( line.indexOf( '=' ) == -1 ) if( line.indexOf( '=' ) == -1 )
{ {
@@ -231,20 +228,20 @@ public class Execute
// New env var...append the previous one if we have it. // New env var...append the previous one if we have it.
if( var != null ) if( var != null )
{ {
procEnvironment.addElement( var );
c_procEnvironment.addElement( var );
} }
var = line; var = line;
} }
} }
// Since we "look ahead" before adding, there's one last env var. // Since we "look ahead" before adding, there's one last env var.
procEnvironment.addElement( var );
c_procEnvironment.addElement( var );
} }
catch( IOException exc ) catch( IOException exc )
{ {
exc.printStackTrace(); exc.printStackTrace();
// Just try to see how much we got // Just try to see how much we got
} }
return procEnvironment;
return c_procEnvironment;
} }


/** /**
@@ -335,7 +332,7 @@ public class Execute
public void setAntRun( Project project ) public void setAntRun( Project project )
throws TaskException throws TaskException
{ {
this.project = project;
this.m_project = project;
} }


/** /**
@@ -345,7 +342,7 @@ public class Execute
*/ */
public void setCommandline( String[] commandline ) public void setCommandline( String[] commandline )
{ {
cmdl = commandline;
m_command = commandline;
} }


/** /**
@@ -355,7 +352,7 @@ public class Execute
*/ */
public void setEnvironment( String[] env ) public void setEnvironment( String[] env )
{ {
this.env = env;
this.m_environment = env;
} }


/** /**
@@ -365,7 +362,7 @@ public class Execute
*/ */
public void setNewenvironment( boolean newenv ) public void setNewenvironment( boolean newenv )
{ {
newEnvironment = newenv;
m_newEnvironment = newenv;
} }


/** /**
@@ -378,7 +375,7 @@ public class Execute
*/ */
public void setVMLauncher( boolean useVMLauncher ) public void setVMLauncher( boolean useVMLauncher )
{ {
this.useVMLauncher = useVMLauncher;
this.m_useVMLauncher = useVMLauncher;
} }


/** /**
@@ -392,10 +389,10 @@ public class Execute
*/ */
public void setWorkingDirectory( File wd ) public void setWorkingDirectory( File wd )
{ {
if( wd == null || wd.getAbsolutePath().equals( antWorkingDirectory ) )
workingDirectory = null;
if( wd == null || wd.getAbsolutePath().equals( c_antWorkingDirectory ) )
m_workingDirectory = null;
else else
workingDirectory = wd;
m_workingDirectory = wd;
} }


/** /**
@@ -405,7 +402,7 @@ public class Execute
*/ */
public String[] getCommandline() public String[] getCommandline()
{ {
return cmdl;
return m_command;
} }


/** /**
@@ -416,8 +413,8 @@ public class Execute
public String[] getEnvironment() public String[] getEnvironment()
throws TaskException throws TaskException
{ {
if( env == null || newEnvironment )
return env;
if( m_environment == null || m_newEnvironment )
return m_environment;
return patchEnvironment(); return patchEnvironment();
} }


@@ -429,7 +426,7 @@ public class Execute
*/ */
public int getExitValue() public int getExitValue()
{ {
return exitValue;
return m_exitValue;
} }


/** /**
@@ -441,43 +438,43 @@ public class Execute
public int execute() public int execute()
throws IOException, TaskException throws IOException, TaskException
{ {
CommandLauncher launcher = vmLauncher != null ? vmLauncher : shellLauncher;
if( !useVMLauncher )
CommandLauncher launcher = c_vmLauncher != null ? c_vmLauncher : c_shellLauncher;
if( !m_useVMLauncher )
{ {
launcher = shellLauncher;
launcher = c_shellLauncher;
} }


final Process process = launcher.exec( project, getCommandline(), getEnvironment(), workingDirectory );
final Process process = launcher.exec( m_project, getCommandline(), getEnvironment(), m_workingDirectory );
try try
{ {
streamHandler.setProcessInputStream( process.getOutputStream() );
streamHandler.setProcessOutputStream( process.getInputStream() );
streamHandler.setProcessErrorStream( process.getErrorStream() );
m_streamHandler.setProcessInputStream( process.getOutputStream() );
m_streamHandler.setProcessOutputStream( process.getInputStream() );
m_streamHandler.setProcessErrorStream( process.getErrorStream() );
} }
catch( IOException e ) catch( IOException e )
{ {
process.destroy(); process.destroy();
throw e; throw e;
} }
streamHandler.start();
m_streamHandler.start();


// add the process to the list of those to destroy if the VM exits // add the process to the list of those to destroy if the VM exits
// //
processDestroyer.add( process );
c_processDestroyer.add( process );


if( watchdog != null )
watchdog.start( process );
if( m_watchdog != null )
m_watchdog.start( process );
waitFor( process ); waitFor( process );


// remove the process to the list of those to destroy if the VM exits // remove the process to the list of those to destroy if the VM exits
// //
processDestroyer.remove( process );
c_processDestroyer.remove( process );


if( watchdog != null )
watchdog.stop();
streamHandler.stop();
if( watchdog != null )
watchdog.checkException();
if( m_watchdog != null )
m_watchdog.stop();
m_streamHandler.stop();
if( m_watchdog != null )
m_watchdog.checkException();
return getExitValue(); return getExitValue();
} }


@@ -489,12 +486,12 @@ public class Execute
*/ */
public boolean killedProcess() public boolean killedProcess()
{ {
return watchdog != null && watchdog.killedProcess();
return m_watchdog != null && m_watchdog.killedProcess();
} }


protected void setExitValue( int value )
private void setExitValue( final int value )
{ {
exitValue = value;
m_exitValue = value;
} }


protected void waitFor( Process process ) protected void waitFor( Process process )
@@ -518,443 +515,25 @@ public class Execute
throws TaskException throws TaskException
{ {
Vector osEnv = (Vector)getProcEnvironment().clone(); Vector osEnv = (Vector)getProcEnvironment().clone();
for( int i = 0; i < env.length; i++ )
for( int i = 0; i < m_environment.length; i++ )
{ {
int pos = env[ i ].indexOf( '=' );
int pos = m_environment[ i ].indexOf( '=' );
// Get key including "=" // Get key including "="
String key = env[ i ].substring( 0, pos + 1 );
String key = m_environment[ i ].substring( 0, pos + 1 );
int size = osEnv.size(); int size = osEnv.size();
for( int j = 0; j < size; j++ ) for( int j = 0; j < size; j++ )
{ {
if( ( (String)osEnv.elementAt( j ) ).startsWith( key ) )
if( ((String)osEnv.elementAt( j )).startsWith( key ) )
{ {
osEnv.removeElementAt( j ); osEnv.removeElementAt( j );
break; break;
} }
} }
osEnv.addElement( env[ i ] );
osEnv.addElement( m_environment[ i ] );
} }
String[] result = new String[ osEnv.size() ]; String[] result = new String[ osEnv.size() ];
osEnv.copyInto( result ); osEnv.copyInto( result );
return result; return result;
} }


/**
* 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.
*
* @author RT
*/
private static 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" );
}
}

/**
* A command launcher that proxies another command launcher. Sub-classes
* override exec(args, env, workdir)
*
* @author RT
*/
private static 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 );
}
}

/**
* 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
*
* @author RT
*/
private static 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 );
}
}

/**
* A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in
* Runtime.exec() command
*
* @author RT
*/
private static 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 );
}
}
}

/**
* A command launcher for Mac that uses a dodgy mechanism to change working
* directory before launching commands.
*
* @author RT
*/
private static 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", antWorkingDirectory );
}
}
}

/**
* A command launcher that uses an auxiliary perl script to launch commands
* in directories other than the current working directory.
*
* @author RT
*/
private static 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 );
}
}

/**
* A command launcher that uses an auxiliary script to launch commands in
* directories other than the current working directory.
*
* @author RT
*/
private static 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 );
}
}

/**
* A command launcher for Windows 2000/NT that uses 'cmd.exe' when launching
* commands in directories other than the current working directory.
*
* @author RT
*/
private static 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 );
}
}
} }

+ 68
- 489
proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/exec/Execute.java View File

@@ -12,11 +12,8 @@ import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale; import java.util.Locale;
import java.util.Vector; import java.util.Vector;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.api.TaskException; import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.Os; import org.apache.myrmidon.framework.Os;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
@@ -35,29 +32,29 @@ public class Execute
*/ */
public final static int INVALID = Integer.MAX_VALUE; public final static int INVALID = Integer.MAX_VALUE;


private static String antWorkingDirectory = System.getProperty( "user.dir" );
private static CommandLauncher vmLauncher;
private static CommandLauncher shellLauncher;
private static Vector procEnvironment;
private static String c_antWorkingDirectory = System.getProperty( "user.dir" );
private static CommandLauncher c_vmLauncher;
private static CommandLauncher c_shellLauncher;
private static Vector c_procEnvironment;


/** /**
* Used to destroy processes when the VM exits. * Used to destroy processes when the VM exits.
*/ */
private static ProcessDestroyer processDestroyer = new ProcessDestroyer();
private static ProcessDestroyer c_processDestroyer = new ProcessDestroyer();


private String[] cmdl = null;
private String[] env = null;
private int exitValue = INVALID;
private File workingDirectory = null;
private Project project = null;
private boolean newEnvironment = false;
private String[] m_command;
private String[] m_environment;
private int m_exitValue = INVALID;
private File m_workingDirectory;
private Project m_project;
private boolean m_newEnvironment;


/** /**
* Controls whether the VM is used to launch commands, where possible * Controls whether the VM is used to launch commands, where possible
*/ */
private boolean useVMLauncher = true;
private ExecuteStreamHandler streamHandler;
private ExecuteWatchdog watchdog;
private boolean m_useVMLauncher = true;
private ExecuteStreamHandler m_streamHandler;
private ExecuteWatchdog m_watchdog;


/** /**
* Builds a command launcher for the OS and JVM we are running under * Builds a command launcher for the OS and JVM we are running under
@@ -70,7 +67,7 @@ public class Execute
// Try using a JDK 1.3 launcher // Try using a JDK 1.3 launcher
try try
{ {
vmLauncher = new Java13CommandLauncher();
c_vmLauncher = new Java13CommandLauncher();
} }
catch( NoSuchMethodException exc ) catch( NoSuchMethodException exc )
{ {
@@ -80,12 +77,12 @@ public class Execute
if( Os.isFamily( "mac" ) ) if( Os.isFamily( "mac" ) )
{ {
// Mac // Mac
shellLauncher = new MacCommandLauncher( new CommandLauncher() );
c_shellLauncher = new MacCommandLauncher( new CommandLauncher() );
} }
else if( Os.isFamily( "os/2" ) ) else if( Os.isFamily( "os/2" ) )
{ {
// OS/2 - use same mechanism as Windows 2000 // OS/2 - use same mechanism as Windows 2000
shellLauncher = new WinNTCommandLauncher( new CommandLauncher() );
c_shellLauncher = new WinNTCommandLauncher( new CommandLauncher() );
} }
else if( Os.isFamily( "windows" ) ) else if( Os.isFamily( "windows" ) )
{ {
@@ -110,15 +107,15 @@ public class Execute
if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 ) if( osname.indexOf( "nt" ) >= 0 || osname.indexOf( "2000" ) >= 0 )
{ {
// Windows 2000/NT // Windows 2000/NT
shellLauncher = new WinNTCommandLauncher( baseLauncher );
c_shellLauncher = new WinNTCommandLauncher( baseLauncher );
} }
else else
{ {
// Windows 98/95 - need to use an auxiliary script // Windows 98/95 - need to use an auxiliary script
shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher );
c_shellLauncher = new ScriptCommandLauncher( "bin/antRun.bat", baseLauncher );
} }
} }
else if( ( new Os( "netware" ) ).eval() )
else if( (new Os( "netware" )).eval() )
{ {
// NetWare. Need to determine which JDK we're running in // NetWare. Need to determine which JDK we're running in
CommandLauncher baseLauncher; CommandLauncher baseLauncher;
@@ -133,12 +130,12 @@ public class Execute
baseLauncher = new CommandLauncher(); baseLauncher = new CommandLauncher();
} }


shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher );
c_shellLauncher = new PerlScriptCommandLauncher( "bin/antRun.pl", baseLauncher );
} }
else else
{ {
// Generic // Generic
shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() );
c_shellLauncher = new ScriptCommandLauncher( "bin/antRun", new CommandLauncher() );
} }
} }
catch( TaskException e ) catch( TaskException e )
@@ -177,8 +174,8 @@ public class Execute
*/ */
public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog ) public Execute( ExecuteStreamHandler streamHandler, ExecuteWatchdog watchdog )
{ {
this.streamHandler = streamHandler;
this.watchdog = watchdog;
this.m_streamHandler = streamHandler;
this.m_watchdog = watchdog;
} }


/** /**
@@ -189,10 +186,10 @@ public class Execute
public static synchronized Vector getProcEnvironment() public static synchronized Vector getProcEnvironment()
throws TaskException throws TaskException
{ {
if( procEnvironment != null )
return procEnvironment;
if( c_procEnvironment != null )
return c_procEnvironment;


procEnvironment = new Vector();
c_procEnvironment = new Vector();
try try
{ {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -211,7 +208,7 @@ public class Execute
String var = null; String var = null;
String line; String line;
String lineSep = System.getProperty( "line.separator" ); String lineSep = System.getProperty( "line.separator" );
while( ( line = in.readLine() ) != null )
while( (line = in.readLine()) != null )
{ {
if( line.indexOf( '=' ) == -1 ) if( line.indexOf( '=' ) == -1 )
{ {
@@ -231,20 +228,20 @@ public class Execute
// New env var...append the previous one if we have it. // New env var...append the previous one if we have it.
if( var != null ) if( var != null )
{ {
procEnvironment.addElement( var );
c_procEnvironment.addElement( var );
} }
var = line; var = line;
} }
} }
// Since we "look ahead" before adding, there's one last env var. // Since we "look ahead" before adding, there's one last env var.
procEnvironment.addElement( var );
c_procEnvironment.addElement( var );
} }
catch( IOException exc ) catch( IOException exc )
{ {
exc.printStackTrace(); exc.printStackTrace();
// Just try to see how much we got // Just try to see how much we got
} }
return procEnvironment;
return c_procEnvironment;
} }


/** /**
@@ -335,7 +332,7 @@ public class Execute
public void setAntRun( Project project ) public void setAntRun( Project project )
throws TaskException throws TaskException
{ {
this.project = project;
this.m_project = project;
} }


/** /**
@@ -345,7 +342,7 @@ public class Execute
*/ */
public void setCommandline( String[] commandline ) public void setCommandline( String[] commandline )
{ {
cmdl = commandline;
m_command = commandline;
} }


/** /**
@@ -355,7 +352,7 @@ public class Execute
*/ */
public void setEnvironment( String[] env ) public void setEnvironment( String[] env )
{ {
this.env = env;
this.m_environment = env;
} }


/** /**
@@ -365,7 +362,7 @@ public class Execute
*/ */
public void setNewenvironment( boolean newenv ) public void setNewenvironment( boolean newenv )
{ {
newEnvironment = newenv;
m_newEnvironment = newenv;
} }


/** /**
@@ -378,7 +375,7 @@ public class Execute
*/ */
public void setVMLauncher( boolean useVMLauncher ) public void setVMLauncher( boolean useVMLauncher )
{ {
this.useVMLauncher = useVMLauncher;
this.m_useVMLauncher = useVMLauncher;
} }


/** /**
@@ -392,10 +389,10 @@ public class Execute
*/ */
public void setWorkingDirectory( File wd ) public void setWorkingDirectory( File wd )
{ {
if( wd == null || wd.getAbsolutePath().equals( antWorkingDirectory ) )
workingDirectory = null;
if( wd == null || wd.getAbsolutePath().equals( c_antWorkingDirectory ) )
m_workingDirectory = null;
else else
workingDirectory = wd;
m_workingDirectory = wd;
} }


/** /**
@@ -405,7 +402,7 @@ public class Execute
*/ */
public String[] getCommandline() public String[] getCommandline()
{ {
return cmdl;
return m_command;
} }


/** /**
@@ -416,8 +413,8 @@ public class Execute
public String[] getEnvironment() public String[] getEnvironment()
throws TaskException throws TaskException
{ {
if( env == null || newEnvironment )
return env;
if( m_environment == null || m_newEnvironment )
return m_environment;
return patchEnvironment(); return patchEnvironment();
} }


@@ -429,7 +426,7 @@ public class Execute
*/ */
public int getExitValue() public int getExitValue()
{ {
return exitValue;
return m_exitValue;
} }


/** /**
@@ -441,43 +438,43 @@ public class Execute
public int execute() public int execute()
throws IOException, TaskException throws IOException, TaskException
{ {
CommandLauncher launcher = vmLauncher != null ? vmLauncher : shellLauncher;
if( !useVMLauncher )
CommandLauncher launcher = c_vmLauncher != null ? c_vmLauncher : c_shellLauncher;
if( !m_useVMLauncher )
{ {
launcher = shellLauncher;
launcher = c_shellLauncher;
} }


final Process process = launcher.exec( project, getCommandline(), getEnvironment(), workingDirectory );
final Process process = launcher.exec( m_project, getCommandline(), getEnvironment(), m_workingDirectory );
try try
{ {
streamHandler.setProcessInputStream( process.getOutputStream() );
streamHandler.setProcessOutputStream( process.getInputStream() );
streamHandler.setProcessErrorStream( process.getErrorStream() );
m_streamHandler.setProcessInputStream( process.getOutputStream() );
m_streamHandler.setProcessOutputStream( process.getInputStream() );
m_streamHandler.setProcessErrorStream( process.getErrorStream() );
} }
catch( IOException e ) catch( IOException e )
{ {
process.destroy(); process.destroy();
throw e; throw e;
} }
streamHandler.start();
m_streamHandler.start();


// add the process to the list of those to destroy if the VM exits // add the process to the list of those to destroy if the VM exits
// //
processDestroyer.add( process );
c_processDestroyer.add( process );


if( watchdog != null )
watchdog.start( process );
if( m_watchdog != null )
m_watchdog.start( process );
waitFor( process ); waitFor( process );


// remove the process to the list of those to destroy if the VM exits // remove the process to the list of those to destroy if the VM exits
// //
processDestroyer.remove( process );
c_processDestroyer.remove( process );


if( watchdog != null )
watchdog.stop();
streamHandler.stop();
if( watchdog != null )
watchdog.checkException();
if( m_watchdog != null )
m_watchdog.stop();
m_streamHandler.stop();
if( m_watchdog != null )
m_watchdog.checkException();
return getExitValue(); return getExitValue();
} }


@@ -489,12 +486,12 @@ public class Execute
*/ */
public boolean killedProcess() public boolean killedProcess()
{ {
return watchdog != null && watchdog.killedProcess();
return m_watchdog != null && m_watchdog.killedProcess();
} }


protected void setExitValue( int value )
private void setExitValue( final int value )
{ {
exitValue = value;
m_exitValue = value;
} }


protected void waitFor( Process process ) protected void waitFor( Process process )
@@ -518,443 +515,25 @@ public class Execute
throws TaskException throws TaskException
{ {
Vector osEnv = (Vector)getProcEnvironment().clone(); Vector osEnv = (Vector)getProcEnvironment().clone();
for( int i = 0; i < env.length; i++ )
for( int i = 0; i < m_environment.length; i++ )
{ {
int pos = env[ i ].indexOf( '=' );
int pos = m_environment[ i ].indexOf( '=' );
// Get key including "=" // Get key including "="
String key = env[ i ].substring( 0, pos + 1 );
String key = m_environment[ i ].substring( 0, pos + 1 );
int size = osEnv.size(); int size = osEnv.size();
for( int j = 0; j < size; j++ ) for( int j = 0; j < size; j++ )
{ {
if( ( (String)osEnv.elementAt( j ) ).startsWith( key ) )
if( ((String)osEnv.elementAt( j )).startsWith( key ) )
{ {
osEnv.removeElementAt( j ); osEnv.removeElementAt( j );
break; break;
} }
} }
osEnv.addElement( env[ i ] );
osEnv.addElement( m_environment[ i ] );
} }
String[] result = new String[ osEnv.size() ]; String[] result = new String[ osEnv.size() ];
osEnv.copyInto( result ); osEnv.copyInto( result );
return result; return result;
} }


/**
* 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.
*
* @author RT
*/
private static 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" );
}
}

/**
* A command launcher that proxies another command launcher. Sub-classes
* override exec(args, env, workdir)
*
* @author RT
*/
private static 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 );
}
}

/**
* 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
*
* @author RT
*/
private static 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 );
}
}

/**
* A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in
* Runtime.exec() command
*
* @author RT
*/
private static 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 );
}
}
}

/**
* A command launcher for Mac that uses a dodgy mechanism to change working
* directory before launching commands.
*
* @author RT
*/
private static 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", antWorkingDirectory );
}
}
}

/**
* A command launcher that uses an auxiliary perl script to launch commands
* in directories other than the current working directory.
*
* @author RT
*/
private static 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 );
}
}

/**
* A command launcher that uses an auxiliary script to launch commands in
* directories other than the current working directory.
*
* @author RT
*/
private static 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 );
}
}

/**
* A command launcher for Windows 2000/NT that uses 'cmd.exe' when launching
* commands in directories other than the current working directory.
*
* @author RT
*/
private static 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 );
}
}
} }

Loading…
Cancel
Save