diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
index 9d0c206de..a94f957b8 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
@@ -1,59 +1,60 @@
/*
- * The Apache Software License, Version 1.1
+ * The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
- * reserved.
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
*
- * 3. The end-user documentation included with the redistribution, if
- * any, must include the following acknowlegement:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowlegement may appear in the software itself,
- * if and wherever such third-party acknowlegements normally appear.
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
*
- * 4. The names "The Jakarta Project", "Ant", and "Apache Software
- * Foundation" must not be used to endorse or promote products derived
- * from this software without prior written permission. For written
- * permission, please contact apache@apache.org.
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
*
- * 5. Products derived from this software may not be called "Apache"
- * nor may "Apache" appear in their names without prior written
- * permission of the Apache Group.
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
*
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
*
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * .
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
*/
package org.apache.ant.antcore.execution;
import java.io.File;
import java.net.MalformedURLException;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.modelparser.XMLProjectParser;
@@ -73,8 +74,13 @@ import org.apache.ant.init.LoaderUtils;
* @created 8 February 2002
*/
public class CoreExecService implements ExecService {
+
/** The Frame this service instance is working for */
private Frame frame;
+
+ /** A map of subbuild keys to the frame of the subbuild. */
+ private Map subBuilds = new HashMap();
+
/**
* Constructor
@@ -85,82 +91,38 @@ public class CoreExecService implements ExecService {
this.frame = frame;
}
- /**
- * Run a sub-build.
- *
- * @param antFile the file containing the XML description of the model
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- public void runBuild(File antFile, Map properties, List targets)
- throws ExecutionException {
- try {
- // Parse the build file into a project
- XMLProjectParser parser = new XMLProjectParser();
- Project project
- = parser.parseBuildFile(InitUtils.getFileURL(antFile));
- runBuild(project, properties, targets);
- } catch (MalformedURLException e) {
- throw new ExecutionException(e);
- } catch (XMLParseException e) {
- throw new ExecutionException(e);
- }
- }
-
- /**
- * Run a sub-build.
- *
- * @param model the project model to be used for the build
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- public void runBuild(Project model, Map properties, List targets)
- throws ExecutionException {
- Frame newFrame = frame.createFrame(model);
- newFrame.setInitialProperties(properties);
- newFrame.runBuild(targets);
- }
-
- /**
- * Run a sub-build using the current frame's project model
- *
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- public void callTarget(Map properties, List targets)
- throws ExecutionException {
- runBuild(frame.getProject(), properties, targets);
- }
/**
- * Execute a task. The task should have already been initialised by
- * the core. This is checked
+ * Execute a task. The task should have already been initialised by the
+ * core. This is checked
*
* @param task the task to be executed
* @exception ExecutionException if there is an execution problem
*/
public void executeTask(Task task) throws ExecutionException {
AntContext context = task.getAntContext();
+
if (!(context instanceof ExecutionContext)) {
throw new ExecutionException("The Task was not configured with an"
+ " appropriate context");
}
ExecutionContext execContext = (ExecutionContext) context;
-
+
frame.getEventSupport().fireTaskStarted(task);
+
Throwable failureCause = null;
+
try {
- ClassLoader currentLoader
- = LoaderUtils.setContextLoader(execContext.getClassLoader());
+ ClassLoader currentLoader
+ = LoaderUtils.setContextLoader(execContext.getClassLoader());
+
task.execute();
LoaderUtils.setContextLoader(currentLoader);
} catch (Throwable e) {
ExecutionException ee =
new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e);
+
failureCause = ee;
throw ee;
} finally {
@@ -168,6 +130,17 @@ public class CoreExecService implements ExecService {
}
}
+
+ /**
+ * Get the base directory for this execution of this frame
+ *
+ * @return the base directory
+ */
+ public File getBaseDir() {
+ return frame.getBaseDir();
+ }
+
+
/**
* get the name of the project associated with this execution.
*
@@ -177,13 +150,99 @@ public class CoreExecService implements ExecService {
return frame.getProjectName();
}
+
/**
- * Get the base directory for this execution of this frame
+ * Handle subbuild output.
*
- * @return the base directory
+ * @param subbuildKey the core's key for managing the subbuild.
+ * @param line the content produce by the current thread.
+ * @param isErr true if this content is from the thread's error stream.
*/
- public File getBaseDir() {
- return frame.getBaseDir();
+ public void handleBuildOutput(Object subbuildKey, String line,
+ boolean isErr) throws ExecutionException {
+ getSubbuildFrame(subbuildKey).threadOutput(line, isErr);
+ }
+
+
+ private Frame getSubbuildFrame(Object key) throws ExecutionException {
+ Frame subFrame = (Frame) subBuilds.get(key);
+
+ if (subFrame == null) {
+ throw new ExecutionException("Could not find execution frame "
+ + "for subbuild");
+ }
+ return subFrame;
+ }
+
+ /**
+ * Run a build which have been previously setup
+ *
+ * @param targets A list of targets to be run
+ * @param key Description of the Parameter
+ * @exception ExecutionException if the build cannot be run
+ */
+ public void runBuild(Object key, List targets) throws ExecutionException {
+ getSubbuildFrame(key).runBuild(targets);
+ subBuilds.remove(key);
+ }
+
+
+ /**
+ * Setup a sub-build.
+ *
+ * @param antFile the file containing the XML description of the model
+ * @param properties the initiali properties to be used in the build
+ * @return Description of the Return Value
+ * @exception ExecutionException if the subbuild cannot be run
+ */
+ public Object setupBuild(File antFile, Map properties)
+ throws ExecutionException {
+ try {
+ // Parse the build file into a project
+ XMLProjectParser parser = new XMLProjectParser();
+ Project project
+ = parser.parseBuildFile(InitUtils.getFileURL(antFile));
+
+ return setupBuild(project, properties);
+ } catch (MalformedURLException e) {
+ throw new ExecutionException(e);
+ } catch (XMLParseException e) {
+ throw new ExecutionException(e);
+ }
+ }
+
+
+ /**
+ * Setup a sub-build.
+ *
+ * @param model the project model to be used for the build
+ * @param properties the initiali properties to be used in the build
+ * @return Description of the Return Value
+ * @exception ExecutionException if the subbuild cannot be run
+ */
+ public Object setupBuild(Project model, Map properties)
+ throws ExecutionException {
+ Frame newFrame = frame.createFrame(model);
+
+ newFrame.setInitialProperties(properties);
+
+ Object key = new Object();
+
+ subBuilds.put(key, newFrame);
+ return key;
+ }
+
+
+ /**
+ * Setup a sub-build using the current frame's project model
+ *
+ * @param properties the initiali properties to be used in the build
+ * @return Description of the Return Value
+ * @exception ExecutionException if the subbuild cannot be run
+ */
+ public Object setupBuild(Map properties)
+ throws ExecutionException {
+ return setupBuild(frame.getProject(), properties);
}
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
index 51f11dc1f..1bbf53a09 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
@@ -84,8 +84,8 @@ import org.apache.ant.init.InitConfig;
* contains the data values set by Ant tasks as they are executed, including
* task definitions, property values, etc.
*
- * @author Conor MacNeill
- * @created 14 January 2002
+ * @author Conor MacNeill
+ * @created 14 January 2002
*/
public class Frame implements DemuxOutputReceiver {
/** the base dir of the project */
@@ -151,12 +151,11 @@ public class Frame implements DemuxOutputReceiver {
/**
* Create an Execution Frame for the given project
*
- * @param standardLibs The libraries of tasks and types
- * available to this frame
- * @param config the user config to use for this
- * execution of Ant
- * @param initConfig Ant's initialisation config
- * @exception ExecutionException if a component of the library cannot be
+ * @param standardLibs The libraries of tasks and types available to this
+ * frame
+ * @param config the user config to use for this execution of Ant
+ * @param initConfig Ant's initialisation config
+ * @exception ExecutionException if a component of the library cannot be
* imported
*/
protected Frame(Map standardLibs, InitConfig initConfig,
@@ -171,11 +170,9 @@ public class Frame implements DemuxOutputReceiver {
* Replace ${} style constructions in the given value with the string
* value of the corresponding data values in the frame
*
- * @param value the string to be scanned for property
- * references.
- * @return the string with all property references
- * replaced
- * @exception ExecutionException if any of the properties do not exist
+ * @param value the string to be scanned for property references.
+ * @return the string with all property references replaced
+ * @exception ExecutionException if any of the properties do not exist
*/
public String replacePropertyRefs(String value) throws ExecutionException {
return dataService.replacePropertyRefs(value);
@@ -185,15 +182,15 @@ public class Frame implements DemuxOutputReceiver {
/**
* Sets the Project of the Frame
*
- * @param project The new Project value
- * @exception ExecutionException if any required sub-frames cannot be
+ * @param project The new Project value
+ * @exception ExecutionException if any required sub-frames cannot be
* created and configured
*/
protected void setProject(Project project) throws ExecutionException {
this.project = project;
referencedFrames = new HashMap();
- for (Iterator i = project.getReferencedProjectNames(); i.hasNext();) {
+ for (Iterator i = project.getReferencedProjectNames(); i.hasNext(); ) {
String referenceName = (String) i.next();
Project referencedProject
= project.getReferencedProject(referenceName);
@@ -211,7 +208,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* get the name of the project associated with this frame.
*
- * @return the project's name
+ * @return the project's name
*/
public String getProjectName() {
if (project != null) {
@@ -224,10 +221,10 @@ public class Frame implements DemuxOutputReceiver {
/**
* Set a value in this frame or any of its imported frames.
*
- * @param name the name of the value
- * @param value the actual value
- * @param mutable if true, existing values can be changed
- * @exception ExecutionException if the value name is invalid
+ * @param name the name of the value
+ * @param value the actual value
+ * @param mutable if true, existing values can be changed
+ * @exception ExecutionException if the value name is invalid
*/
protected void setDataValue(String name, Object value, boolean mutable)
throws ExecutionException {
@@ -253,9 +250,9 @@ public class Frame implements DemuxOutputReceiver {
/**
* Set the initial properties to be used when the frame starts execution
*
- * @param properties a Map of named properties which may in
- * fact be any object
- * @exception ExecutionException if the properties cannot be set
+ * @param properties a Map of named properties which may in fact be any
+ * object
+ * @exception ExecutionException if the properties cannot be set
*/
protected void setInitialProperties(Map properties)
throws ExecutionException {
@@ -271,7 +268,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* Set the values of various magic properties
*
- * @exception ExecutionException if the properties cannot be set
+ * @exception ExecutionException if the properties cannot be set
*/
protected void setMagicProperties() throws ExecutionException {
URL antHomeURL = initConfig.getAntHome();
@@ -291,11 +288,10 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get a definition from a referenced frame
*
- * @param definitionName the name of the definition relative to
- * this frame
- * @return the appropriate import info object from
- * the referenced frame's imports
- * @exception ExecutionException if the referenced definition cannot be
+ * @param definitionName the name of the definition relative to this frame
+ * @return the appropriate import info object from the referenced frame's
+ * imports
+ * @exception ExecutionException if the referenced definition cannot be
* found
*/
protected ImportInfo getReferencedDefinition(String definitionName)
@@ -318,7 +314,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* Gets the project model this frame is working with
*
- * @return the project model
+ * @return the project model
*/
protected Project getProject() {
return project;
@@ -330,7 +326,7 @@ public class Frame implements DemuxOutputReceiver {
* is an expensive operation since it must clone all of the property
* stores in all frames
*
- * @return a Map containing the frames properties indexed by their full
+ * @return a Map containing the frames properties indexed by their full
* name.
*/
protected Map getAllProperties() {
@@ -359,7 +355,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get the Ant initialization configuration for this frame.
*
- * @return Ant's initialization configuration
+ * @return Ant's initialization configuration
*/
protected InitConfig getInitConfig() {
return initConfig;
@@ -369,7 +365,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get the config instance being used by this frame.
*
- * @return the config associated with this frame.
+ * @return the config associated with this frame.
*/
protected AntConfig getConfig() {
return config;
@@ -379,11 +375,10 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get the core's implementation of the given service interface.
*
- * @param serviceInterfaceClass the service interface for which an
+ * @param serviceInterfaceClass the service interface for which an
* implementation is require
- * @return the core's implementation of the service
- * interface
- * @exception ExecutionException if the core does not provide an
+ * @return the core's implementation of the service interface
+ * @exception ExecutionException if the core does not provide an
* implementatin of the requested interface
*/
protected Object getCoreService(Class serviceInterfaceClass)
@@ -402,7 +397,7 @@ public class Frame implements DemuxOutputReceiver {
* Get the EventSupport instance for this frame. This tracks the build
* listeners on this frame
*
- * @return the EventSupport instance
+ * @return the EventSupport instance
*/
protected BuildEventSupport getEventSupport() {
return eventSupport;
@@ -412,7 +407,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* Gets the baseDir of the Frame
*
- * @return the baseDir value
+ * @return the baseDir value
*/
protected File getBaseDir() {
return baseDir;
@@ -422,9 +417,9 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get a referenced frame by its reference name
*
- * @param referenceName the name under which the frame was imported.
- * @return the Frame asscociated with the given reference
- * name or null if there is no such project.
+ * @param referenceName the name under which the frame was imported.
+ * @return the Frame asscociated with the given reference name or null if
+ * there is no such project.
*/
protected Frame getReferencedFrame(String referenceName) {
return (Frame) referencedFrames.get(referenceName);
@@ -434,7 +429,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get the frames representing referenced projects.
*
- * @return an iterator which returns the referenced ExeuctionFrames..
+ * @return an iterator which returns the referenced ExeuctionFrames..
*/
protected Iterator getReferencedFrames() {
return referencedFrames.values().iterator();
@@ -444,8 +439,8 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get the name of an object in its frame
*
- * @param fullname The name of the object
- * @return the name of the object within its containing frame
+ * @param fullname The name of the object
+ * @return the name of the object within its containing frame
*/
protected String getNameInFrame(String fullname) {
int index = fullname.lastIndexOf(Project.REF_DELIMITER);
@@ -460,11 +455,10 @@ public class Frame implements DemuxOutputReceiver {
/**
* Get a value from this frame or any imported frame
*
- * @param name the name of the data value - may contain
- * reference delimiters
- * @return the data value fetched from the
- * appropriate frame
- * @exception ExecutionException if the value is not defined
+ * @param name the name of the data value - may contain reference
+ * delimiters
+ * @return the data value fetched from the appropriate frame
+ * @exception ExecutionException if the value is not defined
*/
protected Object getDataValue(String name) throws ExecutionException {
Frame frame = getContainingFrame(name);
@@ -484,10 +478,10 @@ public class Frame implements DemuxOutputReceiver {
/**
* Indicate if a data value has been set
*
- * @param name the name of the data value - may contain
- * reference delimiters
- * @return true if the value exists
- * @exception ExecutionException if the containing frame for the value
+ * @param name the name of the data value - may contain reference
+ * delimiters
+ * @return true if the value exists
+ * @exception ExecutionException if the containing frame for the value
* does not exist
*/
protected boolean isDataValueSet(String name) throws ExecutionException {
@@ -509,9 +503,9 @@ public class Frame implements DemuxOutputReceiver {
* Get the execution frame which contains, directly, the named element
* where the name is relative to this frame
*
- * @param elementName The name of the element
- * @return the execution frame for the project that contains
- * the given target
+ * @param elementName The name of the element
+ * @return the execution frame for the project that contains the given
+ * target
*/
protected Frame getContainingFrame(String elementName) {
int index = elementName.lastIndexOf(Project.REF_DELIMITER);
@@ -541,12 +535,12 @@ public class Frame implements DemuxOutputReceiver {
/**
* Add a collection of properties to this frame
*
- * @param properties the collection of property values,
- * indexed by their names
- * @exception ExecutionException if the frame cannot be created.
+ * @param properties the collection of property values, indexed by their
+ * names
+ * @exception ExecutionException if the frame cannot be created.
*/
protected void addProperties(Map properties) throws ExecutionException {
- for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
+ for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) {
String name = (String) i.next();
Object value = properties.get(name);
@@ -558,10 +552,9 @@ public class Frame implements DemuxOutputReceiver {
/**
* Create a new frame for a given project
*
- * @param project the project model the frame will deal
- * with
- * @return an Frame ready to build the project
- * @exception ExecutionException if the frame cannot be created.
+ * @param project the project model the frame will deal with
+ * @return an Frame ready to build the project
+ * @exception ExecutionException if the frame cannot be created.
*/
protected Frame createFrame(Project project)
throws ExecutionException {
@@ -569,7 +562,7 @@ public class Frame implements DemuxOutputReceiver {
= new Frame(standardLibs, initConfig, config);
newFrame.setProject(project);
- for (Iterator j = eventSupport.getListeners(); j.hasNext();) {
+ for (Iterator j = eventSupport.getListeners(); j.hasNext(); ) {
BuildListener listener = (BuildListener) j.next();
newFrame.addBuildListener(listener);
@@ -581,8 +574,8 @@ public class Frame implements DemuxOutputReceiver {
/**
* Log a message as a build event
*
- * @param message the message to be logged
- * @param level the priority level of the message
+ * @param message the message to be logged
+ * @param level the priority level of the message
*/
protected void log(String message, int level) {
eventSupport.fireMessageLogged(project, message, level);
@@ -592,10 +585,10 @@ public class Frame implements DemuxOutputReceiver {
/**
* Add a build listener to this execution frame
*
- * @param listener the listener to be added to the frame
+ * @param listener the listener to be added to the frame
*/
protected void addBuildListener(BuildListener listener) {
- for (Iterator i = getReferencedFrames(); i.hasNext();) {
+ for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame referencedFrame = (Frame) i.next();
referencedFrame.addBuildListener(listener);
@@ -607,10 +600,10 @@ public class Frame implements DemuxOutputReceiver {
/**
* Remove a build listener from the execution
*
- * @param listener the listener to be removed
+ * @param listener the listener to be removed
*/
protected void removeBuildListener(BuildListener listener) {
- for (Iterator i = getReferencedFrames(); i.hasNext();) {
+ for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame subFrame = (Frame) i.next();
subFrame.removeBuildListener(listener);
@@ -622,9 +615,8 @@ public class Frame implements DemuxOutputReceiver {
/**
* Run the given list of targets
*
- * @param targets a list of target names which are to be
- * evaluated
- * @exception ExecutionException if there is a problem in the build
+ * @param targets a list of target names which are to be evaluated
+ * @exception ExecutionException if there is a problem in the build
*/
protected void runBuild(List targets) throws ExecutionException {
determineBaseDirs();
@@ -640,7 +632,7 @@ public class Frame implements DemuxOutputReceiver {
executeTarget(defaultTarget);
}
} else {
- for (Iterator i = targets.iterator(); i.hasNext();) {
+ for (Iterator i = targets.iterator(); i.hasNext(); ) {
String targetName = (String) i.next();
log("Executing target: " + targetName, MessageLevel.MSG_DEBUG);
@@ -653,10 +645,9 @@ public class Frame implements DemuxOutputReceiver {
/**
* Execute the tasks of a target in this frame with the given name
*
- * @param targetName the name of the target whose tasks will
- * be evaluated
- * @exception ExecutionException if there is a problem executing the
- * tasks of the target
+ * @param targetName the name of the target whose tasks will be evaluated
+ * @exception ExecutionException if there is a problem executing the tasks
+ * of the target
*/
protected void executeTarget(String targetName) throws ExecutionException {
// to execute a target we must determine its dependencies and
@@ -666,7 +657,7 @@ public class Frame implements DemuxOutputReceiver {
// firstly build a list of fully qualified target names to execute.
List dependencyOrder = project.getTargetDependencies(targetName);
- for (Iterator i = dependencyOrder.iterator(); i.hasNext();) {
+ for (Iterator i = dependencyOrder.iterator(); i.hasNext(); ) {
String fullTargetName = (String) i.next();
Frame frame = getContainingFrame(fullTargetName);
String localTargetName = getNameInFrame(fullTargetName);
@@ -682,8 +673,8 @@ public class Frame implements DemuxOutputReceiver {
/**
* Run the tasks returned by the given iterator
*
- * @param taskIterator the iterator giving the tasks to execute
- * @exception ExecutionException if there is execution problem while
+ * @param taskIterator the iterator giving the tasks to execute
+ * @exception ExecutionException if there is execution problem while
* executing tasks
*/
protected void executeTasks(Iterator taskIterator)
@@ -727,9 +718,9 @@ public class Frame implements DemuxOutputReceiver {
* Execute the given target's tasks. The target must be local to this
* frame's project
*
- * @param targetName the name of the target within this frame
- * that is to be executed.
- * @exception ExecutionException if there is a problem executing tasks
+ * @param targetName the name of the target within this frame that is to
+ * be executed.
+ * @exception ExecutionException if there is a problem executing tasks
*/
protected void executeTargetTasks(String targetName)
throws ExecutionException {
@@ -778,11 +769,11 @@ public class Frame implements DemuxOutputReceiver {
/**
* Initialize the frame by executing the project level tasks if any
*
- * @exception ExecutionException if the top level tasks of the frame
+ * @exception ExecutionException if the top level tasks of the frame
* failed
*/
protected void initialize() throws ExecutionException {
- for (Iterator i = getReferencedFrames(); i.hasNext();) {
+ for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame referencedFrame = (Frame) i.next();
referencedFrame.initialize();
@@ -797,7 +788,7 @@ public class Frame implements DemuxOutputReceiver {
/**
* Determine the base directory for each frame in the frame hierarchy
*
- * @exception ExecutionException if the base directories cannot be
+ * @exception ExecutionException if the base directories cannot be
* determined
*/
private void determineBaseDirs() throws ExecutionException {
@@ -825,7 +816,7 @@ public class Frame implements DemuxOutputReceiver {
}
setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true);
- for (Iterator i = getReferencedFrames(); i.hasNext();) {
+ for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame refFrame = (Frame) i.next();
refFrame.determineBaseDirs();
@@ -859,8 +850,8 @@ public class Frame implements DemuxOutputReceiver {
* the thread producing the content. The content is broken up into
* separate lines
*
- * @param line the content produce by the current thread.
- * @param isErr true if this content is from the thread's error stream.
+ * @param line the content produce by the current thread.
+ * @param isErr true if this content is from the thread's error stream.
*/
public void threadOutput(String line, boolean isErr) {
eventSupport.threadOutput(line, isErr);
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
index 6d42294fe..64d5b63c5 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
@@ -105,11 +105,8 @@ public class Ant extends AntBase {
* @exception ExecutionException if the build can't be run
*/
public void execute() throws ExecutionException {
- System.out.println("Starting Ant Task");
if (baseDir == null) {
- ExecService execService
- = (ExecService) getCoreService(ExecService.class);
- baseDir = execService.getBaseDir();
+ baseDir = getExecService().getBaseDir();
}
File antFile = null;
@@ -125,11 +122,9 @@ public class Ant extends AntBase {
setProperty(MagicProperties.BASEDIR, baseDir.getAbsolutePath());
- ExecService execService
- = (ExecService) getCoreService(ExecService.class);
-
- execService.runBuild(antFile, getProperties(), getTargets());
- System.out.println("Ending Ant Task");
+ Object key = getExecService().setupBuild(antFile, getProperties());
+ setSubBuildKey(key);
+ getExecService().runBuild(key, getTargets());
}
}
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
index 8731f2f42..7860df2ba 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
@@ -1,55 +1,55 @@
/*
- * The Apache Software License, Version 1.1
+ * The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
- * reserved.
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
*
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
*
- * 3. The end-user documentation included with the redistribution, if
- * any, must include the following acknowlegement:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowlegement may appear in the software itself,
- * if and wherever such third-party acknowlegements normally appear.
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
*
- * 4. The names "The Jakarta Project", "Ant", and "Apache Software
- * Foundation" must not be used to endorse or promote products derived
- * from this software without prior written permission. For written
- * permission, please contact apache@apache.org.
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
*
- * 5. Products derived from this software may not be called "Apache"
- * nor may "Apache" appear in their names without prior written
- * permission of the Apache Group.
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
*
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
*
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * .
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
*/
package org.apache.ant.antlib.system;
import java.util.ArrayList;
@@ -60,6 +60,7 @@ import org.apache.ant.common.antlib.AbstractComponent;
import org.apache.ant.common.antlib.AbstractTask;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.service.DataService;
+import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
/**
@@ -85,46 +86,49 @@ public abstract class AntBase extends AbstractTask {
/**
- * Sets the name of the Property
+ * Gets the name of the Property
*
- * @param name the new name value
+ * @return the name value
*/
- public void setName(String name) {
- this.name = name;
+ public String getName() {
+ return name;
}
+
/**
- * Sets the value of the Property
+ * Gets the value of the Property
*
- * @param value the new value value
+ * @return the value value
*/
- public void setValue(String value) {
- this.value = value;
+ public String getValue() {
+ return value;
}
+
/**
- * Gets the name of the Property
+ * Sets the name of the Property
*
- * @return the name value
+ * @param name the new name value
*/
- public String getName() {
- return name;
+ public void setName(String name) {
+ this.name = name;
}
+
/**
- * Gets the value of the Property
+ * Sets the value of the Property
*
- * @return the value value
+ * @param value the new value value
*/
- public String getValue() {
- return value;
+ public void setValue(String value) {
+ this.value = value;
}
+
/**
* Validate this data type instance
*
- * @exception ExecutionException if either attribute has not been
- * set
+ * @exception ExecutionException if either attribute has not been set
*/
public void validateComponent() throws ExecutionException {
if (name == null) {
@@ -138,6 +142,7 @@ public abstract class AntBase extends AbstractTask {
}
}
+
/**
* A simple class to store information about references being passed
*
@@ -150,42 +155,47 @@ public abstract class AntBase extends AbstractTask {
/** The id to be used in the sub-build for this reference */
private String toId;
+
/**
- * Sets the refId of the Reference
+ * Gets the refId of the Reference
*
- * @param refId the new refId value
+ * @return the refId value
*/
- public void setRefId(String refId) {
- this.refId = refId;
+ public String getRefId() {
+ return refId;
}
+
/**
- * Sets the toId of the Reference
+ * Gets the toId of the Reference
*
- * @param toId the new toId value
+ * @return the toId value
*/
- public void setToId(String toId) {
- this.toId = toId;
+ public String getToId() {
+ return toId;
}
+
/**
- * Gets the refId of the Reference
+ * Sets the refId of the Reference
*
- * @return the refId value
+ * @param refId the new refId value
*/
- public String getRefId() {
- return refId;
+ public void setRefId(String refId) {
+ this.refId = refId;
}
+
/**
- * Gets the toId of the Reference
+ * Sets the toId of the Reference
*
- * @return the toId value
+ * @param toId the new toId value
*/
- public String getToId() {
- return toId;
+ public void setToId(String toId) {
+ this.toId = toId;
}
+
/**
* Validate this data type instance
*
@@ -200,68 +210,36 @@ public abstract class AntBase extends AbstractTask {
}
}
- /** The name of the target to be evaluated in the sub-build */
- private String targetName;
+ /** The core's data service for manipulating the properties */
+ private DataService dataService;
+
+ /** The core's ExecutionService for running builds and external programs */
+ private ExecService execService;
+
/**
- * flag which indicates if all current properties should be passed to
- * the subbuild
+ * flag which indicates if all current properties should be passed to the
+ * subbuild
*/
private boolean inheritAll = true;
/**
- * flag which indicates if all current references should be passed to
- * the subbuild
+ * flag which indicates if all current references should be passed to the
+ * subbuild
*/
private boolean inheritRefs = false;
/** The properties which will be passed to the sub-build */
private Map properties = new HashMap();
- /** The core's data service for manipulating the properties */
- private DataService dataService;
-
/**
- * Sets the target to be executed in the subbuild
- *
- * @param targetName the name of the target to build
+ * The key to the subbuild with which the Ant task can manage the subbuild
*/
- public void setTarget(String targetName) {
- this.targetName = targetName;
- }
-
- /**
- * Indicate if all properties should be passed
- *
- * @param inheritAll true if all properties should be passed
- */
- public void setInheritAll(boolean inheritAll) {
- this.inheritAll = inheritAll;
- }
+ private Object subbuildKey;
- /**
- * Indicate if all references are to be passed to the subbuild
- *
- * @param inheritRefs true if the sub-build should be given all the
- * current references
- */
- public void setInheritRefs(boolean inheritRefs) {
- this.inheritRefs = inheritRefs;
- }
+ /** The name of the target to be evaluated in the sub-build */
+ private String targetName;
- /**
- * Initialise this task
- *
- * @param context core's context
- * @param componentType the component type of this component (i.e its
- * defined name in the build file)
- * @exception ExecutionException if we can't access the data service
- */
- public void init(AntContext context, String componentType)
- throws ExecutionException {
- super.init(context, componentType);
- dataService = (DataService) getCoreService(DataService.class);
- }
/**
* Add a property to be passed to the subbuild
@@ -272,6 +250,7 @@ public abstract class AntBase extends AbstractTask {
properties.put(property.getName(), property.getValue());
}
+
/**
* Add a reference to be passed
*
@@ -281,11 +260,13 @@ public abstract class AntBase extends AbstractTask {
*/
public void addReference(Reference reference) throws ExecutionException {
String refId = reference.getRefId();
+
if (!dataService.isDataValueSet(refId)) {
throw new ExecutionException("RefId \"" + refId + "\" is not set");
}
Object value = dataService.getDataValue(refId);
String toId = reference.getToId();
+
if (toId == null) {
toId = refId;
}
@@ -293,16 +274,35 @@ public abstract class AntBase extends AbstractTask {
properties.put(toId, value);
}
+
/**
- * Set a property for the subbuild
+ * Get the core's execution service
*
- * @param propertyName the property name
- * @param propertyValue the value of the property
+ * @return the core's execution service.
*/
- protected void setProperty(String propertyName, Object propertyValue) {
- properties.put(propertyName, propertyValue);
+ protected ExecService getExecService() {
+ return execService;
+ }
+
+
+ /**
+ * Get the properties to be used with the sub-build
+ *
+ * @return the properties the sub-build will start with
+ */
+ protected Map getProperties() {
+ if (!inheritAll) {
+ return properties;
+ }
+
+ // need to combine existing properties with new ones
+ Map subBuildProperties = dataService.getAllProperties();
+
+ subBuildProperties.putAll(properties);
+ return subBuildProperties;
}
+
/**
* Get the list of targets to be executed
*
@@ -310,27 +310,112 @@ public abstract class AntBase extends AbstractTask {
*/
protected List getTargets() {
List targets = new ArrayList();
+
if (targetName != null) {
targets.add(targetName);
}
return targets;
}
+
/**
- * Get the properties to be used with the sub-build
+ * Handle error information produced by the task. When a task prints to
+ * System.err the container may catch this and redirect the content back
+ * to the task by invoking this method. This method must NOT call
+ * System.err, directly or indirectly.
*
- * @return the properties the sub-build will start with
+ * @param line The line of error info produce by the task
*/
- protected Map getProperties() {
- if (!inheritAll) {
- return properties;
+ public void handleSystemErr(String line) {
+ if (subbuildKey == null) {
+ super.handleSystemErr(line);
+ } else {
}
+ }
- // need to combine existing properties with new ones
- Map subBuildProperties = dataService.getAllProperties();
- subBuildProperties.putAll(properties);
- return subBuildProperties;
+
+ /**
+ * Handle Output produced by the task. When a task prints to System.out
+ * the container may catch this and redirect the content back to the task
+ * by invoking this method. This method must NOT call System.out, directly
+ * or indirectly.
+ *
+ * @param line The line of content produce by the task
+ */
+ public void handleSystemOut(String line) {
+ if (subbuildKey == null) {
+ super.handleSystemOut(line);
+ } else {
+ }
}
+
+ /**
+ * Initialise this task
+ *
+ * @param context core's context
+ * @param componentType the component type of this component (i.e its
+ * defined name in the build file)
+ * @exception ExecutionException if we can't access the data service
+ */
+ public void init(AntContext context, String componentType)
+ throws ExecutionException {
+ super.init(context, componentType);
+ dataService = (DataService) getCoreService(DataService.class);
+ execService = (ExecService) getCoreService(ExecService.class);
+
+ }
+
+
+ /**
+ * Indicate if all properties should be passed
+ *
+ * @param inheritAll true if all properties should be passed
+ */
+ public void setInheritAll(boolean inheritAll) {
+ this.inheritAll = inheritAll;
+ }
+
+
+ /**
+ * Indicate if all references are to be passed to the subbuild
+ *
+ * @param inheritRefs true if the sub-build should be given all the
+ * current references
+ */
+ public void setInheritRefs(boolean inheritRefs) {
+ this.inheritRefs = inheritRefs;
+ }
+
+
+ /**
+ * Set a property for the subbuild
+ *
+ * @param propertyName the property name
+ * @param propertyValue the value of the property
+ */
+ protected void setProperty(String propertyName, Object propertyValue) {
+ properties.put(propertyName, propertyValue);
+ }
+
+
+ /**
+ * Set the key of the subbuild
+ *
+ * @param key the key returned by the Ant core for managing the subbuild
+ */
+ protected void setSubBuildKey(Object key) {
+ this.subbuildKey = key;
+ }
+
+
+ /**
+ * Sets the target to be executed in the subbuild
+ *
+ * @param targetName the name of the target to build
+ */
+ public void setTarget(String targetName) {
+ this.targetName = targetName;
+ }
}
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
index f74fb6d03..b118cfdf3 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
@@ -69,12 +69,12 @@ public class AntCall extends AntBase {
* @exception ExecutionException if the build fails
*/
public void execute() throws ExecutionException {
- ExecService execService
- = (ExecService) getCoreService(ExecService.class);
setProperty(MagicProperties.BASEDIR,
- execService.getBaseDir().getAbsolutePath());
+ getExecService().getBaseDir().getAbsolutePath());
- execService.callTarget(getProperties(), getTargets());
+ Object key = getExecService().setupBuild(getProperties());
+ setSubBuildKey(key);
+ getExecService().runBuild(key, getTargets());
}
/**
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListenerAdapter.java b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListenerAdapter.java
new file mode 100644
index 000000000..9702d98ff
--- /dev/null
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListenerAdapter.java
@@ -0,0 +1,135 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.ant.common.event;
+
+/**
+ * Abstract adapter for build listeners which don't want to implement all of
+ * the BuildListener methods
+ *
+ * @author Conor MacNeill
+ * @created 9 April 2002
+ */
+public abstract class BuildListenerAdapter implements BuildListener {
+ /**
+ * Fired before any targets are started.
+ *
+ * @param event the build event for this notification
+ */
+ public void buildStarted(BuildEvent event) {
+ }
+
+
+ /**
+ * Fired after the last target has finished. This event will still be
+ * thrown if an error occured during the build.
+ *
+ * @param event the build event for this notification
+ */
+ public void buildFinished(BuildEvent event) {
+ }
+
+
+
+ /**
+ * Fired when a target is started.
+ *
+ * @param event the build event for this notification
+ */
+ public void targetStarted(BuildEvent event) {
+ }
+
+
+
+ /**
+ * Fired when a target has finished. This event will still be thrown if an
+ * error occured during the build.
+ *
+ * @param event the build event for this notification
+ */
+ public void targetFinished(BuildEvent event) {
+ }
+
+
+
+ /**
+ * Fired when a task is started.
+ *
+ * @param event the build event for this notification
+ */
+ public void taskStarted(BuildEvent event) {
+ }
+
+
+
+ /**
+ * Fired when a task has finished. This event will still be throw if an
+ * error occured during the build.
+ *
+ * @param event the build event for this notification
+ */
+ public void taskFinished(BuildEvent event) {
+ }
+
+
+
+ /**
+ * Fired whenever a message is logged.
+ *
+ * @param event the build event for this notification
+ */
+ public void messageLogged(BuildEvent event) {
+ }
+
+}
+
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
index 376eaff62..a00b96cd9 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
@@ -67,37 +67,46 @@ import org.apache.ant.common.util.ExecutionException;
*/
public interface ExecService {
/**
- * Run a sub-build.
+ * Setup a sub-build.
*
* @param antFile the file containing the XML description of the model
- * @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
+ * @exception ExecutionException if the subbuild cannot be setup
+ * @return a key to the build allowing it to be executed and managed
*/
- void runBuild(File antFile, Map properties, List targets)
+ Object setupBuild(File antFile, Map properties)
throws ExecutionException;
/**
- * Run a sub-build.
+ * Setup a sub-build.
*
* @param model the project model to be used for the build
- * @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
+ * @exception ExecutionException if the subbuild cannot be setup
+ * @return a key to the build allowing it to be executed and managed
*/
- void runBuild(Project model, Map properties, List targets)
+ Object setupBuild(Project model, Map properties)
throws ExecutionException;
/**
- * Run a sub-build using the current frame's project model
+ * Setup a sub-build using the current frame's project model
*
- * @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
+ * @exception ExecutionException if the subbuild cannot be setup
*/
- void callTarget(Map properties, List targets)
+ Object setupBuild(Map properties)
throws ExecutionException;
+ /**
+ * Run a build which have been previously setup
+ *
+ * @param buildKey the buildKey returned previously when the build was
+ * setup
+ * @param targets A list of targets to be run
+ * @exception ExecutionException if the build cannot be run
+ */
+ void runBuild(Object buildKey, List targets) throws ExecutionException;
+
/**
* execute a task. The task should have already been initialised by
* the core
@@ -120,5 +129,15 @@ public interface ExecService {
* @return the base directory for this execution of Ant
*/
File getBaseDir();
+
+ /**
+ * Handle subbuild output.
+ *
+ * @param subbuildKey the core's key for managing the subbuild.
+ * @param line the content produce by the current thread.
+ * @param isErr true if this content is from the thread's error stream.
+ */
+ void handleBuildOutput(Object subbuildKey, String line, boolean isErr)
+ throws ExecutionException;
}