Browse Source

Continue Aspect development

Impementation of the failonerror aspect


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272718 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 23 years ago
parent
commit
fcc7e2b47f
20 changed files with 494 additions and 195 deletions
  1. +7
    -7
      proposal/mutant/build.xml
  2. +2
    -1
      proposal/mutant/build/ant1compat.xml
  3. +1
    -1
      proposal/mutant/build/script.xml
  4. +40
    -105
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
  5. +50
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
  6. +19
    -6
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java
  7. +12
    -16
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
  8. +1
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java
  9. +1
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java
  10. +1
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java
  11. +5
    -5
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java
  12. +57
    -1
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java
  13. +94
    -0
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspectContext.java
  14. +6
    -2
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java
  15. +1
    -8
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
  16. +7
    -3
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java
  17. +134
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/model/AspectValueCollection.java
  18. +26
    -36
      proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java
  19. +14
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
  20. +16
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java

+ 7
- 7
proposal/mutant/build.xml View File

@@ -46,7 +46,7 @@

<target name="init" depends="buildsetup">
<mkdir dir="${bin.dir}/init"/>
<depend destdir="${bin.dir}/init" srcdir="${java.dir}/init"/>
<depend destdir="${bin.dir}/init" srcdir="${java.dir}/init" closure="yes"/>
<javac destdir="${bin.dir}/init" srcdir="${java.dir}/init" debug="${debug}"/>
<jar basedir="${bin.dir}/init" jarfile="${distlib.dir}/init.jar"/>
</target>
@@ -54,7 +54,7 @@
<target name="common" depends="init">
<mkdir dir="${bin.dir}/common"/>
<mkdir dir="${distlib.dir}/common"/>
<depend destdir="${bin.dir}/common" srcdir="${java.dir}/common">
<depend destdir="${bin.dir}/common" srcdir="${java.dir}/common" closure="yes">
<classpath refid="classpath.common"/>
</depend>
<javac destdir="${bin.dir}/common" srcdir="${java.dir}/common" debug="${debug}">
@@ -66,7 +66,7 @@
<target name="antcore" depends="common">
<mkdir dir="${bin.dir}/antcore"/>
<mkdir dir="${distlib.dir}/antcore"/>
<depend destdir="${bin.dir}/antcore" srcdir="${java.dir}/antcore">
<depend destdir="${bin.dir}/antcore" srcdir="${java.dir}/antcore" closure="yes">
<classpath refid="classpath.antcore"/>
</depend>
<javac destdir="${bin.dir}/antcore" srcdir="${java.dir}/antcore" debug="${debug}">
@@ -78,7 +78,7 @@
<target name="frontend" depends="antcore, start">
<mkdir dir="${bin.dir}/frontend"/>
<mkdir dir="${distlib.dir}/frontend"/>
<depend destdir="${bin.dir}/frontend" srcdir="${java.dir}/frontend">
<depend destdir="${bin.dir}/frontend" srcdir="${java.dir}/frontend" closure="yes">
<classpath refid="classpath.frontend"/>
</depend>
<javac destdir="${bin.dir}/frontend" srcdir="${java.dir}/frontend" debug="${debug}">
@@ -98,7 +98,7 @@

<target name="start" depends="init">
<mkdir dir="${bin.dir}/start"/>
<depend destdir="${bin.dir}/start" srcdir="${java.dir}/start">
<depend destdir="${bin.dir}/start" srcdir="${java.dir}/start" closure="yes">
<classpath refid="classpath.start"/>
</depend>
<javac destdir="${bin.dir}/start" srcdir="${java.dir}/start" debug="${debug}">
@@ -126,7 +126,7 @@
<target name="remote" depends="init">
<mkdir dir="${bin.dir}/remote"/>
<depend destdir="${bin.dir}/remote" srcdir="${java.dir}/remote">
<depend destdir="${bin.dir}/remote" srcdir="${java.dir}/remote" closure="yes">
<classpath refid="classpath.start"/>
</depend>
<javac destdir="${bin.dir}/remote" srcdir="${java.dir}/remote" debug="${debug}">
@@ -155,7 +155,7 @@
<path refid="classpath.common"/>
<pathelement location="${distlib.dir}/common/common.jar"/>
</path>
<depend destdir="${bin.dir}/antlibs/system" srcdir="${java.dir}/antlibs/system">
<depend destdir="${bin.dir}/antlibs/system" srcdir="${java.dir}/antlibs/system" closure="yes">
<classpath refid="classpath.antlibs"/>
</depend>
<javac destdir="${bin.dir}/antlibs/system" srcdir="${java.dir}/antlibs/system" debug="${debug}">


+ 2
- 1
proposal/mutant/build/ant1compat.xml View File

@@ -431,7 +431,8 @@
<copy todir="${bin.dir}/ant1src_copy">
<fileset refid="ant1src_tocopy"/>
</copy>
<depend destdir="${bin.dir}/ant1compat" srcdir="${bin.dir}/ant1src_copy:${java.dir}/antlibs/ant1compat">
<depend destdir="${bin.dir}/ant1compat" srcdir="${bin.dir}/ant1src_copy:${java.dir}/antlibs/ant1compat"
closure="yes">
<classpath refid="classpath"/>
</depend>
<javac destdir="${bin.dir}/ant1compat"


+ 1
- 1
proposal/mutant/build/script.xml View File

@@ -37,7 +37,7 @@
<target name="build" depends="check_bsf, nobsf" if="bsf.present">
<mkdir dir="${bin.dir}/antlibs/script"/>
<mkdir dir="${distlib.dir}/antlibs"/>
<depend destdir="${bin.dir}/antlibs/script" srcdir="${java.dir}/antlibs/script">
<depend destdir="${bin.dir}/antlibs/script" srcdir="${java.dir}/antlibs/script" closure="yes">
<classpath refid="classpath.script"/>
</depend>
<javac destdir="${bin.dir}/antlibs/script" srcdir="${java.dir}/antlibs/script" debug="${debug}">


+ 40
- 105
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java View File

@@ -184,7 +184,6 @@ public class ComponentManager implements ComponentService {
if (importAll || doAuto) {
importLibrary(libraryId);
}
addAspects((AntLibrary) antLibraries.get(libraryId));
}
} catch (MalformedURLException e) {
throw new ExecutionException("Unable to load libraries from "
@@ -265,6 +264,7 @@ public class ComponentManager implements ComponentService {
importLibraryDef(library, defName, null);
}
addConverters(library);
addAspects(library);
}

/**
@@ -288,6 +288,7 @@ public class ComponentManager implements ComponentService {
}
importLibraryDef(library, defName, alias);
addConverters(library);
addAspects(library);
}

/**
@@ -392,7 +393,7 @@ public class ComponentManager implements ComponentService {
return (AntLibFactory) libFactories.get(libraryId);
}
ExecutionContext context
= new ExecutionContext(frame, null, Location.UNKNOWN_LOCATION);
= new ExecutionContext(frame, null, null);
AntLibFactory libFactory = componentLibrary.getFactory(context);
if (libFactory == null) {
libFactory = new StandardLibFactory();
@@ -511,7 +512,7 @@ public class ComponentManager implements ComponentService {
// initialise the component with it.
if (execComponent != null) {
ExecutionContext context
= new ExecutionContext(frame, execComponent, location);
= new ExecutionContext(frame, execComponent, model);
context.setClassLoader(componentLoader);
execComponent.init(context, componentName);
}
@@ -604,98 +605,6 @@ public class ComponentManager implements ComponentService {
return setter;
}

/**
* Create a component - handles all the variations
*
* @param loader the component's classloader
* @param componentClass The class of the component.
* @param componentName The component's name in the global context
* @param addTaskAdapter whether the component should add a Task adapter
* to make this component a Task.
* @param localName The name of the component within its library
* @param model the BuildElement model of the component's configuration
* @param factory the facrtory object used to create the component
* @return the required component potentially wrapped in a wrapper object.
* @exception ExecutionException if the component cannot be created
*/
private Object createComponent(ClassLoader loader, AntLibFactory factory,
Class componentClass, String componentName,
String localName, boolean addTaskAdapter,
BuildElement model)
throws ExecutionException {
// set the location to unknown unless we have a build model to use
Location location = Location.UNKNOWN_LOCATION;
if (model != null) {
location = model.getLocation();
}

try {
// create the component using the factory
Object component
= factory.createComponent(componentClass, localName);

// wrap the component in an adapter if required.
ExecutionComponent execComponent = null;
if (addTaskAdapter) {
if (component instanceof Task) {
execComponent = (Task) component;
} else {
execComponent = new TaskAdapter(componentName, component);
}
} else if (component instanceof ExecutionComponent) {
execComponent = (ExecutionComponent) component;
}

// set the context loader to that for the component
ClassLoader currentLoader
= LoaderUtils.setContextLoader(loader);

// if the component is an execution component create a context and
// initialise the component with it.
if (execComponent != null) {
ExecutionContext context
= new ExecutionContext(frame, execComponent, location);
context.setClassLoader(loader);
execComponent.init(context, componentName);
}

// if we have a model, use it to configure the component. Otherwise
// the caller is expected to configure thre object
if (model != null) {
configureElement(factory, component, model);
// if the component is an execution component and we have a
// model, validate it
if (execComponent != null) {
execComponent.validateComponent();
}
}

// reset the loader
LoaderUtils.setContextLoader(currentLoader);

// if we have an execution component, potentially a wrapper,
// return it otherwise the component directly
if (execComponent != null) {
return execComponent;
} else {
return component;
}
} catch (InstantiationException e) {
throw new ExecutionException("Unable to instantiate component "
+ "class " + componentClass.getName() + " for component <"
+ componentName + ">", e, location);
} catch (IllegalAccessException e) {
throw new ExecutionException("Unable to access task class "
+ componentClass.getName() + " for component <"
+ componentName + ">", e, location);
} catch (ExecutionException e) {
e.setLocation(location, false);
throw e;
} catch (RuntimeException e) {
throw new ExecutionException(e, location);
}
}

/**
* Create an instance of a type given its required class
*
@@ -718,8 +627,8 @@ public class ComponentManager implements ComponentService {
if (typeInstance instanceof ExecutionComponent) {
ExecutionComponent component
= (ExecutionComponent) typeInstance;
ExecutionContext context = new ExecutionContext(frame,
component, model.getLocation());
ExecutionContext context
= new ExecutionContext(frame, component, model);
component.init(context, localName);
configureElement(libFactory, typeInstance, model);
component.validateComponent();
@@ -761,8 +670,10 @@ public class ComponentManager implements ComponentService {
Class nestedType = setter.getType(nestedElementName);

// is there a polymorph indicator - look in Ant aspects
String typeName = model.getAspectValue(Constants.ANT_ASPECT, "type");
String refId = model.getAspectValue(Constants.ANT_ASPECT, "refid");
String typeName
= model.getAspectAttributeValue(Constants.ANT_ASPECT, "type");
String refId
= model.getAspectAttributeValue(Constants.ANT_ASPECT, "refid");
if (refId != null && typeName != null) {
throw new ExecutionException("Only one of " + Constants.ANT_ASPECT
+ ":type and " + Constants.ANT_ASPECT
@@ -849,8 +760,8 @@ public class ComponentManager implements ComponentService {
if (nestedElement instanceof ExecutionComponent) {
ExecutionComponent component
= (ExecutionComponent) nestedElement;
ExecutionContext context = new ExecutionContext(frame,
component, model.getLocation());
ExecutionContext context
= new ExecutionContext(frame, component, model);
component.init(context, nestedElementName);
configureElement(factory, nestedElement, model);
component.validateComponent();
@@ -865,6 +776,30 @@ public class ComponentManager implements ComponentService {
}
}

/**
* configure an object with attribtes from the given map
*
* @param object the object to be configured.
* @param attributeValues a map containing named attribute values.
*
* @exception ExecutionException if the object does not support an
* attribute in the map.
*/
public void configureAttributes(Object object, Map attributeValues)
throws ExecutionException {
Setter setter = getSetter(object.getClass());
for (Iterator i = attributeValues.keySet().iterator(); i.hasNext();) {
String attributeName = (String) i.next();
String attributeValue = (String) attributeValues.get(attributeName);
if (!setter.supportsAttribute(attributeName)) {
throw new ExecutionException(object.getClass().getName()
+ " does not support the \"" + attributeName
+ "\" attribute");
}
setter.setAttribute(object, attributeName,
frame.replacePropertyRefs(attributeValue));
}
}

/**
* Configure an element according to the given model.
@@ -985,8 +920,8 @@ public class ComponentManager implements ComponentService {
+ " does not implement the Aspect interface");
}
Aspect aspect = (Aspect) libFactory.createInstance(aspectClass);
ExecutionContext context = new ExecutionContext(frame,
null, Location.UNKNOWN_LOCATION);
ExecutionContext context
= new ExecutionContext(frame, null, null);
aspect.init(context);
aspects.add(aspect);
}
@@ -1045,8 +980,8 @@ public class ComponentManager implements ComponentService {
}
Converter converter
= (Converter) libFactory.createInstance(converterClass);
ExecutionContext context = new ExecutionContext(frame,
null, Location.UNKNOWN_LOCATION);
ExecutionContext context
= new ExecutionContext(frame, null, null);
converter.init(context);
Class[] converterTypes = converter.getTypes();
for (int j = 0; j < converterTypes.length; ++j) {


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

@@ -60,10 +60,13 @@ import java.util.Map;
import org.apache.ant.antcore.modelparser.XMLProjectParser;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitUtils;
import org.apache.ant.common.model.AspectValueCollection;

/**
* This is the core's implementation of the Execution Service.
@@ -98,8 +101,54 @@ public class CoreExecService implements ExecService {
* @exception ExecutionException if there is an execution problem
*/
public void executeTask(Task task) throws ExecutionException {
frame.executeTask(task);
ExecutionContext execContext = getTaskExecutionContext(task);

BuildElement model = execContext.getModel();
AspectValueCollection aspectValues = null;
if (model != null) {
aspectValues = model.getAspectAttributes();
}
frame.executeTask(task, aspectValues);
}
/**
* Retrieve the execution context from a task and verify that the context
* is valid.
*
* @param task the task.
* @return the task's execution context.
*
* @exception ExecutionException if the task's context is not valid.
*/
private ExecutionContext getTaskExecutionContext(Task task)
throws ExecutionException {
AntContext context = task.getAntContext();

if (!(context instanceof ExecutionContext)) {
throw new ExecutionException("The Task was not configured with an"
+ " appropriate context");
}
return (ExecutionContext) context;
}
/**
* Execute a task with a set of aspect values. Normally aspect values come
* from a build model but not all tasks will be created from a build model.
* Some may be created dynamically and configured programatically. This
* method allows aspect values to provided for execution of such tasks since
* by their nature, aspect values are not part of the task configuration.
*
* @param task the task to be executed
* @param aspectValues the aspect attribute values.
* @exception ExecutionException if there is an execution problem
*/
public void executeTask(Task task, AspectValueCollection aspectValues)
throws ExecutionException {
ExecutionContext execContext = getTaskExecutionContext(task);

frame.executeTask(task, aspectValues);
}


/**


+ 19
- 6
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java View File

@@ -56,6 +56,7 @@ import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.ExecutionComponent;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.Location;
import org.apache.ant.common.model.BuildElement;

/**
* This is the core's implementation of the AntContext for all core objects.
@@ -71,8 +72,8 @@ public class ExecutionContext implements AntContext {
/** the event support instance used to manage build events */
private BuildEventSupport eventSupport;

/** The location of the object associated with this context */
private Location location;
/** The build model associated with this context. */
private BuildElement model;

/** the execution component associated with the context, if any */
private ExecutionComponent component;
@@ -89,13 +90,13 @@ public class ExecutionContext implements AntContext {
*
* @param frame the frame containing this context
* @param component the component associated with this context - may be null
* @param location the location associated with the component
* @param model the build model associated with this component if any.
*/
protected ExecutionContext(Frame frame, ExecutionComponent component,
Location location) {
BuildElement model) {
this.frame = frame;
this.eventSupport = frame.getEventSupport();
this.location = location;
this.model = model;
this.component = component;
}

@@ -120,7 +121,10 @@ public class ExecutionContext implements AntContext {
* @return the location in the build model associated with this context.
*/
public Location getLocation() {
return location;
if (model == null) {
return Location.UNKNOWN_LOCATION;
}
return model.getLocation();
}

/**
@@ -166,5 +170,14 @@ public class ExecutionContext implements AntContext {
protected ExecutionComponent getExecutionComponent() {
return component;
}
/**
* Get the build model associated with this context.
*
* @return the build model or null if there is no build model.
*/
protected BuildElement getModel() {
return model;
}
}


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

@@ -65,12 +65,12 @@ import java.util.Set;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.antlib.Aspect;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.event.MessageLevel;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.model.Target;
import org.apache.ant.common.model.AspectValueCollection;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.service.EventService;
@@ -860,36 +860,32 @@ public class Frame implements DemuxOutputReceiver {
}

/**
* Execute a task notifiying all registered aspects of the fact
*
* @param task the Task instance to execute.
* Execute a task with the given aspect values.
*
* @param task the task to be executed.
* @param aspectValues the collection of aspect attribute values.
* @exception ExecutionException if the task has a problem.
*/
protected void executeTask(Task task) throws ExecutionException {
protected void executeTask(Task task, AspectValueCollection aspectValues)
throws ExecutionException {
List aspects = componentManager.getAspects();
Map aspectContexts = new HashMap();
for (Iterator i = aspects.iterator(); i.hasNext();) {
Aspect aspect = (Aspect) i.next();
Object context = aspect.preExecuteTask(task);
aspectContexts.put(aspect, context);
Object aspectContext = aspect.preExecuteTask(task, aspectValues);
if (aspectContext != null) {
aspectContexts.put(aspect, aspectContext);
}
}
if (aspectContexts.size() != 0) {
aspectContextsMap.put(task, aspectContexts);
}
AntContext context = task.getAntContext();

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

eventSupport.fireTaskStarted(task);

Throwable failureCause = null;

ExecutionContext execContext = (ExecutionContext) task.getAntContext();
try {
ClassLoader currentLoader
= LoaderUtils.setContextLoader(execContext.getClassLoader());
@@ -949,7 +945,7 @@ public class Frame implements DemuxOutputReceiver {
}

if (component instanceof Task) {
executeTask((Task) component);
execService.executeTask((Task) component);
}
} catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);


+ 1
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java View File

@@ -93,7 +93,7 @@ public class BuildElementHandler extends ModelElementHandler {
buildElement.addAttribute(attributeName,
getAttribute(attributeName));
}
buildElement.setAspects(getAspects());
buildElement.addAspectAttributes(getAspectAttributes());
}




+ 1
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java View File

@@ -133,7 +133,7 @@ public class ProjectHandler extends ModelElementHandler {
project.setDefaultTarget(getAttribute(DEFAULT_ATTR));
project.setBase(getAttribute(BASEDIR_ATTR));
project.setName(getAttribute(NAME_ATTR));
project.setAspects(getAspects());
project.addAspectAttributes(getAspectAttributes());
}
}



+ 1
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java View File

@@ -105,7 +105,7 @@ public class TargetHandler extends ModelElementHandler {
target = new Target(getLocation(), getAttribute(NAME_ATTR));
setModelElement(target);
target.setDescription(getAttribute(DESC_ATTR));
target.setAspects(getAspects());
target.addAspectAttributes(getAspectAttributes());

String depends = getAttribute(DEPENDS_ATTR);
if (depends != null) {


+ 5
- 5
proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java View File

@@ -101,7 +101,7 @@ public abstract class ElementHandler extends DefaultHandler {
private Map elementAttributes;

/** The aspect attributes read from the element definition */
private Map aspects;
private Map aspectAttributes;

/** The content of this element */
private String content;
@@ -150,8 +150,8 @@ public abstract class ElementHandler extends DefaultHandler {
*
* @return The aspect attributes.
*/
public Map getAspects() {
return aspects;
public Map getAspectAttributes() {
return aspectAttributes;
}

/**
@@ -313,14 +313,14 @@ public abstract class ElementHandler extends DefaultHandler {
*/
protected final void processAttributes(Attributes attributes)
throws SAXParseException {
aspects = new HashMap();
aspectAttributes = new HashMap();
elementAttributes = new HashMap();
int length = attributes.getLength();
for (int i = 0; i < length; ++i) {
String attributeName = attributes.getQName(i);
String attributeValue = attributes.getValue(i);
if (attributeName.indexOf(":") != -1) {
aspects.put(attributeName, attributeValue);
aspectAttributes.put(attributeName, attributeValue);
} else {
validateAttribute(attributeName, attributeValue);
elementAttributes.put(attributeName, attributeValue);


+ 57
- 1
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java View File

@@ -52,11 +52,16 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.antlib.system;

import java.util.Map;
import org.apache.ant.common.antlib.AbstractAspect;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.AspectValueCollection;

/**
* The Ant aspect - handles all ant aspects
@@ -70,6 +75,9 @@ public class AntAspect extends AbstractAspect {
/** The core's data service implementation */
private DataService dataService = null;

/** The core's component service */
private ComponentService componentService = null;

/**
* Initialise the aspect with a context.
*
@@ -79,6 +87,8 @@ public class AntAspect extends AbstractAspect {
public void init(AntContext context) throws ExecutionException {
super.init(context);
dataService = (DataService) context.getCoreService(DataService.class);
componentService
= (ComponentService) context.getCoreService(ComponentService.class);
}
/**
@@ -95,7 +105,7 @@ public class AntAspect extends AbstractAspect {
*/
public Object postCreateComponent(Object component, BuildElement model)
throws ExecutionException {
String typeId = model.getAspectValue(ANT_ASPECT, "id");
String typeId = model.getAspectAttributeValue(ANT_ASPECT, "id");
if (typeId != null) {
dataService.setMutableDataValue(typeId, component);
@@ -103,5 +113,51 @@ public class AntAspect extends AbstractAspect {
return null;
}

/**
* This join point is activated just prior to task execution.
*
* @param task the task being executed.
* @param aspectValues a collection of aspect attribute values for use
* during the task execution.
*
* @return an objectwhich indicates that this aspect wishes to
* be notified after execution has been completed, in which case the obkect
* is returned to provide the aspect its context. If this returns null
* the aspect's postExecuteTask method will not be invoked.
* @exception ExecutionException if the aspect cannot process the task.
*/
public Object preExecuteTask(Task task, AspectValueCollection aspectValues)
throws ExecutionException {
AntAspectContext aspectContext = new AntAspectContext();
Map antAspectValues = aspectValues.getAttributes(ANT_ASPECT);
if (antAspectValues == null) {
return null;
}
componentService.configureAttributes(aspectContext, antAspectValues);
if (aspectContext.isRequired()) {
return aspectContext;
}
return null;
}
/**
* This join point is activated after a task has executed. The aspect
* may override the task's failure cause by returning a new failure.
*
* @param context the context the aspect provided in preExecuteTask.
* @param failureCause the current failure reason for the task.
*
* @return a new failure reason or null if the task is not to fail.
*/
public Throwable postExecuteTask(Object context, Throwable failureCause) {
AntAspectContext aspectContext = (AntAspectContext) context;
if (!aspectContext.getFailOnError()) {
return null;
}
return super.postExecuteTask(context, failureCause);
}

}


+ 94
- 0
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspectContext.java View File

@@ -0,0 +1,94 @@
/*
* 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.antlib.system;

/**
* The context for the Ant Aspect
*
* @author Conor MacNeill
*/
public class AntAspectContext {
/** Indicates if the task's execution should not fail */
private boolean failOnError = true;
/**
* Set the flag covering whether a task failure halts the build.
*
* @param failOnError false if the build should continue.
*/
public void setFailOnError(boolean failOnError) {
this.failOnError = failOnError;
}

/**
* Indicate whether a task failure halts the build.
*
* @return true if a task error causes the build to fail.
*/
public boolean getFailOnError() {
return failOnError;
}

/**
* Indicate if this aspect context is required - i.e. whether the
* aspect needs to be reactivated after task execution
*
* @return true if the context should be used and the aspect reactivated
* after task execution.
*/
public boolean isRequired() {
return failOnError != true;
}
}


+ 6
- 2
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java View File

@@ -55,6 +55,7 @@ package org.apache.ant.common.antlib;

import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.AspectValueCollection;

/**
* An implementation of the Aspect interface providing default behaviour.
@@ -109,14 +110,17 @@ public class AbstractAspect implements Aspect {
* This join point is activated just prior to task execution.
*
* @param task the task being executed.
* @param aspectValues a collection of aspect attribute values for use
* during the task execution.
*
* @return an objectwhich indicates that this aspect wishes to
* @return an object which indicates that this aspect wishes to
* be notified after execution has been completed, in which case the obkect
* is returned to provide the aspect its context. If this returns null
* the aspect's postExecuteTask method will not be invoked.
* @exception ExecutionException if the aspect cannot process the task.
*/
public Object preExecuteTask(Task task) throws ExecutionException {
public Object preExecuteTask(Task task, AspectValueCollection aspectValues)
throws ExecutionException {
return null;
}


+ 1
- 8
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java View File

@@ -88,15 +88,8 @@ public interface AntContext {
/**
* Gets the location associated with the AntContext
*
* @return the location
* @return the location which may be the unknown location
*/
Location getLocation();
/**
* Get the classloader associated with this context
*
* @return a classloader instance.
*/
ClassLoader getClassLoader();
}


+ 7
- 3
proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java View File

@@ -55,6 +55,7 @@ package org.apache.ant.common.antlib;

import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.AspectValueCollection;

/**
* An aspect is a component which is activated across all task and
@@ -93,14 +94,17 @@ public interface Aspect {
* This join point is activated just prior to task execution.
*
* @param task the task being executed.
*
* @return an objectwhich indicates that this aspect wishes to
* @param aspectValues a collection of aspect attribute values for use
* during the task execution - may be null if no aspect values are
* provided.
* @return an object which indicates that this aspect wishes to
* be notified after execution has been completed, in which case the obkect
* is returned to provide the aspect its context. If this returns null
* the aspect's postExecuteTask method will not be invoked.
* @exception ExecutionException if the aspect cannot process the task.
*/
Object preExecuteTask(Task task) throws ExecutionException;
Object preExecuteTask(Task task, AspectValueCollection aspectValues)
throws ExecutionException;
/**
* This join point is activated after a task has executed. The aspect


+ 134
- 0
proposal/mutant/src/java/common/org/apache/ant/common/model/AspectValueCollection.java View File

@@ -0,0 +1,134 @@
/*
* 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.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* The AspectValueCollection holds aspect values for a range of aspects.
* Values can be retrieved for a particular aspect attribute or all attributes
* of a given aspect.
*
* @author Conor MacNeill
* @created 11 January 2002
*/
public class AspectValueCollection {
/** The aspects defined for this element. */
private Map aspectMaps = new HashMap();

/**
* Set the aspect attribute values.
*
* The attributes are sorted into their various aspects
*
* @param attributes a Map of aspect attributes values. The keys are the
* aspect
*/
public void addAttributes(Map attributes) {
for (Iterator i = attributes.keySet().iterator(); i.hasNext();) {
String attributeName = (String) i.next();
int separator = attributeName.indexOf(":");
if (separator != -1) {
String aspectName = attributeName.substring(0, separator);
String name = attributeName.substring(separator + 1);
if (aspectName.length() != 0 && name.length() != 0) {
Map prefixMap = (Map) aspectMaps.get(aspectName);
if (prefixMap == null) {
prefixMap = new HashMap();
aspectMaps.put(aspectName, prefixMap);
}
prefixMap.put(name, attributes.get(attributeName));
}
}
}
}

/**
* Get an iterator on the aspects which have been given values on this
* element
*
* @return an iterator of Strings , being the aspects which have been
* given values on this element.
*/
public Iterator getNames() {
return aspectMaps.keySet().iterator();
}

/**
* Get the set of attribute values related to the given aspect
*
* @param aspectName the aspect name
* @return a map of the attribute values for the given aspect.
*/
public Map getAttributes(String aspectName) {
return (Map) aspectMaps.get(aspectName);
}

/**
* Get the value of a single aspect attribute
*
* @param aspectName the prefix which identifies the aspectr
* @param keyName the attribute name
* @return the aspect value
*/
public String getAttributeValue(String aspectName, String keyName) {
Map aspectAttributes = getAttributes(aspectName);
if (aspectAttributes == null) {
return null;
}
return (String) aspectAttributes.get(keyName);
}
}


+ 26
- 36
proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java View File

@@ -52,7 +52,7 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.common.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@@ -67,8 +67,8 @@ import org.apache.ant.common.util.Location;
* @created 11 January 2002
*/
public abstract class ModelElement {
/** The aspects defined for this element. */
private Map aspectMaps;
/** The aspectValues defined for this element. */
private AspectValueCollection aspectValues = new AspectValueCollection();

/** The starting location of this element */
private Location location = Location.UNKNOWN_LOCATION;
@@ -107,28 +107,13 @@ public abstract class ModelElement {
}
/**
* Set the aspects of this element
* Adds aspect related attributes of this element
*
* @param aspects a Map of apects that relate to this model element.
* @param aspectAttributes a Map of aspect realted attributes that pertain
* to this model element.
*/
public void setAspects(Map aspects) {
aspectMaps = new HashMap();
for (Iterator i = aspects.keySet().iterator(); i.hasNext();) {
String aspectName = (String) i.next();
int separator = aspectName.indexOf(":");
if (separator != -1) {
String prefix = aspectName.substring(0, separator);
String name = aspectName.substring(separator + 1);
if (prefix.length() != 0 && name.length() != 0) {
Map prefixMap = (Map) aspectMaps.get(prefix);
if (prefixMap == null) {
prefixMap = new HashMap();
aspectMaps.put(prefix, prefixMap);
}
prefixMap.put(name, aspects.get(aspectName));
}
}
}
public void addAspectAttributes(Map aspectAttributes) {
aspectValues.addAttributes(aspectAttributes);
}

/**
@@ -159,39 +144,44 @@ public abstract class ModelElement {
}

/**
* Get an iterator on the aspects which have been given values on this
* Get an iterator on the aspectValues which have been given values on this
* element
*
* @return an iterator of Strings , being the aspects which have been
* @return an iterator of Strings , being the aspectValues which have been
* given values on this element.
*/
public Iterator getAspectNames() {
return aspectMaps.keySet().iterator();
return aspectValues.getNames();
}

/**
* Get the set of attribute values related to the given aspect
*
* @param aspectPrefix the aspect identifier
* @param aspectName the aspect identifier
* @return a map of the attribute values for the given aspect.
*/
public Map getAspectAttributes(String aspectPrefix) {
return (Map) aspectMaps.get(aspectPrefix);
public Map getAspectAttributes(String aspectName) {
return aspectValues.getAttributes(aspectName);
}

/**
* Get the value of a single aspect attribute
*
* @param aspectPrefix the prefix which identifies the aspectr
* @param aspectName the aspect name
* @param keyName the attribute name
* @return the aspect value
*/
public String getAspectValue(String aspectPrefix, String keyName) {
Map aspectAttributes = getAspectAttributes(aspectPrefix);
if (aspectAttributes == null) {
return null;
}
return (String) aspectAttributes.get(keyName);
public String getAspectAttributeValue(String aspectName, String keyName) {
return aspectValues.getAttributeValue(aspectName, keyName);
}
/**
* Get the complete collection of aspect attribute values.
*
* @return an AspectValueCollection instance.
*/
public AspectValueCollection getAspectAttributes() {
return aspectValues;
}
}


+ 14
- 0
proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java View File

@@ -53,9 +53,11 @@
*/
package org.apache.ant.common.service;
import java.net.URL;
import java.util.Map;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.util.ExecutionException;


/**
* The Component Service is used to manage the definitions that Ant uses at
* runtime. It supports the following operations
@@ -186,5 +188,17 @@ public interface ComponentService {
*/
Object createComponent(String libraryId, String localName)
throws ExecutionException;
/**
* Configure an object with attribtes from the given map
*
* @param object the object to be configured.
* @param attributeValues a map containing named attribute values.
*
* @exception ExecutionException if the object does not support an
* attribute in the map.
*/
void configureAttributes(Object object, Map attributeValues)
throws ExecutionException;
}


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

@@ -58,6 +58,7 @@ import java.util.Map;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.model.AspectValueCollection;

/**
* The ExecService provides executiuon services to tasks
@@ -133,6 +134,21 @@ public interface ExecService {
void executeTask(Task task) throws ExecutionException;


/**
* Execute a task with a set of aspect values. Normally aspect values come
* from a build model but not all tasks will be created from a build model.
* Some may be created dynamically and configured programatically. This
* method allows aspect values to provided for execution of such tasks since
* by their nature, aspect values are not part of the task configuration.
*
* @param task the task to be executed
* @param aspectValues the aspect attribute values.
* @exception ExecutionException if there is an execution problem
*/
void executeTask(Task task, AspectValueCollection aspectValues)
throws ExecutionException;
/**
* get the name of the project associated with this execution.
*


Loading…
Cancel
Save