FileDocCategorySizeDatePackage
SubAnt.javaAPI DocApache Ant 1.7019122Wed Dec 13 06:16:18 GMT 2006org.apache.tools.ant.taskdefs

SubAnt

public class SubAnt extends org.apache.tools.ant.Task
Calls a given target for all defined sub-builds. This is an extension of ant for bulk project execution.

Use with directories

subant can be used with directory sets to execute a build from different directories. 2 different options are offered

  • run the same build file /somepath/otherpath/mybuild.xml with different base directories use the genericantfile attribute
  • if you want to run directory1/build.xml, directory2/build.xml, .... use the antfile attribute. The base directory does not get set by the subant task in this case, because you can specify it in each build file.
since
Ant1.6
ant.task
name="subant" category="control"

Fields Summary
private org.apache.tools.ant.types.Path
buildpath
private Ant
ant
private String
subTarget
private String
antfile
private File
genericantfile
private boolean
verbose
private boolean
inheritAll
private boolean
inheritRefs
private boolean
failOnError
private String
output
private Vector
properties
private Vector
references
private Vector
propertySets
private Vector
targets
the targets to call on the new project
Constructors Summary
Methods Summary
public voidadd(org.apache.tools.ant.types.ResourceCollection rc)
Adds a resource collection to the implicit build path.

param
rc the resource collection to add.
since
Ant 1.7

        getBuildpath().add(rc);
    
public voidaddConfiguredTarget(org.apache.tools.ant.taskdefs.Ant.TargetElement t)
Add a target to this Ant invocation.

param
t the TargetElement to add.
since
Ant 1.7

        String name = t.getName();
        if ("".equals(name)) {
            throw new BuildException("target name must not be empty");
        }
        targets.add(t);
    
public voidaddDirset(org.apache.tools.ant.types.DirSet set)
Adds a directory set to the implicit build path.

Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!

param
set the directory set to add.

        add(set);
    
public voidaddFilelist(org.apache.tools.ant.types.FileList list)
Adds an ordered file list to the implicit build path.

Note that contrary to file and directory sets, file lists can reference non-existent files or directories!

param
list the file list to add.

        add(list);
    
public voidaddFileset(org.apache.tools.ant.types.FileSet set)
Adds a file set to the implicit build path.

Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!

param
set the file set to add.

        add(set);
    
public voidaddProperty(Property p)
Corresponds to <ant>'s nested <property> element.

param
p the property to pass on explicitly to the sub-build.

        properties.addElement(p);
    
public voidaddPropertyset(org.apache.tools.ant.types.PropertySet ps)
Corresponds to <ant>'s nested <propertyset> element.

param
ps the propertset

        propertySets.addElement(ps);
    
public voidaddReference(Ant.Reference r)
Corresponds to <ant>'s nested <reference> element.

param
r the reference to pass on explicitly to the sub-build.

        references.addElement(r);
    
private static voidcopyProperty(Property to, Property from)
Assigns an Ant property to another.

param
to the destination property whose content is modified.
param
from the source property whose content is copied.

        to.setName(from.getName());

        if (from.getValue() != null) {
            to.setValue(from.getValue());
        }
        if (from.getFile() != null) {
            to.setFile(from.getFile());
        }
        if (from.getResource() != null) {
            to.setResource(from.getResource());
        }
        if (from.getPrefix() != null) {
            to.setPrefix(from.getPrefix());
        }
        if (from.getRefid() != null) {
            to.setRefid(from.getRefid());
        }
        if (from.getEnvironment() != null) {
            to.setEnvironment(from.getEnvironment());
        }
        if (from.getClasspath() != null) {
            to.setClasspath(from.getClasspath());
        }
    
private AntcreateAntTask(java.io.File directory)
Creates the <ant> task configured to run a specific target.

param
directory : if not null the directory where the build should run
return
the ant task, configured with the explicit properties and references necessary to run the sub-build.

        Ant antTask = new Ant(this);
        antTask.init();
        if (subTarget != null && subTarget.length() > 0) {
            antTask.setTarget(subTarget);
        }


        if (output != null) {
            antTask.setOutput(output);
        }

        if (directory != null) {
            antTask.setDir(directory);
        }

        antTask.setInheritAll(inheritAll);
        for (Enumeration i = properties.elements(); i.hasMoreElements();) {
            copyProperty(antTask.createProperty(), (Property) i.nextElement());
        }

        for (Enumeration i = propertySets.elements(); i.hasMoreElements();) {
            antTask.addPropertyset((PropertySet) i.nextElement());
        }

        antTask.setInheritRefs(inheritRefs);
        for (Enumeration i = references.elements(); i.hasMoreElements();) {
            antTask.addReference((Ant.Reference) i.nextElement());
        }

        return antTask;
    
public org.apache.tools.ant.types.PathcreateBuildpath()
Creates a nested build path, and add it to the implicit build path.

return
the newly created nested build path.

        return getBuildpath().createPath();
    
public Path.PathElementcreateBuildpathElement()
Creates a nested <buildpathelement>, and add it to the implicit build path.

return
the newly created nested build path element.

        return getBuildpath().createPathElement();
    
public voidexecute()
Runs the various sub-builds.

        if (buildpath == null) {
            throw new BuildException("No buildpath specified");
        }

        final String[] filenames = buildpath.list();
        final int count = filenames.length;
        if (count < 1) {
            log("No sub-builds to iterate on", Project.MSG_WARN);
            return;
        }
/*
    //REVISIT: there must be cleaner way of doing this, if it is merited at all
        if (subTarget == null) {
            subTarget = getOwningTarget().getName();
        }
*/
        BuildException buildException = null;
        for (int i = 0; i < count; ++i) {
            File file = null;
            String subdirPath = null;
            Throwable thrownException = null;
            try {
                File directory = null;
                file = new File(filenames[i]);
                if (file.isDirectory()) {
                    if (verbose) {
                        subdirPath = file.getPath();
                        log("Entering directory: " + subdirPath + "\n", Project.MSG_INFO);
                    }
                    if (genericantfile != null) {
                        directory = file;
                        file = genericantfile;
                    } else {
                        file = new File(file, antfile);
                    }
                }
                execute(file, directory);
                if (verbose && subdirPath != null) {
                    log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
                }
            } catch (RuntimeException ex) {
                if (!(getProject().isKeepGoingMode())) {
                    if (verbose && subdirPath != null) {
                        log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
                    }
                    throw ex; // throw further
                }
                thrownException = ex;
            } catch (Throwable ex) {
                if (!(getProject().isKeepGoingMode())) {
                    if (verbose && subdirPath != null) {
                        log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
                    }
                    throw new BuildException(ex);
                }
                thrownException = ex;
            }
            if (thrownException != null) {
                if (thrownException instanceof BuildException) {
                    log("File '" + file
                        + "' failed with message '"
                        + thrownException.getMessage() + "'.", Project.MSG_ERR);
                    // only the first build exception is reported
                    if (buildException == null) {
                        buildException = (BuildException) thrownException;
                    }
                } else {
                    log("Target '" + file
                        + "' failed with message '"
                        + thrownException.getMessage() + "'.", Project.MSG_ERR);
                    thrownException.printStackTrace(System.err);
                    if (buildException == null) {
                        buildException =
                            new BuildException(thrownException);
                    }
                }
                if (verbose && subdirPath != null) {
                    log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
                }
            }
        }
        // check if one of the builds failed in keep going mode
        if (buildException != null) {
            throw buildException;
        }
    
private voidexecute(java.io.File file, java.io.File directory)
Runs the given target on the provided build file.

param
file the build file to execute
param
directory the directory of the current iteration
throws
BuildException is the file cannot be found, read, is a directory, or the target called failed, but only if failOnError is true. Otherwise, a warning log message is simply output.

        if (!file.exists() || file.isDirectory() || !file.canRead()) {
            String msg = "Invalid file: " + file;
            if (failOnError) {
                throw new BuildException(msg);
            }
            log(msg, Project.MSG_WARN);
            return;
        }

        ant = createAntTask(directory);
        String antfilename = file.getAbsolutePath();
        ant.setAntfile(antfilename);
        for (int i = 0; i < targets.size(); i++) {
            TargetElement targetElement = (TargetElement) targets.get(i);
            ant.addConfiguredTarget(targetElement);
        }

        try {
            ant.execute();
        } catch (BuildException e) {
            if (failOnError) {
                throw e;
            }
            log("Failure for target '" + subTarget
               + "' of: " +  antfilename + "\n"
               + e.getMessage(), Project.MSG_WARN);
        } catch (Throwable e) {
            if (failOnError) {
                throw new BuildException(e);
            }
            log("Failure for target '" + subTarget
                + "' of: " + antfilename + "\n"
                + e.toString(),
                Project.MSG_WARN);
        } finally {
            ant = null;
        }
    
private org.apache.tools.ant.types.PathgetBuildpath()
Gets the implicit build path, creating it if null.

return
the implicit build path.

        if (buildpath == null) {
            buildpath = new Path(getProject());
        }
        return buildpath;
    
public voidhandleErrorFlush(java.lang.String output)
Pass output sent to System.err to the new project.

param
output The error output to log. Should not be null.
since
Ant 1.6.2

        if (ant != null) {
            ant.handleErrorFlush(output);
        } else {
            super.handleErrorFlush(output);
        }
    
public voidhandleErrorOutput(java.lang.String output)
Pass output sent to System.err to the new project.

param
output The error output to log. Should not be null.
since
Ant 1.6.2

        if (ant != null) {
            ant.handleErrorOutput(output);
        } else {
            super.handleErrorOutput(output);
        }
    
public voidhandleFlush(java.lang.String output)
Pass output sent to System.out to the new project.

param
output The output to log. Should not be null.
since
Ant 1.6.2

        if (ant != null) {
            ant.handleFlush(output);
        } else {
            super.handleFlush(output);
        }
    
public inthandleInput(byte[] buffer, int offset, int length)
Process input into the ant task

param
buffer the buffer into which data is to be read.
param
offset the offset into the buffer at which data is stored.
param
length the amount of data to read
return
the number of bytes read
exception
IOException if the data cannot be read
see
Task#handleInput(byte[], int, int)
since
Ant 1.6.2

        if (ant != null) {
            return ant.handleInput(buffer, offset, length);
        } else {
            return super.handleInput(buffer, offset, length);
        }
    
public voidhandleOutput(java.lang.String output)
Pass output sent to System.out to the new project.

param
output a line of output
since
Ant 1.6.2


                           
        
        if (ant != null) {
            ant.handleOutput(output);
        } else {
            super.handleOutput(output);
        }
    
public voidsetAntfile(java.lang.String antfile)
This method builds the file name to use in conjunction with directories.

Defaults to "build.xml". If genericantfile is set, this attribute is ignored.

param
antfile the short build file name. Defaults to "build.xml".

        this.antfile = antfile;
    
public voidsetBuildpath(org.apache.tools.ant.types.Path s)
Set the buildpath to be used to find sub-projects.

param
s an Ant Path object containing the buildpath.

        getBuildpath().append(s);
    
public voidsetBuildpathRef(org.apache.tools.ant.types.Reference r)
Buildpath to use, by reference.

param
r a reference to an Ant Path object containing the buildpath.

        createBuildpath().setRefid(r);
    
public voidsetFailonerror(boolean failOnError)
Sets whether to fail with a build exception on error, or go on.

param
failOnError the new value for this boolean flag.

        this.failOnError = failOnError;
    
public voidsetGenericAntfile(java.io.File afile)
This method builds a file path to use in conjunction with directories.

Use genericantfile, in order to run the same build file with different basedirs.

If this attribute is set, antfile is ignored.

param
afile (path of the generic ant file, absolute or relative to project base directory)

        this.genericantfile = afile;
    
public voidsetInheritall(boolean b)
Corresponds to <ant>'s inheritall attribute.

param
b the new value for this boolean flag.

        this.inheritAll = b;
    
public voidsetInheritrefs(boolean b)
Corresponds to <ant>'s inheritrefs attribute.

param
b the new value for this boolean flag.

        this.inheritRefs = b;
    
public voidsetOutput(java.lang.String s)
Corresponds to <ant>'s output attribute.

param
s the filename to write the output to.

        this.output = s;
    
public voidsetTarget(java.lang.String target)
The target to call on the different sub-builds. Set to "" to execute the default target.

param
target the target

        this.subTarget = target;
    
public voidsetVerbose(boolean on)
Enable/ disable verbose log messages showing when each sub-build path is entered/ exited. The default value is "false".

param
on true to enable verbose mode, false otherwise (default).

        this.verbose = on;