Browse Source

Output management

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272310 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 23 years ago
parent
commit
7fe322a216
7 changed files with 638 additions and 354 deletions
  1. +159
    -100
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
  2. +84
    -93
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
  3. +4
    -9
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
  4. +221
    -136
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
  5. +4
    -4
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
  6. +135
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListenerAdapter.java
  7. +31
    -12
      proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java

+ 159
- 100
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java View File

@@ -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
* <http://www.apache.org/>.
* 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
* <http://www.apache.org/>.
*/ */
package org.apache.ant.antcore.execution; package org.apache.ant.antcore.execution;
import java.io.File; import java.io.File;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.ant.antcore.modelparser.XMLProjectParser; import org.apache.ant.antcore.modelparser.XMLProjectParser;
@@ -73,8 +74,13 @@ import org.apache.ant.init.LoaderUtils;
* @created 8 February 2002 * @created 8 February 2002
*/ */
public class CoreExecService implements ExecService { public class CoreExecService implements ExecService {

/** The Frame this service instance is working for */ /** The Frame this service instance is working for */
private Frame frame; private Frame frame;
/** A map of subbuild keys to the frame of the subbuild. */
private Map subBuilds = new HashMap();



/** /**
* Constructor * Constructor
@@ -85,82 +91,38 @@ public class CoreExecService implements ExecService {
this.frame = frame; 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 * @param task the task to be executed
* @exception ExecutionException if there is an execution problem * @exception ExecutionException if there is an execution problem
*/ */
public void executeTask(Task task) throws ExecutionException { public void executeTask(Task task) throws ExecutionException {
AntContext context = task.getAntContext(); AntContext context = task.getAntContext();

if (!(context instanceof ExecutionContext)) { if (!(context instanceof ExecutionContext)) {
throw new ExecutionException("The Task was not configured with an" throw new ExecutionException("The Task was not configured with an"
+ " appropriate context"); + " appropriate context");
} }
ExecutionContext execContext = (ExecutionContext) context; ExecutionContext execContext = (ExecutionContext) context;

frame.getEventSupport().fireTaskStarted(task); frame.getEventSupport().fireTaskStarted(task);

Throwable failureCause = null; Throwable failureCause = null;

try { try {
ClassLoader currentLoader
= LoaderUtils.setContextLoader(execContext.getClassLoader());
ClassLoader currentLoader
= LoaderUtils.setContextLoader(execContext.getClassLoader());

task.execute(); task.execute();
LoaderUtils.setContextLoader(currentLoader); LoaderUtils.setContextLoader(currentLoader);
} catch (Throwable e) { } catch (Throwable e) {
ExecutionException ee = ExecutionException ee =
new ExecutionException(e.getClass().getName() + ": " new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e); + e.getMessage(), e);

failureCause = ee; failureCause = ee;
throw ee; throw ee;
} finally { } 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. * get the name of the project associated with this execution.
* *
@@ -177,13 +150,99 @@ public class CoreExecService implements ExecService {
return frame.getProjectName(); 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);
} }
} }



+ 84
- 93
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java View File

@@ -84,8 +84,8 @@ import org.apache.ant.init.InitConfig;
* contains the data values set by Ant tasks as they are executed, including * contains the data values set by Ant tasks as they are executed, including
* task definitions, property values, etc. * task definitions, property values, etc.
* *
* @author Conor MacNeill
* @created 14 January 2002
* @author Conor MacNeill
* @created 14 January 2002
*/ */
public class Frame implements DemuxOutputReceiver { public class Frame implements DemuxOutputReceiver {
/** the base dir of the project */ /** the base dir of the project */
@@ -151,12 +151,11 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Create an Execution Frame for the given project * 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 * imported
*/ */
protected Frame(Map standardLibs, InitConfig initConfig, 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 * Replace ${} style constructions in the given value with the string
* value of the corresponding data values in the frame * 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 { public String replacePropertyRefs(String value) throws ExecutionException {
return dataService.replacePropertyRefs(value); return dataService.replacePropertyRefs(value);
@@ -185,15 +182,15 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Sets the Project of the Frame * 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 * created and configured
*/ */
protected void setProject(Project project) throws ExecutionException { protected void setProject(Project project) throws ExecutionException {
this.project = project; this.project = project;
referencedFrames = new HashMap(); referencedFrames = new HashMap();


for (Iterator i = project.getReferencedProjectNames(); i.hasNext();) {
for (Iterator i = project.getReferencedProjectNames(); i.hasNext(); ) {
String referenceName = (String) i.next(); String referenceName = (String) i.next();
Project referencedProject Project referencedProject
= project.getReferencedProject(referenceName); = project.getReferencedProject(referenceName);
@@ -211,7 +208,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* get the name of the project associated with this frame. * get the name of the project associated with this frame.
* *
* @return the project's name
* @return the project's name
*/ */
public String getProjectName() { public String getProjectName() {
if (project != null) { if (project != null) {
@@ -224,10 +221,10 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Set a value in this frame or any of its imported frames. * 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) protected void setDataValue(String name, Object value, boolean mutable)
throws ExecutionException { throws ExecutionException {
@@ -253,9 +250,9 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Set the initial properties to be used when the frame starts execution * 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) protected void setInitialProperties(Map properties)
throws ExecutionException { throws ExecutionException {
@@ -271,7 +268,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Set the values of various magic properties * 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 { protected void setMagicProperties() throws ExecutionException {
URL antHomeURL = initConfig.getAntHome(); URL antHomeURL = initConfig.getAntHome();
@@ -291,11 +288,10 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Get a definition from a referenced frame * 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 * found
*/ */
protected ImportInfo getReferencedDefinition(String definitionName) protected ImportInfo getReferencedDefinition(String definitionName)
@@ -318,7 +314,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Gets the project model this frame is working with * Gets the project model this frame is working with
* *
* @return the project model
* @return the project model
*/ */
protected Project getProject() { protected Project getProject() {
return project; return project;
@@ -330,7 +326,7 @@ public class Frame implements DemuxOutputReceiver {
* is an expensive operation since it must clone all of the property * is an expensive operation since it must clone all of the property
* stores in all frames * 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. * name.
*/ */
protected Map getAllProperties() { protected Map getAllProperties() {
@@ -359,7 +355,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Get the Ant initialization configuration for this frame. * Get the Ant initialization configuration for this frame.
* *
* @return Ant's initialization configuration
* @return Ant's initialization configuration
*/ */
protected InitConfig getInitConfig() { protected InitConfig getInitConfig() {
return initConfig; return initConfig;
@@ -369,7 +365,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Get the config instance being used by this frame. * 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() { protected AntConfig getConfig() {
return config; return config;
@@ -379,11 +375,10 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Get the core's implementation of the given service interface. * 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 * 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 * implementatin of the requested interface
*/ */
protected Object getCoreService(Class serviceInterfaceClass) 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 * Get the EventSupport instance for this frame. This tracks the build
* listeners on this frame * listeners on this frame
* *
* @return the EventSupport instance
* @return the EventSupport instance
*/ */
protected BuildEventSupport getEventSupport() { protected BuildEventSupport getEventSupport() {
return eventSupport; return eventSupport;
@@ -412,7 +407,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Gets the baseDir of the Frame * Gets the baseDir of the Frame
* *
* @return the baseDir value
* @return the baseDir value
*/ */
protected File getBaseDir() { protected File getBaseDir() {
return baseDir; return baseDir;
@@ -422,9 +417,9 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Get a referenced frame by its reference name * 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) { protected Frame getReferencedFrame(String referenceName) {
return (Frame) referencedFrames.get(referenceName); return (Frame) referencedFrames.get(referenceName);
@@ -434,7 +429,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Get the frames representing referenced projects. * 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() { protected Iterator getReferencedFrames() {
return referencedFrames.values().iterator(); return referencedFrames.values().iterator();
@@ -444,8 +439,8 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Get the name of an object in its frame * 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) { protected String getNameInFrame(String fullname) {
int index = fullname.lastIndexOf(Project.REF_DELIMITER); 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 * 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 { protected Object getDataValue(String name) throws ExecutionException {
Frame frame = getContainingFrame(name); Frame frame = getContainingFrame(name);
@@ -484,10 +478,10 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Indicate if a data value has been set * 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 * does not exist
*/ */
protected boolean isDataValueSet(String name) throws ExecutionException { 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 * Get the execution frame which contains, directly, the named element
* where the name is relative to this frame * 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) { protected Frame getContainingFrame(String elementName) {
int index = elementName.lastIndexOf(Project.REF_DELIMITER); int index = elementName.lastIndexOf(Project.REF_DELIMITER);
@@ -541,12 +535,12 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Add a collection of properties to this frame * 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 { 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(); String name = (String) i.next();
Object value = properties.get(name); Object value = properties.get(name);


@@ -558,10 +552,9 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Create a new frame for a given project * 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) protected Frame createFrame(Project project)
throws ExecutionException { throws ExecutionException {
@@ -569,7 +562,7 @@ public class Frame implements DemuxOutputReceiver {
= new Frame(standardLibs, initConfig, config); = new Frame(standardLibs, initConfig, config);


newFrame.setProject(project); newFrame.setProject(project);
for (Iterator j = eventSupport.getListeners(); j.hasNext();) {
for (Iterator j = eventSupport.getListeners(); j.hasNext(); ) {
BuildListener listener = (BuildListener) j.next(); BuildListener listener = (BuildListener) j.next();


newFrame.addBuildListener(listener); newFrame.addBuildListener(listener);
@@ -581,8 +574,8 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Log a message as a build event * 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) { protected void log(String message, int level) {
eventSupport.fireMessageLogged(project, message, level); eventSupport.fireMessageLogged(project, message, level);
@@ -592,10 +585,10 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Add a build listener to this execution frame * 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) { protected void addBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext();) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame referencedFrame = (Frame) i.next(); Frame referencedFrame = (Frame) i.next();


referencedFrame.addBuildListener(listener); referencedFrame.addBuildListener(listener);
@@ -607,10 +600,10 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Remove a build listener from the execution * 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) { protected void removeBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext();) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame subFrame = (Frame) i.next(); Frame subFrame = (Frame) i.next();


subFrame.removeBuildListener(listener); subFrame.removeBuildListener(listener);
@@ -622,9 +615,8 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Run the given list of targets * 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 { protected void runBuild(List targets) throws ExecutionException {
determineBaseDirs(); determineBaseDirs();
@@ -640,7 +632,7 @@ public class Frame implements DemuxOutputReceiver {
executeTarget(defaultTarget); executeTarget(defaultTarget);
} }
} else { } else {
for (Iterator i = targets.iterator(); i.hasNext();) {
for (Iterator i = targets.iterator(); i.hasNext(); ) {
String targetName = (String) i.next(); String targetName = (String) i.next();


log("Executing target: " + targetName, MessageLevel.MSG_DEBUG); 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 * 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 { protected void executeTarget(String targetName) throws ExecutionException {
// to execute a target we must determine its dependencies and // 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. // firstly build a list of fully qualified target names to execute.
List dependencyOrder = project.getTargetDependencies(targetName); List dependencyOrder = project.getTargetDependencies(targetName);


for (Iterator i = dependencyOrder.iterator(); i.hasNext();) {
for (Iterator i = dependencyOrder.iterator(); i.hasNext(); ) {
String fullTargetName = (String) i.next(); String fullTargetName = (String) i.next();
Frame frame = getContainingFrame(fullTargetName); Frame frame = getContainingFrame(fullTargetName);
String localTargetName = getNameInFrame(fullTargetName); String localTargetName = getNameInFrame(fullTargetName);
@@ -682,8 +673,8 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Run the tasks returned by the given iterator * 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 * executing tasks
*/ */
protected void executeTasks(Iterator taskIterator) 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 * Execute the given target's tasks. The target must be local to this
* frame's project * 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) protected void executeTargetTasks(String targetName)
throws ExecutionException { throws ExecutionException {
@@ -778,11 +769,11 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Initialize the frame by executing the project level tasks if any * 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 * failed
*/ */
protected void initialize() throws ExecutionException { protected void initialize() throws ExecutionException {
for (Iterator i = getReferencedFrames(); i.hasNext();) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame referencedFrame = (Frame) i.next(); Frame referencedFrame = (Frame) i.next();


referencedFrame.initialize(); referencedFrame.initialize();
@@ -797,7 +788,7 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Determine the base directory for each frame in the frame hierarchy * 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 * determined
*/ */
private void determineBaseDirs() throws ExecutionException { private void determineBaseDirs() throws ExecutionException {
@@ -825,7 +816,7 @@ public class Frame implements DemuxOutputReceiver {
} }
setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true); setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true);


for (Iterator i = getReferencedFrames(); i.hasNext();) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame refFrame = (Frame) i.next(); Frame refFrame = (Frame) i.next();


refFrame.determineBaseDirs(); refFrame.determineBaseDirs();
@@ -859,8 +850,8 @@ public class Frame implements DemuxOutputReceiver {
* the thread producing the content. The content is broken up into * the thread producing the content. The content is broken up into
* separate lines * 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) { public void threadOutput(String line, boolean isErr) {
eventSupport.threadOutput(line, isErr); eventSupport.threadOutput(line, isErr);


+ 4
- 9
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java View File

@@ -105,11 +105,8 @@ public class Ant extends AntBase {
* @exception ExecutionException if the build can't be run * @exception ExecutionException if the build can't be run
*/ */
public void execute() throws ExecutionException { public void execute() throws ExecutionException {
System.out.println("Starting Ant Task");
if (baseDir == null) { if (baseDir == null) {
ExecService execService
= (ExecService) getCoreService(ExecService.class);
baseDir = execService.getBaseDir();
baseDir = getExecService().getBaseDir();
} }
File antFile = null; File antFile = null;
@@ -125,11 +122,9 @@ public class Ant extends AntBase {
setProperty(MagicProperties.BASEDIR, baseDir.getAbsolutePath()); 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());
} }
} }



+ 221
- 136
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java View File

@@ -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
* <http://www.apache.org/>.
* 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
* <http://www.apache.org/>.
*/ */
package org.apache.ant.antlib.system; package org.apache.ant.antlib.system;
import java.util.ArrayList; 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.AbstractTask;
import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.DataService;
import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException; 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 * 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 { public void validateComponent() throws ExecutionException {
if (name == null) { if (name == null) {
@@ -138,6 +142,7 @@ public abstract class AntBase extends AbstractTask {
} }
} }



/** /**
* A simple class to store information about references being passed * 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 */ /** The id to be used in the sub-build for this reference */
private String toId; 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 * 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; 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; private boolean inheritRefs = false;


/** The properties which will be passed to the sub-build */ /** The properties which will be passed to the sub-build */
private Map properties = new HashMap(); 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 * 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()); properties.put(property.getName(), property.getValue());
} }



/** /**
* Add a reference to be passed * Add a reference to be passed
* *
@@ -281,11 +260,13 @@ public abstract class AntBase extends AbstractTask {
*/ */
public void addReference(Reference reference) throws ExecutionException { public void addReference(Reference reference) throws ExecutionException {
String refId = reference.getRefId(); String refId = reference.getRefId();

if (!dataService.isDataValueSet(refId)) { if (!dataService.isDataValueSet(refId)) {
throw new ExecutionException("RefId \"" + refId + "\" is not set"); throw new ExecutionException("RefId \"" + refId + "\" is not set");
} }
Object value = dataService.getDataValue(refId); Object value = dataService.getDataValue(refId);
String toId = reference.getToId(); String toId = reference.getToId();

if (toId == null) { if (toId == null) {
toId = refId; toId = refId;
} }
@@ -293,16 +274,35 @@ public abstract class AntBase extends AbstractTask {
properties.put(toId, value); 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 * Get the list of targets to be executed
* *
@@ -310,27 +310,112 @@ public abstract class AntBase extends AbstractTask {
*/ */
protected List getTargets() { protected List getTargets() {
List targets = new ArrayList(); List targets = new ArrayList();

if (targetName != null) { if (targetName != null) {
targets.add(targetName); targets.add(targetName);
} }
return targets; 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;
}
} }



+ 4
- 4
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java View File

@@ -69,12 +69,12 @@ public class AntCall extends AntBase {
* @exception ExecutionException if the build fails * @exception ExecutionException if the build fails
*/ */
public void execute() throws ExecutionException { public void execute() throws ExecutionException {
ExecService execService
= (ExecService) getCoreService(ExecService.class);
setProperty(MagicProperties.BASEDIR, setProperty(MagicProperties.BASEDIR,
execService.getBaseDir().getAbsolutePath());
getExecService().getBaseDir().getAbsolutePath());


execService.callTarget(getProperties(), getTargets());
Object key = getExecService().setupBuild(getProperties());
setSubBuildKey(key);
getExecService().runBuild(key, getTargets());
} }


/** /**


+ 135
- 0
proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListenerAdapter.java View File

@@ -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
* <http://www.apache.org/>.
*/
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) {
}

}


+ 31
- 12
proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java View File

@@ -67,37 +67,46 @@ import org.apache.ant.common.util.ExecutionException;
*/ */
public interface ExecService { public interface ExecService {
/** /**
* Run a sub-build.
* Setup a sub-build.
* *
* @param antFile the file containing the XML description of the model * @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 * @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; throws ExecutionException;


/** /**
* Run a sub-build.
* Setup a sub-build.
* *
* @param model the project model to be used for the 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 * @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; 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 * @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; 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 * execute a task. The task should have already been initialised by
* the core * the core
@@ -120,5 +129,15 @@ public interface ExecService {
* @return the base directory for this execution of Ant * @return the base directory for this execution of Ant
*/ */
File getBaseDir(); 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;
} }



Loading…
Cancel
Save