import java.io.File;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.ExecuteJava;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
/**
* Ant task to derive a set of target files from a given set of source
* files. The derivation is done by invoking {@link Main#main(String[])}.
*
* @layer<antDerive>
*/
public class DeriveAntTask extends MatchingTask {
/**
* Adds a given argument to the argument list.
*
* @layer<antDerive>
*/
public Commandline.Argument createArg() {
return command.createArgument() ;
}
/**
* Adds a path for source directory search.
*
* @layer<antDerive>
*/
public Path createSrc() {
if ( sourcePath == null )
sourcePath = new Path( getProject() ) ;
return sourcePath.createPath() ;
}
/**
* Invokes {@link Main#main(String[])} for each source file.
*
* @layer<antDerive>
*/
public void execute() throws BuildException {
if ( sourcePath == null || sourcePath.size() < 1 )
throw new BuildException( "srcdir attribute must be set",
getLocation() ) ;
createArg().setValue( listFiles ? "-verbose" : "-quiet" ) ;
String[] extraArgs = command.getArguments() ;
int errors = 0 ;
String[] sourceDirs = sourcePath.list() ;
for ( int dirIndex = 0; dirIndex < sourceDirs.length; ++dirIndex ) {
File directory = getProject().resolveFile( sourceDirs [dirIndex] ) ;
if ( listFiles )
log( "directory \"" + directory + '"', Project.MSG_INFO ) ;
if ( ! directory.exists() )
throw new BuildException( "source directory \""
+ directory.getPath()
+ "\" does not exist",
getLocation() ) ;
DirectoryScanner scanner = getDirectoryScanner( directory ) ;
String[] files = scanner.getIncludedFiles() ;
if ( files.length > 0 ) {
for ( int n = 0 ; n < files.length ; ++n )
files[n] = new File( directory,files[n] ).toString() ;
processFiles( files, extraArgs ) ;
}
else
if ( errorIfNoFiles ) {
throw new BuildException( "no input files given",getLocation() ) ;
}
}
if ( errors > 0 ) {
String errorMessage =
"derivation failed in "
+ errors
+ " source "
+ ( errors == 1 ? "directory" : "directories" ) ;
if ( failOnError )
throw new BuildException( errorMessage, getLocation() ) ;
else
log( errorMessage, Project.MSG_ERR ) ;
}
}
/**
* A <code>main</code> method causes a wrapper class to be generated
* at the top level of the enclosing package. As a result, this task
* will be available as a top-level (<em>not</em> inner) class within
* the enclosing package.
*
* @layer<antDerive>
*/
public static void main( String[] args ) {
throw new UnsupportedOperationException( "invoking \"DeriveAntTask.main\" is not supported" ) ;
}
/**
* Processes a given array of source file names with a specified
* array of command-line options.
*
* @layer<antDerive>
*/
public boolean processFiles( String[] sources, String[] options )
throws BuildException {
// Form total argument list by concatenating sources with options:
//
String[] args = new String [sources.length + options.length] ;
System.arraycopy( sources,0, args,0, sources.length ) ;
System.arraycopy( options,0, args,sources.length, options.length ) ;
try {
Main.main( args ) ;
return true ;
}
catch ( BuildException exception ) {
throw exception ;
}
catch ( Exception exception ) {
log( exception.toString(), Project.MSG_ERR ) ;
return false ;
}
}
/**
* If true and if errors occur during derivation, aborts the enclosing
* build at the end of the task.
*
* @layer<antDerive>
*/
public void setFailonerror( boolean fail ) {
failOnError = fail ;
}
/**
* If true, list the source files to be handed to the tool.
*
* @layer<antDerive>
*/
public void setListfiles( boolean list ) {
listFiles = list ;
}
/**
* If true, throws a build error if no source files are found for the
* tool. If false and there are no source files, this task just exits
* without invoking the tool.
*
* @layer<antDerive>
*/
public void setErrorifnofiles( boolean errorIfNoFiles ) {
this.errorIfNoFiles = errorIfNoFiles ;
}
/**
* An alternative way to specify a source search path.
* @see #createSrc()
*
* @layer<antDerive>
*/
public void setSrcdir( Path srcDir ) {
if ( sourcePath == null )
sourcePath = srcDir ;
else
sourcePath.append( srcDir ) ;
}
/**
* Specifies a timeout on the time to derive from a given file.
*
* @layer<antDerive>
*/
public void setTimeout( Long interval ) {
timeOut = interval ;
}
protected Commandline command = new Commandline() ;
private boolean errorIfNoFiles = true ;
private boolean failOnError = false ;
private boolean listFiles = false ;
private Path sourcePath = null ;
private Long timeOut = null ;
}