diff --git a/proposal/myrmidon/src/java/org/apache/antlib/nativelib/Exec.java b/proposal/myrmidon/src/java/org/apache/antlib/nativelib/Exec.java new file mode 100644 index 000000000..30a144eb5 --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/antlib/nativelib/Exec.java @@ -0,0 +1,190 @@ +/* + * 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.antlib.nativelib; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; +import org.apache.avalon.excalibur.i18n.ResourceManager; +import org.apache.avalon.excalibur.i18n.Resources; +import org.apache.myrmidon.api.AbstractTask; +import org.apache.myrmidon.api.TaskException; +import org.apache.aut.nativelib.Os; +import org.apache.tools.ant.taskdefs.exec.Execute2; +import org.apache.tools.ant.types.Argument; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.EnvironmentData; +import org.apache.tools.ant.types.EnvironmentVariable; + +/** + * Executes a native command. + * + * @author JDD + * @author Sam Ruby + * @author Peter Donald + * @author Stefan Bodewig + * @author Mariusz Nowostawski + * @author Thomas Haas + */ +public class Exec + extends AbstractTask +{ + private static final Resources REZ = + ResourceManager.getPackageResources( Exec.class ); + + private long m_timeout; + private EnvironmentData m_env = new EnvironmentData(); + private Commandline m_command = new Commandline(); + private boolean m_newEnvironment; + private File m_dir; + private String m_os; + + /** + * The working directory of the process + */ + public void setDir( final File dir ) + throws TaskException + { + m_dir = dir; + } + + /** + * The command to execute. + */ + public void setExecutable( final String value ) + throws TaskException + { + m_command.setExecutable( value ); + } + + /** + * Use a completely new environment + */ + public void setNewenvironment( final boolean newEnvironment ) + { + m_newEnvironment = newEnvironment; + } + + /** + * Only execute the process if os.name is included in this + * string. + */ + public void setOs( final String os ) + { + m_os = os; + } + + /** + * Timeout in milliseconds after which the process will be killed. + */ + public void setTimeout( final long timeout ) + { + m_timeout = timeout; + } + + /** + * Add a nested env element - an environment variable. + */ + public void addEnv( final EnvironmentVariable var ) + { + m_env.addVariable( var ); + } + + /** + * Add a nested arg element - a command line argument. + */ + public Argument createArg() + { + return m_command.createArgument(); + } + + public void execute() + throws TaskException + { + validate(); + if( Os.isFamily( m_os ) ) + { + final Execute2 exe = createExecute(); + doExecute( exe ); + } + } + + private void doExecute( final Execute2 exe ) + throws TaskException + { + try + { + final int err = exe.execute(); + if( 0 != err ) + { + final String message = + REZ.getString( "exec.bad-resultcode.error", new Integer( err ) ); + throw new TaskException( message ); + } + } + catch( final IOException ioe ) + { + final String message = REZ.getString( "exec.failed.error", ioe ); + throw new TaskException( message, ioe ); + } + } + + private void validate() + throws TaskException + { + if( null == m_command.getExecutable() ) + { + final String message = REZ.getString( "exec.no-executable.error" ); + throw new TaskException( message ); + } + + // default directory to the project's base directory + if( m_dir == null ) + { + m_dir = getBaseDirectory(); + } + else + { + if( !m_dir.exists() ) + { + final String message = REZ.getString( "exec.dir-noexist.error", m_dir ); + throw new TaskException( message ); + } + else if( !m_dir.isDirectory() ) + { + final String message = REZ.getString( "exec.dir-notdir.error", m_dir ); + throw new TaskException( message ); + } + } + } + + private Execute2 createExecute() + throws TaskException + { + final Properties environment = m_env.getVariables(); + + logExecDetails( environment ); + + final Execute2 exe = new Execute2(); + setupLogger( exe ); + exe.setTimeout( m_timeout ); + exe.setWorkingDirectory( m_dir ); + exe.setNewenvironment( m_newEnvironment ); + exe.setEnvironment( environment ); + exe.setCommandline( m_command.getCommandline() ); + return exe; + } + + private void logExecDetails( final Properties environment ) + { + // show the command + getLogger().debug( m_command.toString() ); + final String message = REZ.getString( "exec.env-vars.notice", environment ); + getLogger().debug( message ); + } +} diff --git a/proposal/myrmidon/src/java/org/apache/antlib/nativelib/Resources.properties b/proposal/myrmidon/src/java/org/apache/antlib/nativelib/Resources.properties index 86749caaa..b713f3f2e 100644 --- a/proposal/myrmidon/src/java/org/apache/antlib/nativelib/Resources.properties +++ b/proposal/myrmidon/src/java/org/apache/antlib/nativelib/Resources.properties @@ -1,3 +1,11 @@ loadenv.no-prefix.error=No prefix specified for environment data. loadenv.prefix.notice=Loading Environment with prefix {0}. loadenv.ignoring-empty.warn=Key {0} in native OS environment is empty - ignoring key. + +exec.failed.error=Execute failed. (Reason: {0}). +exec.bad-resultcode.error=Bad result code {0}. +exec.no-executable.error=No executable specified. +exec.dir-noexist.error=The directory you specified ({0}) does not exist. +exec.dir-notdir.error=The directory you specified is not a directory. +exec.env-vars.notice=Setting environment variables: {0}. +exec.invalid-os.notice=This OS, {0} was not found in the specified list of valid OSes: {1}.