git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271341 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1,414 +0,0 @@ | |||||
| /* | |||||
| * 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.io.BufferedReader; | |||||
| import java.io.ByteArrayOutputStream; | |||||
| import java.io.File; | |||||
| import java.io.FileNotFoundException; | |||||
| import java.io.FileOutputStream; | |||||
| import java.io.IOException; | |||||
| import java.io.StringReader; | |||||
| import java.util.Iterator; | |||||
| import java.util.Properties; | |||||
| import org.apache.avalon.excalibur.util.StringUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.tools.ant.Task; | |||||
| 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 given command if the os platform is appropriate. | |||||
| * | |||||
| * @author duncan@x180.com | |||||
| * @author rubys@us.ibm.com | |||||
| * @author thomas.haas@softwired-inc.com | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @author <a href="mailto:mariusz@rakiura.org">Mariusz Nowostawski</a> | |||||
| */ | |||||
| public class ExecTask | |||||
| extends Task | |||||
| { | |||||
| private boolean m_newEnvironment; | |||||
| private Integer m_timeout; | |||||
| private EnvironmentData m_env = new EnvironmentData(); | |||||
| private Commandline m_command = new Commandline(); | |||||
| private FileOutputStream m_ouput; | |||||
| private ByteArrayOutputStream m_byteArrayOutput; | |||||
| /** | |||||
| * Controls whether the VM (1.3 and above) is used to execute the command | |||||
| */ | |||||
| private boolean m_useVMLauncher = true; | |||||
| private File m_workingDirectory; | |||||
| private String m_os; | |||||
| private File m_outputFile; | |||||
| private String m_outputProperty; | |||||
| private String m_resultProperty; | |||||
| /** | |||||
| * The working directory of the process | |||||
| * | |||||
| * @param d The new Dir value | |||||
| */ | |||||
| public void setDir( final File dir ) | |||||
| throws TaskException | |||||
| { | |||||
| m_workingDirectory = 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 <code>os.name</code> is included in this | |||||
| * string. | |||||
| * | |||||
| * @param os The new Os value | |||||
| */ | |||||
| public void setOs( final String os ) | |||||
| { | |||||
| m_os = os; | |||||
| } | |||||
| /** | |||||
| * File the output of the process is redirected to. | |||||
| * | |||||
| * @param out The new Output value | |||||
| */ | |||||
| public void setOutput( final File outputFile ) | |||||
| { | |||||
| m_outputFile = outputFile; | |||||
| } | |||||
| /** | |||||
| * Property name whose value should be set to the output of the process | |||||
| * | |||||
| * @param outputprop The new Outputproperty value | |||||
| */ | |||||
| public void setOutputproperty( final String outputprop ) | |||||
| { | |||||
| m_outputProperty = outputprop; | |||||
| } | |||||
| /** | |||||
| * fill a property in with a result. when no property is defined: failure to | |||||
| * execute | |||||
| * | |||||
| * @param resultProperty The new ResultProperty value | |||||
| * @since 1.5 | |||||
| */ | |||||
| public void setResultProperty( final String resultProperty ) | |||||
| { | |||||
| m_resultProperty = resultProperty; | |||||
| } | |||||
| /** | |||||
| * Timeout in milliseconds after which the process will be killed. | |||||
| * | |||||
| * @param value The new Timeout value | |||||
| */ | |||||
| public void setTimeout( final Integer timeout ) | |||||
| { | |||||
| m_timeout = timeout; | |||||
| } | |||||
| /** | |||||
| * Control whether the VM is used to launch the new process or whether the | |||||
| * OS's shell is used. | |||||
| * | |||||
| * @param vmLauncher The new VMLauncher value | |||||
| */ | |||||
| public void setVMLauncher( final boolean vmLauncher ) | |||||
| { | |||||
| m_useVMLauncher = vmLauncher; | |||||
| } | |||||
| /** | |||||
| * Add a nested env element - an environment variable. | |||||
| * | |||||
| * @param var The feature to be added to the Env attribute | |||||
| */ | |||||
| public void addEnv( final EnvironmentVariable var ) | |||||
| { | |||||
| m_env.addVariable( var ); | |||||
| } | |||||
| /** | |||||
| * Add a nested arg element - a command line argument. | |||||
| */ | |||||
| public void addArg( final Argument argument ) | |||||
| { | |||||
| m_command.addArgument( argument ); | |||||
| } | |||||
| /** | |||||
| * Do the work. | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| validate(); | |||||
| if( isValidOs() ) | |||||
| { | |||||
| runExec( prepareExec() ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Is this the OS the user wanted? | |||||
| * | |||||
| * @return The ValidOs value | |||||
| */ | |||||
| protected boolean isValidOs() | |||||
| { | |||||
| // test if os match | |||||
| final String os = System.getProperty( "os.name" ); | |||||
| getLogger().debug( "Current OS is " + os ); | |||||
| if( ( m_os != null ) && ( m_os.indexOf( os ) < 0 ) ) | |||||
| { | |||||
| // this command will be executed only on the specified OS | |||||
| getLogger().debug( "This OS, " + os + " was not found in the specified list of valid OSes: " + m_os ); | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /** | |||||
| * A Utility method for this classes and subclasses to run an Execute | |||||
| * instance (an external command). | |||||
| * | |||||
| * @param exe Description of Parameter | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| protected final void runExecute( final Execute exe ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| final int err = exe.execute(); | |||||
| //test for and handle a forced process death | |||||
| maybeSetResultPropertyValue( err ); | |||||
| if( 0 != err ) | |||||
| { | |||||
| throw new TaskException( getContext().getName() + " returned: " + err ); | |||||
| } | |||||
| if( null != m_byteArrayOutput ) | |||||
| { | |||||
| writeResultToProperty(); | |||||
| } | |||||
| } | |||||
| private void writeResultToProperty() throws IOException, TaskException | |||||
| { | |||||
| final BufferedReader input = | |||||
| new BufferedReader( new StringReader( m_byteArrayOutput.toString() ) ); | |||||
| String line = null; | |||||
| StringBuffer val = new StringBuffer(); | |||||
| while( ( line = input.readLine() ) != null ) | |||||
| { | |||||
| if( val.length() != 0 ) | |||||
| { | |||||
| val.append( StringUtil.LINE_SEPARATOR ); | |||||
| } | |||||
| val.append( line ); | |||||
| } | |||||
| final String name = m_outputProperty; | |||||
| final Object value = val.toString(); | |||||
| getContext().setProperty( name, value ); | |||||
| } | |||||
| /** | |||||
| * Has the user set all necessary attributes? | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| protected void validate() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_command.getExecutable() == null ) | |||||
| { | |||||
| throw new TaskException( "no executable specified" ); | |||||
| } | |||||
| if( m_workingDirectory != null && !m_workingDirectory.exists() ) | |||||
| { | |||||
| throw new TaskException( "The directory you specified does not exist" ); | |||||
| } | |||||
| if( m_workingDirectory != null && !m_workingDirectory.isDirectory() ) | |||||
| { | |||||
| throw new TaskException( "The directory you specified is not a directory" ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Create the StreamHandler to use with our Execute instance. | |||||
| * | |||||
| * @return Description of the Returned Value | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| private void setupOutput( final Execute exe ) | |||||
| throws TaskException | |||||
| { | |||||
| if( m_outputFile != null ) | |||||
| { | |||||
| try | |||||
| { | |||||
| m_ouput = new FileOutputStream( m_outputFile ); | |||||
| getLogger().debug( "Output redirected to " + m_outputFile ); | |||||
| exe.setOutput( m_ouput ); | |||||
| exe.setError( m_ouput ); | |||||
| } | |||||
| catch( FileNotFoundException fne ) | |||||
| { | |||||
| throw new TaskException( "Cannot write to " + m_outputFile, fne ); | |||||
| } | |||||
| catch( IOException ioe ) | |||||
| { | |||||
| throw new TaskException( "Cannot write to " + m_outputFile, ioe ); | |||||
| } | |||||
| } | |||||
| else if( m_outputProperty != null ) | |||||
| { | |||||
| m_byteArrayOutput = new ByteArrayOutputStream(); | |||||
| getLogger().debug( "Output redirected to ByteArray" ); | |||||
| exe.setOutput( m_byteArrayOutput ); | |||||
| exe.setError( m_byteArrayOutput ); | |||||
| } | |||||
| else | |||||
| { | |||||
| exe.setOutput( new LogOutputStream( getLogger(), false ) ); | |||||
| exe.setError( new LogOutputStream( getLogger(), true ) ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Flush the output stream - if there is one. | |||||
| */ | |||||
| protected void logFlush() | |||||
| { | |||||
| try | |||||
| { | |||||
| if( m_ouput != null ) | |||||
| { | |||||
| m_ouput.close(); | |||||
| } | |||||
| if( m_byteArrayOutput != null ) | |||||
| { | |||||
| m_byteArrayOutput.close(); | |||||
| } | |||||
| } | |||||
| catch( IOException io ) | |||||
| { | |||||
| } | |||||
| } | |||||
| /** | |||||
| * helper method to set result property to the passed in value if | |||||
| * appropriate | |||||
| */ | |||||
| protected void maybeSetResultPropertyValue( int result ) | |||||
| throws TaskException | |||||
| { | |||||
| final String res = Integer.toString( result ); | |||||
| if( m_resultProperty != null ) | |||||
| { | |||||
| final String name = m_resultProperty; | |||||
| getContext().setProperty( name, res ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Create an Execute instance with the correct working directory set. | |||||
| */ | |||||
| protected Execute prepareExec() | |||||
| throws TaskException | |||||
| { | |||||
| // default directory to the project's base directory | |||||
| if( m_workingDirectory == null ) | |||||
| { | |||||
| m_workingDirectory = getBaseDirectory(); | |||||
| } | |||||
| // show the command | |||||
| getLogger().debug( m_command.toString() ); | |||||
| final Execute exe = new Execute(); | |||||
| setupOutput( exe ); | |||||
| if( null != m_timeout ) | |||||
| { | |||||
| exe.setTimeout( m_timeout.intValue() ); | |||||
| } | |||||
| exe.setWorkingDirectory( m_workingDirectory ); | |||||
| exe.setVMLauncher( m_useVMLauncher ); | |||||
| exe.setNewenvironment( m_newEnvironment ); | |||||
| final Properties environment = m_env.getVariables(); | |||||
| final Iterator keys = environment.keySet().iterator(); | |||||
| while( keys.hasNext() ) | |||||
| { | |||||
| final String key = (String)keys.next(); | |||||
| final String value = environment.getProperty( key ); | |||||
| getLogger().debug( "Setting environment variable: " + key + "=" + value ); | |||||
| } | |||||
| exe.setEnvironment( environment ); | |||||
| return exe; | |||||
| } | |||||
| /** | |||||
| * Run the command using the given Execute instance. This may be overidden | |||||
| * by subclasses | |||||
| * | |||||
| * @param exe Description of Parameter | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| protected void runExec( final Execute exe ) | |||||
| throws TaskException | |||||
| { | |||||
| exe.setCommandline( m_command.getCommandline() ); | |||||
| try | |||||
| { | |||||
| runExecute( exe ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Execute failed: " + e.toString(), e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| // close the output file if required | |||||
| logFlush(); | |||||
| } | |||||
| } | |||||
| protected final Commandline getCommand() | |||||
| { | |||||
| return m_command; | |||||
| } | |||||
| } | |||||
| @@ -1,142 +0,0 @@ | |||||
| /* | |||||
| * 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.io.File; | |||||
| import java.io.IOException; | |||||
| import java.io.OutputStream; | |||||
| import java.util.Properties; | |||||
| import org.apache.aut.nativelib.ExecException; | |||||
| import org.apache.aut.nativelib.ExecManager; | |||||
| import org.apache.aut.nativelib.ExecMetaData; | |||||
| import org.apache.avalon.excalibur.io.IOUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.myrmidon.framework.factorys.ExecManagerFactory; | |||||
| import org.apache.myrmidon.interfaces.service.ServiceException; | |||||
| /** | |||||
| * Runs an external program. | |||||
| * | |||||
| * @author thomas.haas@softwired-inc.com | |||||
| */ | |||||
| public class Execute | |||||
| { | |||||
| private String[] m_command; | |||||
| private Properties m_environment = new Properties(); | |||||
| private File m_workingDirectory = new File( "." ); | |||||
| private boolean m_newEnvironment; | |||||
| private OutputStream m_output; | |||||
| private OutputStream m_error; | |||||
| private long m_timeout; | |||||
| /** | |||||
| * Controls whether the VM is used to launch commands, where possible | |||||
| */ | |||||
| private boolean m_useVMLauncher = true; | |||||
| public void setTimeout( final long timeout ) | |||||
| { | |||||
| m_timeout = timeout; | |||||
| } | |||||
| public void setOutput( final OutputStream output ) | |||||
| { | |||||
| m_output = output; | |||||
| } | |||||
| public void setError( final OutputStream error ) | |||||
| { | |||||
| m_error = error; | |||||
| } | |||||
| /** | |||||
| * Sets the commandline of the subprocess to launch. | |||||
| * | |||||
| * @param commandline the commandline of the subprocess to launch | |||||
| */ | |||||
| public void setCommandline( String[] commandline ) | |||||
| { | |||||
| m_command = commandline; | |||||
| } | |||||
| public void setEnvironment( final Properties environment ) | |||||
| { | |||||
| if( null == environment ) | |||||
| { | |||||
| throw new NullPointerException( "environment" ); | |||||
| } | |||||
| m_environment = environment; | |||||
| } | |||||
| /** | |||||
| * Set whether to propagate the default environment or not. | |||||
| * | |||||
| * @param newenv whether to propagate the process environment. | |||||
| */ | |||||
| public void setNewenvironment( boolean newEnvironment ) | |||||
| { | |||||
| m_newEnvironment = newEnvironment; | |||||
| } | |||||
| /** | |||||
| * Launch this execution through the VM, where possible, rather than through | |||||
| * the OS's shell. In some cases and operating systems using the shell will | |||||
| * allow the shell to perform additional processing such as associating an | |||||
| * executable with a script, etc | |||||
| * | |||||
| * @param useVMLauncher The new VMLauncher value | |||||
| */ | |||||
| public void setVMLauncher( boolean useVMLauncher ) | |||||
| { | |||||
| m_useVMLauncher = useVMLauncher; | |||||
| } | |||||
| /** | |||||
| * Sets the working directory of the process to execute. <p> | |||||
| * | |||||
| * @param workingDirectory the working directory of the process. | |||||
| */ | |||||
| public void setWorkingDirectory( final File workingDirectory ) | |||||
| { | |||||
| m_workingDirectory = workingDirectory; | |||||
| } | |||||
| /** | |||||
| * Runs a process defined by the command line and returns its exit status. | |||||
| * | |||||
| * @return the exit status of the subprocess or <code>INVALID</code> | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public int execute() | |||||
| throws IOException, TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| final ExecManagerFactory factory = new ExecManagerFactory(); | |||||
| final ExecManager manager = (ExecManager)factory.createService(); | |||||
| final ExecMetaData metaData = | |||||
| new ExecMetaData( m_command, m_environment, | |||||
| m_workingDirectory, m_newEnvironment ); | |||||
| return manager.execute( metaData, null, m_output, m_error, m_timeout ); | |||||
| } | |||||
| catch( final ExecException ee ) | |||||
| { | |||||
| throw new TaskException( ee.getMessage(), ee ); | |||||
| } | |||||
| catch( final ServiceException se ) | |||||
| { | |||||
| throw new TaskException( se.getMessage(), se ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| IOUtil.shutdownStream( m_output ); | |||||
| IOUtil.shutdownStream( m_error ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,440 +0,0 @@ | |||||
| /* | |||||
| * 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.io.File; | |||||
| import java.io.IOException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Hashtable; | |||||
| import org.apache.avalon.excalibur.util.StringUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.tools.ant.types.DirectoryScanner; | |||||
| import org.apache.tools.ant.types.FileSet; | |||||
| import org.apache.tools.ant.types.Marker; | |||||
| import org.apache.tools.ant.types.ScannerUtil; | |||||
| import org.apache.tools.ant.types.SourceFileScanner; | |||||
| import org.apache.tools.ant.util.mappers.FileNameMapper; | |||||
| import org.apache.tools.ant.util.mappers.Mapper; | |||||
| /** | |||||
| * Executes a given command, supplying a set of files as arguments. | |||||
| * | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @author <a href="mailto:mariusz@rakiura.org">Mariusz Nowostawski</a> | |||||
| */ | |||||
| public class ExecuteOn | |||||
| extends ExecTask | |||||
| { | |||||
| private ArrayList m_filesets = new ArrayList(); | |||||
| private boolean m_relative; | |||||
| private boolean m_parallel; | |||||
| private String m_type = "file"; | |||||
| private Marker m_srcFilePos; | |||||
| private boolean m_skipEmpty; | |||||
| private Marker m_targetFilePos; | |||||
| private Mapper m_mapperElement; | |||||
| private FileNameMapper m_mapper; | |||||
| private File m_destDir; | |||||
| /** | |||||
| * Has <srcfile> been specified before <targetfile> | |||||
| */ | |||||
| private boolean m_srcIsFirst = true; | |||||
| /** | |||||
| * Set the destination directory. | |||||
| */ | |||||
| public void setDest( final File destDir ) | |||||
| { | |||||
| m_destDir = destDir; | |||||
| } | |||||
| /** | |||||
| * Shall the command work on all specified files in parallel? | |||||
| */ | |||||
| public void setParallel( final boolean parallel ) | |||||
| { | |||||
| m_parallel = parallel; | |||||
| } | |||||
| /** | |||||
| * Should filenames be returned as relative path names? | |||||
| */ | |||||
| public void setRelative( final boolean relative ) | |||||
| { | |||||
| m_relative = relative; | |||||
| } | |||||
| /** | |||||
| * Should empty filesets be ignored? | |||||
| */ | |||||
| public void setSkipEmptyFilesets( final boolean skip ) | |||||
| { | |||||
| m_skipEmpty = skip; | |||||
| } | |||||
| /** | |||||
| * Shall the command work only on files, directories or both? | |||||
| */ | |||||
| public void setType( final FileDirBoth type ) | |||||
| { | |||||
| m_type = type.getValue(); | |||||
| } | |||||
| /** | |||||
| * Adds a set of files (nested fileset attribute). | |||||
| */ | |||||
| public void addFileset( final FileSet set ) | |||||
| { | |||||
| m_filesets.add( set ); | |||||
| } | |||||
| /** | |||||
| * Defines the FileNameMapper to use (nested mapper element). | |||||
| */ | |||||
| public Mapper createMapper() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_mapperElement != null ) | |||||
| { | |||||
| throw new TaskException( "Cannot define more than one mapper" ); | |||||
| } | |||||
| m_mapperElement = new Mapper(); | |||||
| return m_mapperElement; | |||||
| } | |||||
| /** | |||||
| * Marker that indicates where the name of the source file should be put on | |||||
| * the command line. | |||||
| */ | |||||
| public Marker createSrcfile() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_srcFilePos != null ) | |||||
| { | |||||
| throw new TaskException( getContext().getName() + " doesn\'t support multiple srcfile elements." ); | |||||
| } | |||||
| m_srcFilePos = getCommand().createMarker(); | |||||
| return m_srcFilePos; | |||||
| } | |||||
| /** | |||||
| * Marker that indicates where the name of the target file should be put on | |||||
| * the command line. | |||||
| */ | |||||
| public Marker createTargetfile() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_targetFilePos != null ) | |||||
| { | |||||
| throw new TaskException( getContext().getName() + " doesn\'t support multiple targetfile elements." ); | |||||
| } | |||||
| m_targetFilePos = getCommand().createMarker(); | |||||
| m_srcIsFirst = ( m_srcFilePos != null ); | |||||
| return m_targetFilePos; | |||||
| } | |||||
| /** | |||||
| * Construct the command line for parallel execution. | |||||
| * | |||||
| * @param srcFiles The filenames to add to the commandline | |||||
| */ | |||||
| protected String[] getCommandline( final String[] srcFiles, | |||||
| final File[] baseDirs ) | |||||
| throws TaskException | |||||
| { | |||||
| final ArrayList targets = new ArrayList(); | |||||
| if( m_targetFilePos != null ) | |||||
| { | |||||
| Hashtable addedFiles = new Hashtable(); | |||||
| for( int i = 0; i < srcFiles.length; i++ ) | |||||
| { | |||||
| String[] subTargets = m_mapper.mapFileName( srcFiles[ i ] ); | |||||
| if( subTargets != null ) | |||||
| { | |||||
| for( int j = 0; j < subTargets.length; j++ ) | |||||
| { | |||||
| String name = null; | |||||
| if( !m_relative ) | |||||
| { | |||||
| name = | |||||
| ( new File( m_destDir, subTargets[ j ] ) ).getAbsolutePath(); | |||||
| } | |||||
| else | |||||
| { | |||||
| name = subTargets[ j ]; | |||||
| } | |||||
| if( !addedFiles.contains( name ) ) | |||||
| { | |||||
| targets.add( name ); | |||||
| addedFiles.put( name, name ); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| String[] targetFiles = new String[ targets.size() ]; | |||||
| targetFiles = (String[])targets.toArray( targetFiles ); | |||||
| String[] orig = getCommand().getCommandline(); | |||||
| String[] result = new String[ orig.length + srcFiles.length + targetFiles.length ]; | |||||
| int srcIndex = orig.length; | |||||
| if( m_srcFilePos != null ) | |||||
| { | |||||
| srcIndex = m_srcFilePos.getPosition(); | |||||
| } | |||||
| if( m_targetFilePos != null ) | |||||
| { | |||||
| int targetIndex = m_targetFilePos.getPosition(); | |||||
| if( srcIndex < targetIndex | |||||
| || ( srcIndex == targetIndex && m_srcIsFirst ) ) | |||||
| { | |||||
| // 0 --> srcIndex | |||||
| System.arraycopy( orig, 0, result, 0, srcIndex ); | |||||
| // srcIndex --> targetIndex | |||||
| System.arraycopy( orig, srcIndex, result, | |||||
| srcIndex + srcFiles.length, | |||||
| targetIndex - srcIndex ); | |||||
| // targets are already absolute file names | |||||
| System.arraycopy( targetFiles, 0, result, | |||||
| targetIndex + srcFiles.length, | |||||
| targetFiles.length ); | |||||
| // targetIndex --> end | |||||
| System.arraycopy( orig, targetIndex, result, | |||||
| targetIndex + srcFiles.length + targetFiles.length, | |||||
| orig.length - targetIndex ); | |||||
| } | |||||
| else | |||||
| { | |||||
| // 0 --> targetIndex | |||||
| System.arraycopy( orig, 0, result, 0, targetIndex ); | |||||
| // targets are already absolute file names | |||||
| System.arraycopy( targetFiles, 0, result, | |||||
| targetIndex, | |||||
| targetFiles.length ); | |||||
| // targetIndex --> srcIndex | |||||
| System.arraycopy( orig, targetIndex, result, | |||||
| targetIndex + targetFiles.length, | |||||
| srcIndex - targetIndex ); | |||||
| // srcIndex --> end | |||||
| System.arraycopy( orig, srcIndex, result, | |||||
| srcIndex + srcFiles.length + targetFiles.length, | |||||
| orig.length - srcIndex ); | |||||
| srcIndex += targetFiles.length; | |||||
| } | |||||
| } | |||||
| else | |||||
| {// no targetFilePos | |||||
| // 0 --> srcIndex | |||||
| System.arraycopy( orig, 0, result, 0, srcIndex ); | |||||
| // srcIndex --> end | |||||
| System.arraycopy( orig, srcIndex, result, | |||||
| srcIndex + srcFiles.length, | |||||
| orig.length - srcIndex ); | |||||
| } | |||||
| // fill in source file names | |||||
| for( int i = 0; i < srcFiles.length; i++ ) | |||||
| { | |||||
| if( !m_relative ) | |||||
| { | |||||
| result[ srcIndex + i ] = | |||||
| ( new File( baseDirs[ i ], srcFiles[ i ] ) ).getAbsolutePath(); | |||||
| } | |||||
| else | |||||
| { | |||||
| result[ srcIndex + i ] = srcFiles[ i ]; | |||||
| } | |||||
| } | |||||
| return result; | |||||
| } | |||||
| /** | |||||
| * Construct the command line for serial execution. | |||||
| * | |||||
| * @param srcFile The filename to add to the commandline | |||||
| * @param baseDir filename is relative to this dir | |||||
| * @return The Commandline value | |||||
| */ | |||||
| protected String[] getCommandline( final String srcFile, | |||||
| final File baseDir ) | |||||
| throws TaskException | |||||
| { | |||||
| return getCommandline( new String[]{srcFile}, new File[]{baseDir} ); | |||||
| } | |||||
| /** | |||||
| * Return the list of Directories from this DirectoryScanner that should be | |||||
| * included on the command line. | |||||
| * | |||||
| * @param baseDir Description of Parameter | |||||
| * @param ds Description of Parameter | |||||
| * @return The Dirs value | |||||
| */ | |||||
| protected String[] getDirs( final File baseDir, | |||||
| final DirectoryScanner ds ) | |||||
| throws TaskException | |||||
| { | |||||
| if( m_mapper != null ) | |||||
| { | |||||
| final SourceFileScanner scanner = new SourceFileScanner(); | |||||
| setupLogger( scanner ); | |||||
| return scanner.restrict( ds.getIncludedDirectories(), baseDir, m_destDir, | |||||
| m_mapper ); | |||||
| } | |||||
| else | |||||
| { | |||||
| return ds.getIncludedDirectories(); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Return the list of files from this DirectoryScanner that should be | |||||
| * included on the command line. | |||||
| * | |||||
| * @param baseDir Description of Parameter | |||||
| * @param ds Description of Parameter | |||||
| * @return The Files value | |||||
| */ | |||||
| protected String[] getFiles( final File baseDir, | |||||
| final DirectoryScanner ds ) | |||||
| throws TaskException | |||||
| { | |||||
| if( m_mapper != null ) | |||||
| { | |||||
| final SourceFileScanner scanner = new SourceFileScanner(); | |||||
| setupLogger( scanner ); | |||||
| return scanner.restrict( ds.getIncludedFiles(), baseDir, m_destDir, | |||||
| m_mapper ); | |||||
| } | |||||
| else | |||||
| { | |||||
| return ds.getIncludedFiles(); | |||||
| } | |||||
| } | |||||
| protected void validate() | |||||
| throws TaskException | |||||
| { | |||||
| super.validate(); | |||||
| if( m_filesets.size() == 0 ) | |||||
| { | |||||
| final String message = "no filesets specified"; | |||||
| throw new TaskException( message ); | |||||
| } | |||||
| if( m_targetFilePos != null || | |||||
| m_mapperElement != null || | |||||
| m_destDir != null ) | |||||
| { | |||||
| if( m_mapperElement == null ) | |||||
| { | |||||
| final String message = "no mapper specified"; | |||||
| throw new TaskException( message ); | |||||
| } | |||||
| if( m_mapperElement == null ) | |||||
| { | |||||
| final String message = "no dest attribute specified"; | |||||
| throw new TaskException( message ); | |||||
| } | |||||
| m_mapper = m_mapperElement.getImplementation(); | |||||
| } | |||||
| } | |||||
| protected void runExec( final Execute exe ) | |||||
| throws TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| final ArrayList fileNames = new ArrayList(); | |||||
| final ArrayList baseDirs = new ArrayList(); | |||||
| for( int i = 0; i < m_filesets.size(); i++ ) | |||||
| { | |||||
| final FileSet fs = (FileSet)m_filesets.get( i ); | |||||
| final File base = fs.getDir(); | |||||
| final DirectoryScanner ds = ScannerUtil.getDirectoryScanner( fs ); | |||||
| if( !"dir".equals( m_type ) ) | |||||
| { | |||||
| final String[] s = getFiles( base, ds ); | |||||
| for( int j = 0; j < s.length; j++ ) | |||||
| { | |||||
| fileNames.add( s[ j ] ); | |||||
| baseDirs.add( base ); | |||||
| } | |||||
| } | |||||
| if( !"file".equals( m_type ) ) | |||||
| { | |||||
| final String[] s = getDirs( base, ds ); | |||||
| for( int j = 0; j < s.length; j++ ) | |||||
| { | |||||
| fileNames.add( s[ j ] ); | |||||
| baseDirs.add( base ); | |||||
| } | |||||
| } | |||||
| if( fileNames.size() == 0 && m_skipEmpty ) | |||||
| { | |||||
| getLogger().info( "Skipping fileset for directory " + base + ". It is empty." ); | |||||
| continue; | |||||
| } | |||||
| if( !m_parallel ) | |||||
| { | |||||
| String[] s = new String[ fileNames.size() ]; | |||||
| s = (String[])fileNames.toArray( s ); | |||||
| for( int j = 0; j < s.length; j++ ) | |||||
| { | |||||
| String[] command = getCommandline( s[ j ], base ); | |||||
| getLogger().debug( "Executing " + StringUtil.join( command, " " ) ); | |||||
| exe.setCommandline( command ); | |||||
| runExecute( exe ); | |||||
| } | |||||
| fileNames.clear(); | |||||
| baseDirs.clear(); | |||||
| } | |||||
| } | |||||
| if( m_parallel && ( fileNames.size() > 0 || !m_skipEmpty ) ) | |||||
| { | |||||
| String[] s = new String[ fileNames.size() ]; | |||||
| s = (String[])fileNames.toArray( s ); | |||||
| File[] b = new File[ baseDirs.size() ]; | |||||
| b = (File[])baseDirs.toArray( b ); | |||||
| String[] command = getCommandline( s, b ); | |||||
| getLogger().debug( "Executing " + StringUtil.join( command, " " ) ); | |||||
| exe.setCommandline( command ); | |||||
| runExecute( exe ); | |||||
| } | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Execute failed: " + e, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| // close the output file if required | |||||
| logFlush(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| /* | |||||
| * 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.types.EnumeratedAttribute; | |||||
| /** | |||||
| * Enumerated attribute with the values "file", "dir" and "both" for the | |||||
| * type attribute. | |||||
| */ | |||||
| public class FileDirBoth | |||||
| extends EnumeratedAttribute | |||||
| { | |||||
| public String[] getValues() | |||||
| { | |||||
| return new String[]{"file", "dir", "both"}; | |||||
| } | |||||
| } | |||||
| @@ -1,114 +0,0 @@ | |||||
| /* | |||||
| * 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.io.ByteArrayOutputStream; | |||||
| import java.io.IOException; | |||||
| import java.io.OutputStream; | |||||
| import org.apache.avalon.framework.logger.Logger; | |||||
| /** | |||||
| * Logs each line written to this stream to the log system of ant. Tries to be | |||||
| * smart about line separators.<br> | |||||
| * TODO: This class can be split to implement other line based processing of | |||||
| * data written to the stream. | |||||
| * | |||||
| * @author thomas.haas@softwired-inc.com | |||||
| */ | |||||
| public class LogOutputStream | |||||
| extends OutputStream | |||||
| { | |||||
| private final boolean m_isError; | |||||
| private final Logger m_logger; | |||||
| private ByteArrayOutputStream m_buffer = new ByteArrayOutputStream(); | |||||
| private boolean m_skip; | |||||
| public LogOutputStream( final Logger logger, final boolean isError ) | |||||
| { | |||||
| m_logger = logger; | |||||
| m_isError = isError; | |||||
| } | |||||
| protected final Logger getLogger() | |||||
| { | |||||
| return m_logger; | |||||
| } | |||||
| /** | |||||
| * Writes all remaining | |||||
| * | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public void close() | |||||
| throws IOException | |||||
| { | |||||
| if( m_buffer.size() > 0 ) | |||||
| { | |||||
| processBuffer(); | |||||
| } | |||||
| super.close(); | |||||
| } | |||||
| /** | |||||
| * Write the data to the buffer and flush the buffer, if a line separator is | |||||
| * detected. | |||||
| * | |||||
| * @param cc data to log (byte). | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public void write( final int ch ) | |||||
| throws IOException | |||||
| { | |||||
| if( ( ch == '\n' ) || ( ch == '\r' ) ) | |||||
| { | |||||
| if( !m_skip ) | |||||
| { | |||||
| processBuffer(); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| m_buffer.write( (byte)ch ); | |||||
| } | |||||
| m_skip = ( ch == '\r' ); | |||||
| } | |||||
| /** | |||||
| * Converts the buffer to a string and sends it to <code>processLine</code> | |||||
| */ | |||||
| private void processBuffer() | |||||
| { | |||||
| processLine( m_buffer.toString() ); | |||||
| m_buffer.reset(); | |||||
| } | |||||
| /** | |||||
| * Logs a line to the log system of ant. | |||||
| * | |||||
| * @param line the line to log. | |||||
| * @param level Description of Parameter | |||||
| */ | |||||
| protected void processLine( final String line ) | |||||
| { | |||||
| if( m_isError ) | |||||
| { | |||||
| getLogger().warn( line ); | |||||
| } | |||||
| else | |||||
| { | |||||
| getLogger().info( line ); | |||||
| } | |||||
| } | |||||
| public boolean isError() | |||||
| { | |||||
| return m_isError; | |||||
| } | |||||
| } | |||||
| @@ -1,414 +0,0 @@ | |||||
| /* | |||||
| * 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.io.BufferedReader; | |||||
| import java.io.ByteArrayOutputStream; | |||||
| import java.io.File; | |||||
| import java.io.FileNotFoundException; | |||||
| import java.io.FileOutputStream; | |||||
| import java.io.IOException; | |||||
| import java.io.StringReader; | |||||
| import java.util.Iterator; | |||||
| import java.util.Properties; | |||||
| import org.apache.avalon.excalibur.util.StringUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.tools.ant.Task; | |||||
| 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 given command if the os platform is appropriate. | |||||
| * | |||||
| * @author duncan@x180.com | |||||
| * @author rubys@us.ibm.com | |||||
| * @author thomas.haas@softwired-inc.com | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @author <a href="mailto:mariusz@rakiura.org">Mariusz Nowostawski</a> | |||||
| */ | |||||
| public class ExecTask | |||||
| extends Task | |||||
| { | |||||
| private boolean m_newEnvironment; | |||||
| private Integer m_timeout; | |||||
| private EnvironmentData m_env = new EnvironmentData(); | |||||
| private Commandline m_command = new Commandline(); | |||||
| private FileOutputStream m_ouput; | |||||
| private ByteArrayOutputStream m_byteArrayOutput; | |||||
| /** | |||||
| * Controls whether the VM (1.3 and above) is used to execute the command | |||||
| */ | |||||
| private boolean m_useVMLauncher = true; | |||||
| private File m_workingDirectory; | |||||
| private String m_os; | |||||
| private File m_outputFile; | |||||
| private String m_outputProperty; | |||||
| private String m_resultProperty; | |||||
| /** | |||||
| * The working directory of the process | |||||
| * | |||||
| * @param d The new Dir value | |||||
| */ | |||||
| public void setDir( final File dir ) | |||||
| throws TaskException | |||||
| { | |||||
| m_workingDirectory = 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 <code>os.name</code> is included in this | |||||
| * string. | |||||
| * | |||||
| * @param os The new Os value | |||||
| */ | |||||
| public void setOs( final String os ) | |||||
| { | |||||
| m_os = os; | |||||
| } | |||||
| /** | |||||
| * File the output of the process is redirected to. | |||||
| * | |||||
| * @param out The new Output value | |||||
| */ | |||||
| public void setOutput( final File outputFile ) | |||||
| { | |||||
| m_outputFile = outputFile; | |||||
| } | |||||
| /** | |||||
| * Property name whose value should be set to the output of the process | |||||
| * | |||||
| * @param outputprop The new Outputproperty value | |||||
| */ | |||||
| public void setOutputproperty( final String outputprop ) | |||||
| { | |||||
| m_outputProperty = outputprop; | |||||
| } | |||||
| /** | |||||
| * fill a property in with a result. when no property is defined: failure to | |||||
| * execute | |||||
| * | |||||
| * @param resultProperty The new ResultProperty value | |||||
| * @since 1.5 | |||||
| */ | |||||
| public void setResultProperty( final String resultProperty ) | |||||
| { | |||||
| m_resultProperty = resultProperty; | |||||
| } | |||||
| /** | |||||
| * Timeout in milliseconds after which the process will be killed. | |||||
| * | |||||
| * @param value The new Timeout value | |||||
| */ | |||||
| public void setTimeout( final Integer timeout ) | |||||
| { | |||||
| m_timeout = timeout; | |||||
| } | |||||
| /** | |||||
| * Control whether the VM is used to launch the new process or whether the | |||||
| * OS's shell is used. | |||||
| * | |||||
| * @param vmLauncher The new VMLauncher value | |||||
| */ | |||||
| public void setVMLauncher( final boolean vmLauncher ) | |||||
| { | |||||
| m_useVMLauncher = vmLauncher; | |||||
| } | |||||
| /** | |||||
| * Add a nested env element - an environment variable. | |||||
| * | |||||
| * @param var The feature to be added to the Env attribute | |||||
| */ | |||||
| public void addEnv( final EnvironmentVariable var ) | |||||
| { | |||||
| m_env.addVariable( var ); | |||||
| } | |||||
| /** | |||||
| * Add a nested arg element - a command line argument. | |||||
| */ | |||||
| public void addArg( final Argument argument ) | |||||
| { | |||||
| m_command.addArgument( argument ); | |||||
| } | |||||
| /** | |||||
| * Do the work. | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| public void execute() | |||||
| throws TaskException | |||||
| { | |||||
| validate(); | |||||
| if( isValidOs() ) | |||||
| { | |||||
| runExec( prepareExec() ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Is this the OS the user wanted? | |||||
| * | |||||
| * @return The ValidOs value | |||||
| */ | |||||
| protected boolean isValidOs() | |||||
| { | |||||
| // test if os match | |||||
| final String os = System.getProperty( "os.name" ); | |||||
| getLogger().debug( "Current OS is " + os ); | |||||
| if( ( m_os != null ) && ( m_os.indexOf( os ) < 0 ) ) | |||||
| { | |||||
| // this command will be executed only on the specified OS | |||||
| getLogger().debug( "This OS, " + os + " was not found in the specified list of valid OSes: " + m_os ); | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /** | |||||
| * A Utility method for this classes and subclasses to run an Execute | |||||
| * instance (an external command). | |||||
| * | |||||
| * @param exe Description of Parameter | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| protected final void runExecute( final Execute exe ) | |||||
| throws IOException, TaskException | |||||
| { | |||||
| final int err = exe.execute(); | |||||
| //test for and handle a forced process death | |||||
| maybeSetResultPropertyValue( err ); | |||||
| if( 0 != err ) | |||||
| { | |||||
| throw new TaskException( getContext().getName() + " returned: " + err ); | |||||
| } | |||||
| if( null != m_byteArrayOutput ) | |||||
| { | |||||
| writeResultToProperty(); | |||||
| } | |||||
| } | |||||
| private void writeResultToProperty() throws IOException, TaskException | |||||
| { | |||||
| final BufferedReader input = | |||||
| new BufferedReader( new StringReader( m_byteArrayOutput.toString() ) ); | |||||
| String line = null; | |||||
| StringBuffer val = new StringBuffer(); | |||||
| while( ( line = input.readLine() ) != null ) | |||||
| { | |||||
| if( val.length() != 0 ) | |||||
| { | |||||
| val.append( StringUtil.LINE_SEPARATOR ); | |||||
| } | |||||
| val.append( line ); | |||||
| } | |||||
| final String name = m_outputProperty; | |||||
| final Object value = val.toString(); | |||||
| getContext().setProperty( name, value ); | |||||
| } | |||||
| /** | |||||
| * Has the user set all necessary attributes? | |||||
| * | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| protected void validate() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_command.getExecutable() == null ) | |||||
| { | |||||
| throw new TaskException( "no executable specified" ); | |||||
| } | |||||
| if( m_workingDirectory != null && !m_workingDirectory.exists() ) | |||||
| { | |||||
| throw new TaskException( "The directory you specified does not exist" ); | |||||
| } | |||||
| if( m_workingDirectory != null && !m_workingDirectory.isDirectory() ) | |||||
| { | |||||
| throw new TaskException( "The directory you specified is not a directory" ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Create the StreamHandler to use with our Execute instance. | |||||
| * | |||||
| * @return Description of the Returned Value | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| private void setupOutput( final Execute exe ) | |||||
| throws TaskException | |||||
| { | |||||
| if( m_outputFile != null ) | |||||
| { | |||||
| try | |||||
| { | |||||
| m_ouput = new FileOutputStream( m_outputFile ); | |||||
| getLogger().debug( "Output redirected to " + m_outputFile ); | |||||
| exe.setOutput( m_ouput ); | |||||
| exe.setError( m_ouput ); | |||||
| } | |||||
| catch( FileNotFoundException fne ) | |||||
| { | |||||
| throw new TaskException( "Cannot write to " + m_outputFile, fne ); | |||||
| } | |||||
| catch( IOException ioe ) | |||||
| { | |||||
| throw new TaskException( "Cannot write to " + m_outputFile, ioe ); | |||||
| } | |||||
| } | |||||
| else if( m_outputProperty != null ) | |||||
| { | |||||
| m_byteArrayOutput = new ByteArrayOutputStream(); | |||||
| getLogger().debug( "Output redirected to ByteArray" ); | |||||
| exe.setOutput( m_byteArrayOutput ); | |||||
| exe.setError( m_byteArrayOutput ); | |||||
| } | |||||
| else | |||||
| { | |||||
| exe.setOutput( new LogOutputStream( getLogger(), false ) ); | |||||
| exe.setError( new LogOutputStream( getLogger(), true ) ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Flush the output stream - if there is one. | |||||
| */ | |||||
| protected void logFlush() | |||||
| { | |||||
| try | |||||
| { | |||||
| if( m_ouput != null ) | |||||
| { | |||||
| m_ouput.close(); | |||||
| } | |||||
| if( m_byteArrayOutput != null ) | |||||
| { | |||||
| m_byteArrayOutput.close(); | |||||
| } | |||||
| } | |||||
| catch( IOException io ) | |||||
| { | |||||
| } | |||||
| } | |||||
| /** | |||||
| * helper method to set result property to the passed in value if | |||||
| * appropriate | |||||
| */ | |||||
| protected void maybeSetResultPropertyValue( int result ) | |||||
| throws TaskException | |||||
| { | |||||
| final String res = Integer.toString( result ); | |||||
| if( m_resultProperty != null ) | |||||
| { | |||||
| final String name = m_resultProperty; | |||||
| getContext().setProperty( name, res ); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Create an Execute instance with the correct working directory set. | |||||
| */ | |||||
| protected Execute prepareExec() | |||||
| throws TaskException | |||||
| { | |||||
| // default directory to the project's base directory | |||||
| if( m_workingDirectory == null ) | |||||
| { | |||||
| m_workingDirectory = getBaseDirectory(); | |||||
| } | |||||
| // show the command | |||||
| getLogger().debug( m_command.toString() ); | |||||
| final Execute exe = new Execute(); | |||||
| setupOutput( exe ); | |||||
| if( null != m_timeout ) | |||||
| { | |||||
| exe.setTimeout( m_timeout.intValue() ); | |||||
| } | |||||
| exe.setWorkingDirectory( m_workingDirectory ); | |||||
| exe.setVMLauncher( m_useVMLauncher ); | |||||
| exe.setNewenvironment( m_newEnvironment ); | |||||
| final Properties environment = m_env.getVariables(); | |||||
| final Iterator keys = environment.keySet().iterator(); | |||||
| while( keys.hasNext() ) | |||||
| { | |||||
| final String key = (String)keys.next(); | |||||
| final String value = environment.getProperty( key ); | |||||
| getLogger().debug( "Setting environment variable: " + key + "=" + value ); | |||||
| } | |||||
| exe.setEnvironment( environment ); | |||||
| return exe; | |||||
| } | |||||
| /** | |||||
| * Run the command using the given Execute instance. This may be overidden | |||||
| * by subclasses | |||||
| * | |||||
| * @param exe Description of Parameter | |||||
| * @exception TaskException Description of Exception | |||||
| */ | |||||
| protected void runExec( final Execute exe ) | |||||
| throws TaskException | |||||
| { | |||||
| exe.setCommandline( m_command.getCommandline() ); | |||||
| try | |||||
| { | |||||
| runExecute( exe ); | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Execute failed: " + e.toString(), e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| // close the output file if required | |||||
| logFlush(); | |||||
| } | |||||
| } | |||||
| protected final Commandline getCommand() | |||||
| { | |||||
| return m_command; | |||||
| } | |||||
| } | |||||
| @@ -1,142 +0,0 @@ | |||||
| /* | |||||
| * 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.io.File; | |||||
| import java.io.IOException; | |||||
| import java.io.OutputStream; | |||||
| import java.util.Properties; | |||||
| import org.apache.aut.nativelib.ExecException; | |||||
| import org.apache.aut.nativelib.ExecManager; | |||||
| import org.apache.aut.nativelib.ExecMetaData; | |||||
| import org.apache.avalon.excalibur.io.IOUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.myrmidon.framework.factorys.ExecManagerFactory; | |||||
| import org.apache.myrmidon.interfaces.service.ServiceException; | |||||
| /** | |||||
| * Runs an external program. | |||||
| * | |||||
| * @author thomas.haas@softwired-inc.com | |||||
| */ | |||||
| public class Execute | |||||
| { | |||||
| private String[] m_command; | |||||
| private Properties m_environment = new Properties(); | |||||
| private File m_workingDirectory = new File( "." ); | |||||
| private boolean m_newEnvironment; | |||||
| private OutputStream m_output; | |||||
| private OutputStream m_error; | |||||
| private long m_timeout; | |||||
| /** | |||||
| * Controls whether the VM is used to launch commands, where possible | |||||
| */ | |||||
| private boolean m_useVMLauncher = true; | |||||
| public void setTimeout( final long timeout ) | |||||
| { | |||||
| m_timeout = timeout; | |||||
| } | |||||
| public void setOutput( final OutputStream output ) | |||||
| { | |||||
| m_output = output; | |||||
| } | |||||
| public void setError( final OutputStream error ) | |||||
| { | |||||
| m_error = error; | |||||
| } | |||||
| /** | |||||
| * Sets the commandline of the subprocess to launch. | |||||
| * | |||||
| * @param commandline the commandline of the subprocess to launch | |||||
| */ | |||||
| public void setCommandline( String[] commandline ) | |||||
| { | |||||
| m_command = commandline; | |||||
| } | |||||
| public void setEnvironment( final Properties environment ) | |||||
| { | |||||
| if( null == environment ) | |||||
| { | |||||
| throw new NullPointerException( "environment" ); | |||||
| } | |||||
| m_environment = environment; | |||||
| } | |||||
| /** | |||||
| * Set whether to propagate the default environment or not. | |||||
| * | |||||
| * @param newenv whether to propagate the process environment. | |||||
| */ | |||||
| public void setNewenvironment( boolean newEnvironment ) | |||||
| { | |||||
| m_newEnvironment = newEnvironment; | |||||
| } | |||||
| /** | |||||
| * Launch this execution through the VM, where possible, rather than through | |||||
| * the OS's shell. In some cases and operating systems using the shell will | |||||
| * allow the shell to perform additional processing such as associating an | |||||
| * executable with a script, etc | |||||
| * | |||||
| * @param useVMLauncher The new VMLauncher value | |||||
| */ | |||||
| public void setVMLauncher( boolean useVMLauncher ) | |||||
| { | |||||
| m_useVMLauncher = useVMLauncher; | |||||
| } | |||||
| /** | |||||
| * Sets the working directory of the process to execute. <p> | |||||
| * | |||||
| * @param workingDirectory the working directory of the process. | |||||
| */ | |||||
| public void setWorkingDirectory( final File workingDirectory ) | |||||
| { | |||||
| m_workingDirectory = workingDirectory; | |||||
| } | |||||
| /** | |||||
| * Runs a process defined by the command line and returns its exit status. | |||||
| * | |||||
| * @return the exit status of the subprocess or <code>INVALID</code> | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public int execute() | |||||
| throws IOException, TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| final ExecManagerFactory factory = new ExecManagerFactory(); | |||||
| final ExecManager manager = (ExecManager)factory.createService(); | |||||
| final ExecMetaData metaData = | |||||
| new ExecMetaData( m_command, m_environment, | |||||
| m_workingDirectory, m_newEnvironment ); | |||||
| return manager.execute( metaData, null, m_output, m_error, m_timeout ); | |||||
| } | |||||
| catch( final ExecException ee ) | |||||
| { | |||||
| throw new TaskException( ee.getMessage(), ee ); | |||||
| } | |||||
| catch( final ServiceException se ) | |||||
| { | |||||
| throw new TaskException( se.getMessage(), se ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| IOUtil.shutdownStream( m_output ); | |||||
| IOUtil.shutdownStream( m_error ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,440 +0,0 @@ | |||||
| /* | |||||
| * 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.io.File; | |||||
| import java.io.IOException; | |||||
| import java.util.ArrayList; | |||||
| import java.util.Hashtable; | |||||
| import org.apache.avalon.excalibur.util.StringUtil; | |||||
| import org.apache.myrmidon.api.TaskException; | |||||
| import org.apache.tools.ant.types.DirectoryScanner; | |||||
| import org.apache.tools.ant.types.FileSet; | |||||
| import org.apache.tools.ant.types.Marker; | |||||
| import org.apache.tools.ant.types.ScannerUtil; | |||||
| import org.apache.tools.ant.types.SourceFileScanner; | |||||
| import org.apache.tools.ant.util.mappers.FileNameMapper; | |||||
| import org.apache.tools.ant.util.mappers.Mapper; | |||||
| /** | |||||
| * Executes a given command, supplying a set of files as arguments. | |||||
| * | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @author <a href="mailto:mariusz@rakiura.org">Mariusz Nowostawski</a> | |||||
| */ | |||||
| public class ExecuteOn | |||||
| extends ExecTask | |||||
| { | |||||
| private ArrayList m_filesets = new ArrayList(); | |||||
| private boolean m_relative; | |||||
| private boolean m_parallel; | |||||
| private String m_type = "file"; | |||||
| private Marker m_srcFilePos; | |||||
| private boolean m_skipEmpty; | |||||
| private Marker m_targetFilePos; | |||||
| private Mapper m_mapperElement; | |||||
| private FileNameMapper m_mapper; | |||||
| private File m_destDir; | |||||
| /** | |||||
| * Has <srcfile> been specified before <targetfile> | |||||
| */ | |||||
| private boolean m_srcIsFirst = true; | |||||
| /** | |||||
| * Set the destination directory. | |||||
| */ | |||||
| public void setDest( final File destDir ) | |||||
| { | |||||
| m_destDir = destDir; | |||||
| } | |||||
| /** | |||||
| * Shall the command work on all specified files in parallel? | |||||
| */ | |||||
| public void setParallel( final boolean parallel ) | |||||
| { | |||||
| m_parallel = parallel; | |||||
| } | |||||
| /** | |||||
| * Should filenames be returned as relative path names? | |||||
| */ | |||||
| public void setRelative( final boolean relative ) | |||||
| { | |||||
| m_relative = relative; | |||||
| } | |||||
| /** | |||||
| * Should empty filesets be ignored? | |||||
| */ | |||||
| public void setSkipEmptyFilesets( final boolean skip ) | |||||
| { | |||||
| m_skipEmpty = skip; | |||||
| } | |||||
| /** | |||||
| * Shall the command work only on files, directories or both? | |||||
| */ | |||||
| public void setType( final FileDirBoth type ) | |||||
| { | |||||
| m_type = type.getValue(); | |||||
| } | |||||
| /** | |||||
| * Adds a set of files (nested fileset attribute). | |||||
| */ | |||||
| public void addFileset( final FileSet set ) | |||||
| { | |||||
| m_filesets.add( set ); | |||||
| } | |||||
| /** | |||||
| * Defines the FileNameMapper to use (nested mapper element). | |||||
| */ | |||||
| public Mapper createMapper() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_mapperElement != null ) | |||||
| { | |||||
| throw new TaskException( "Cannot define more than one mapper" ); | |||||
| } | |||||
| m_mapperElement = new Mapper(); | |||||
| return m_mapperElement; | |||||
| } | |||||
| /** | |||||
| * Marker that indicates where the name of the source file should be put on | |||||
| * the command line. | |||||
| */ | |||||
| public Marker createSrcfile() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_srcFilePos != null ) | |||||
| { | |||||
| throw new TaskException( getContext().getName() + " doesn\'t support multiple srcfile elements." ); | |||||
| } | |||||
| m_srcFilePos = getCommand().createMarker(); | |||||
| return m_srcFilePos; | |||||
| } | |||||
| /** | |||||
| * Marker that indicates where the name of the target file should be put on | |||||
| * the command line. | |||||
| */ | |||||
| public Marker createTargetfile() | |||||
| throws TaskException | |||||
| { | |||||
| if( m_targetFilePos != null ) | |||||
| { | |||||
| throw new TaskException( getContext().getName() + " doesn\'t support multiple targetfile elements." ); | |||||
| } | |||||
| m_targetFilePos = getCommand().createMarker(); | |||||
| m_srcIsFirst = ( m_srcFilePos != null ); | |||||
| return m_targetFilePos; | |||||
| } | |||||
| /** | |||||
| * Construct the command line for parallel execution. | |||||
| * | |||||
| * @param srcFiles The filenames to add to the commandline | |||||
| */ | |||||
| protected String[] getCommandline( final String[] srcFiles, | |||||
| final File[] baseDirs ) | |||||
| throws TaskException | |||||
| { | |||||
| final ArrayList targets = new ArrayList(); | |||||
| if( m_targetFilePos != null ) | |||||
| { | |||||
| Hashtable addedFiles = new Hashtable(); | |||||
| for( int i = 0; i < srcFiles.length; i++ ) | |||||
| { | |||||
| String[] subTargets = m_mapper.mapFileName( srcFiles[ i ] ); | |||||
| if( subTargets != null ) | |||||
| { | |||||
| for( int j = 0; j < subTargets.length; j++ ) | |||||
| { | |||||
| String name = null; | |||||
| if( !m_relative ) | |||||
| { | |||||
| name = | |||||
| ( new File( m_destDir, subTargets[ j ] ) ).getAbsolutePath(); | |||||
| } | |||||
| else | |||||
| { | |||||
| name = subTargets[ j ]; | |||||
| } | |||||
| if( !addedFiles.contains( name ) ) | |||||
| { | |||||
| targets.add( name ); | |||||
| addedFiles.put( name, name ); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| String[] targetFiles = new String[ targets.size() ]; | |||||
| targetFiles = (String[])targets.toArray( targetFiles ); | |||||
| String[] orig = getCommand().getCommandline(); | |||||
| String[] result = new String[ orig.length + srcFiles.length + targetFiles.length ]; | |||||
| int srcIndex = orig.length; | |||||
| if( m_srcFilePos != null ) | |||||
| { | |||||
| srcIndex = m_srcFilePos.getPosition(); | |||||
| } | |||||
| if( m_targetFilePos != null ) | |||||
| { | |||||
| int targetIndex = m_targetFilePos.getPosition(); | |||||
| if( srcIndex < targetIndex | |||||
| || ( srcIndex == targetIndex && m_srcIsFirst ) ) | |||||
| { | |||||
| // 0 --> srcIndex | |||||
| System.arraycopy( orig, 0, result, 0, srcIndex ); | |||||
| // srcIndex --> targetIndex | |||||
| System.arraycopy( orig, srcIndex, result, | |||||
| srcIndex + srcFiles.length, | |||||
| targetIndex - srcIndex ); | |||||
| // targets are already absolute file names | |||||
| System.arraycopy( targetFiles, 0, result, | |||||
| targetIndex + srcFiles.length, | |||||
| targetFiles.length ); | |||||
| // targetIndex --> end | |||||
| System.arraycopy( orig, targetIndex, result, | |||||
| targetIndex + srcFiles.length + targetFiles.length, | |||||
| orig.length - targetIndex ); | |||||
| } | |||||
| else | |||||
| { | |||||
| // 0 --> targetIndex | |||||
| System.arraycopy( orig, 0, result, 0, targetIndex ); | |||||
| // targets are already absolute file names | |||||
| System.arraycopy( targetFiles, 0, result, | |||||
| targetIndex, | |||||
| targetFiles.length ); | |||||
| // targetIndex --> srcIndex | |||||
| System.arraycopy( orig, targetIndex, result, | |||||
| targetIndex + targetFiles.length, | |||||
| srcIndex - targetIndex ); | |||||
| // srcIndex --> end | |||||
| System.arraycopy( orig, srcIndex, result, | |||||
| srcIndex + srcFiles.length + targetFiles.length, | |||||
| orig.length - srcIndex ); | |||||
| srcIndex += targetFiles.length; | |||||
| } | |||||
| } | |||||
| else | |||||
| {// no targetFilePos | |||||
| // 0 --> srcIndex | |||||
| System.arraycopy( orig, 0, result, 0, srcIndex ); | |||||
| // srcIndex --> end | |||||
| System.arraycopy( orig, srcIndex, result, | |||||
| srcIndex + srcFiles.length, | |||||
| orig.length - srcIndex ); | |||||
| } | |||||
| // fill in source file names | |||||
| for( int i = 0; i < srcFiles.length; i++ ) | |||||
| { | |||||
| if( !m_relative ) | |||||
| { | |||||
| result[ srcIndex + i ] = | |||||
| ( new File( baseDirs[ i ], srcFiles[ i ] ) ).getAbsolutePath(); | |||||
| } | |||||
| else | |||||
| { | |||||
| result[ srcIndex + i ] = srcFiles[ i ]; | |||||
| } | |||||
| } | |||||
| return result; | |||||
| } | |||||
| /** | |||||
| * Construct the command line for serial execution. | |||||
| * | |||||
| * @param srcFile The filename to add to the commandline | |||||
| * @param baseDir filename is relative to this dir | |||||
| * @return The Commandline value | |||||
| */ | |||||
| protected String[] getCommandline( final String srcFile, | |||||
| final File baseDir ) | |||||
| throws TaskException | |||||
| { | |||||
| return getCommandline( new String[]{srcFile}, new File[]{baseDir} ); | |||||
| } | |||||
| /** | |||||
| * Return the list of Directories from this DirectoryScanner that should be | |||||
| * included on the command line. | |||||
| * | |||||
| * @param baseDir Description of Parameter | |||||
| * @param ds Description of Parameter | |||||
| * @return The Dirs value | |||||
| */ | |||||
| protected String[] getDirs( final File baseDir, | |||||
| final DirectoryScanner ds ) | |||||
| throws TaskException | |||||
| { | |||||
| if( m_mapper != null ) | |||||
| { | |||||
| final SourceFileScanner scanner = new SourceFileScanner(); | |||||
| setupLogger( scanner ); | |||||
| return scanner.restrict( ds.getIncludedDirectories(), baseDir, m_destDir, | |||||
| m_mapper ); | |||||
| } | |||||
| else | |||||
| { | |||||
| return ds.getIncludedDirectories(); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Return the list of files from this DirectoryScanner that should be | |||||
| * included on the command line. | |||||
| * | |||||
| * @param baseDir Description of Parameter | |||||
| * @param ds Description of Parameter | |||||
| * @return The Files value | |||||
| */ | |||||
| protected String[] getFiles( final File baseDir, | |||||
| final DirectoryScanner ds ) | |||||
| throws TaskException | |||||
| { | |||||
| if( m_mapper != null ) | |||||
| { | |||||
| final SourceFileScanner scanner = new SourceFileScanner(); | |||||
| setupLogger( scanner ); | |||||
| return scanner.restrict( ds.getIncludedFiles(), baseDir, m_destDir, | |||||
| m_mapper ); | |||||
| } | |||||
| else | |||||
| { | |||||
| return ds.getIncludedFiles(); | |||||
| } | |||||
| } | |||||
| protected void validate() | |||||
| throws TaskException | |||||
| { | |||||
| super.validate(); | |||||
| if( m_filesets.size() == 0 ) | |||||
| { | |||||
| final String message = "no filesets specified"; | |||||
| throw new TaskException( message ); | |||||
| } | |||||
| if( m_targetFilePos != null || | |||||
| m_mapperElement != null || | |||||
| m_destDir != null ) | |||||
| { | |||||
| if( m_mapperElement == null ) | |||||
| { | |||||
| final String message = "no mapper specified"; | |||||
| throw new TaskException( message ); | |||||
| } | |||||
| if( m_mapperElement == null ) | |||||
| { | |||||
| final String message = "no dest attribute specified"; | |||||
| throw new TaskException( message ); | |||||
| } | |||||
| m_mapper = m_mapperElement.getImplementation(); | |||||
| } | |||||
| } | |||||
| protected void runExec( final Execute exe ) | |||||
| throws TaskException | |||||
| { | |||||
| try | |||||
| { | |||||
| final ArrayList fileNames = new ArrayList(); | |||||
| final ArrayList baseDirs = new ArrayList(); | |||||
| for( int i = 0; i < m_filesets.size(); i++ ) | |||||
| { | |||||
| final FileSet fs = (FileSet)m_filesets.get( i ); | |||||
| final File base = fs.getDir(); | |||||
| final DirectoryScanner ds = ScannerUtil.getDirectoryScanner( fs ); | |||||
| if( !"dir".equals( m_type ) ) | |||||
| { | |||||
| final String[] s = getFiles( base, ds ); | |||||
| for( int j = 0; j < s.length; j++ ) | |||||
| { | |||||
| fileNames.add( s[ j ] ); | |||||
| baseDirs.add( base ); | |||||
| } | |||||
| } | |||||
| if( !"file".equals( m_type ) ) | |||||
| { | |||||
| final String[] s = getDirs( base, ds ); | |||||
| for( int j = 0; j < s.length; j++ ) | |||||
| { | |||||
| fileNames.add( s[ j ] ); | |||||
| baseDirs.add( base ); | |||||
| } | |||||
| } | |||||
| if( fileNames.size() == 0 && m_skipEmpty ) | |||||
| { | |||||
| getLogger().info( "Skipping fileset for directory " + base + ". It is empty." ); | |||||
| continue; | |||||
| } | |||||
| if( !m_parallel ) | |||||
| { | |||||
| String[] s = new String[ fileNames.size() ]; | |||||
| s = (String[])fileNames.toArray( s ); | |||||
| for( int j = 0; j < s.length; j++ ) | |||||
| { | |||||
| String[] command = getCommandline( s[ j ], base ); | |||||
| getLogger().debug( "Executing " + StringUtil.join( command, " " ) ); | |||||
| exe.setCommandline( command ); | |||||
| runExecute( exe ); | |||||
| } | |||||
| fileNames.clear(); | |||||
| baseDirs.clear(); | |||||
| } | |||||
| } | |||||
| if( m_parallel && ( fileNames.size() > 0 || !m_skipEmpty ) ) | |||||
| { | |||||
| String[] s = new String[ fileNames.size() ]; | |||||
| s = (String[])fileNames.toArray( s ); | |||||
| File[] b = new File[ baseDirs.size() ]; | |||||
| b = (File[])baseDirs.toArray( b ); | |||||
| String[] command = getCommandline( s, b ); | |||||
| getLogger().debug( "Executing " + StringUtil.join( command, " " ) ); | |||||
| exe.setCommandline( command ); | |||||
| runExecute( exe ); | |||||
| } | |||||
| } | |||||
| catch( IOException e ) | |||||
| { | |||||
| throw new TaskException( "Execute failed: " + e, e ); | |||||
| } | |||||
| finally | |||||
| { | |||||
| // close the output file if required | |||||
| logFlush(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| /* | |||||
| * 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.types.EnumeratedAttribute; | |||||
| /** | |||||
| * Enumerated attribute with the values "file", "dir" and "both" for the | |||||
| * type attribute. | |||||
| */ | |||||
| public class FileDirBoth | |||||
| extends EnumeratedAttribute | |||||
| { | |||||
| public String[] getValues() | |||||
| { | |||||
| return new String[]{"file", "dir", "both"}; | |||||
| } | |||||
| } | |||||
| @@ -1,114 +0,0 @@ | |||||
| /* | |||||
| * 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.io.ByteArrayOutputStream; | |||||
| import java.io.IOException; | |||||
| import java.io.OutputStream; | |||||
| import org.apache.avalon.framework.logger.Logger; | |||||
| /** | |||||
| * Logs each line written to this stream to the log system of ant. Tries to be | |||||
| * smart about line separators.<br> | |||||
| * TODO: This class can be split to implement other line based processing of | |||||
| * data written to the stream. | |||||
| * | |||||
| * @author thomas.haas@softwired-inc.com | |||||
| */ | |||||
| public class LogOutputStream | |||||
| extends OutputStream | |||||
| { | |||||
| private final boolean m_isError; | |||||
| private final Logger m_logger; | |||||
| private ByteArrayOutputStream m_buffer = new ByteArrayOutputStream(); | |||||
| private boolean m_skip; | |||||
| public LogOutputStream( final Logger logger, final boolean isError ) | |||||
| { | |||||
| m_logger = logger; | |||||
| m_isError = isError; | |||||
| } | |||||
| protected final Logger getLogger() | |||||
| { | |||||
| return m_logger; | |||||
| } | |||||
| /** | |||||
| * Writes all remaining | |||||
| * | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public void close() | |||||
| throws IOException | |||||
| { | |||||
| if( m_buffer.size() > 0 ) | |||||
| { | |||||
| processBuffer(); | |||||
| } | |||||
| super.close(); | |||||
| } | |||||
| /** | |||||
| * Write the data to the buffer and flush the buffer, if a line separator is | |||||
| * detected. | |||||
| * | |||||
| * @param cc data to log (byte). | |||||
| * @exception IOException Description of Exception | |||||
| */ | |||||
| public void write( final int ch ) | |||||
| throws IOException | |||||
| { | |||||
| if( ( ch == '\n' ) || ( ch == '\r' ) ) | |||||
| { | |||||
| if( !m_skip ) | |||||
| { | |||||
| processBuffer(); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| m_buffer.write( (byte)ch ); | |||||
| } | |||||
| m_skip = ( ch == '\r' ); | |||||
| } | |||||
| /** | |||||
| * Converts the buffer to a string and sends it to <code>processLine</code> | |||||
| */ | |||||
| private void processBuffer() | |||||
| { | |||||
| processLine( m_buffer.toString() ); | |||||
| m_buffer.reset(); | |||||
| } | |||||
| /** | |||||
| * Logs a line to the log system of ant. | |||||
| * | |||||
| * @param line the line to log. | |||||
| * @param level Description of Parameter | |||||
| */ | |||||
| protected void processLine( final String line ) | |||||
| { | |||||
| if( m_isError ) | |||||
| { | |||||
| getLogger().warn( line ); | |||||
| } | |||||
| else | |||||
| { | |||||
| getLogger().info( line ); | |||||
| } | |||||
| } | |||||
| public boolean isError() | |||||
| { | |||||
| return m_isError; | |||||
| } | |||||
| } | |||||