Browse Source

Add support for Aspects

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272712 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 23 years ago
parent
commit
69d9b9a496
21 changed files with 868 additions and 188 deletions
  1. +7
    -2
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java
  2. +17
    -6
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java
  3. +23
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java
  4. +23
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java
  5. +244
    -79
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
  6. +1
    -32
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
  7. +4
    -2
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java
  8. +90
    -13
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
  9. +8
    -0
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java
  10. +18
    -18
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java
  11. +2
    -5
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
  12. +1
    -3
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/Ant.java
  13. +2
    -2
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/CallTarget.java
  14. +3
    -1
      proposal/mutant/src/java/antlibs/system/antlib.xml
  15. +107
    -0
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java
  16. +162
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java
  17. +4
    -4
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java
  18. +138
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java
  19. +2
    -2
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
  20. +5
    -5
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
  21. +7
    -12
      proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java

+ 7
- 2
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java View File

@@ -144,12 +144,17 @@ public class AntLibHandler extends ElementHandler {
antLibrarySpec.addDefinition(defnHandler.getDefinitionType(),
defnHandler.getName(), defnHandler.getClassName());
} else if (qualifiedName.equals("converter")) {
ClassNameHandler converterHandler
= new ClassNameHandler();
ClassNameHandler converterHandler = new ClassNameHandler();
converterHandler.start(getParseContext(), getXMLReader(),
this, getLocator(), attributes, getElementSource(),
qualifiedName);
antLibrarySpec.addConverter(converterHandler.getClassName());
} else if (qualifiedName.equals("aspect")) {
ClassNameHandler aspectHandler = new ClassNameHandler();
aspectHandler.start(getParseContext(), getXMLReader(),
this, getLocator(), attributes, getElementSource(),
qualifiedName);
antLibrarySpec.addAspect(aspectHandler.getClassName());
} else if (qualifiedName.equals("factory")) {
ClassNameHandler factoryHandler
= new ClassNameHandler();


+ 17
- 6
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java View File

@@ -60,6 +60,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import org.apache.ant.antcore.xml.ParseContext;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.util.CircularDependencyChecker;
@@ -153,10 +154,11 @@ public class AntLibManager {
* @param initConfig the Ant initialization configuration
* @param libraries the collection of libraries already configured
* @param libPathsMap a map of lists of library paths for each library
* @return A map of the newly configured libraries
* @exception ExecutionException if a library cannot be configured from
* the given specification
*/
public void configLibraries(InitConfig initConfig, Map librarySpecs,
public Map configLibraries(InitConfig initConfig, Map librarySpecs,
Map libraries, Map libPathsMap)
throws ExecutionException {

@@ -180,15 +182,18 @@ public class AntLibManager {
}
}

Map newLibraries = new HashMap();
CircularDependencyChecker configuring
= new CircularDependencyChecker("configuring Ant libraries");
for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext();) {
String libraryId = (String) i.next();
if (!libraries.containsKey(libraryId)) {
configLibrary(initConfig, librarySpecs, libraryId,
configuring, libraries, libPathsMap);
configuring, libraries, newLibraries, libPathsMap);
}
}
return newLibraries;
}

/**
@@ -267,13 +272,14 @@ public class AntLibManager {
* dependencies.
* @param libraries the collection of libraries which have already been
* configured
* @param newLibraries the new libraries being configured.
* @param libPathsMap a map of lists of library patsh fro each library
* @exception ExecutionException if the library cannot be configured.
*/
private void configLibrary(InitConfig initConfig, Map librarySpecs,
String libraryId,
CircularDependencyChecker configuring,
Map libraries, Map libPathsMap)
Map libraries, Map newLibraries, Map libPathsMap)
throws ExecutionException {

try {
@@ -283,14 +289,15 @@ public class AntLibManager {
= (AntLibrarySpec) librarySpecs.get(libraryId);
String extendsId = librarySpec.getExtendsLibraryId();
if (extendsId != null) {
if (!libraries.containsKey(extendsId)) {
if (!libraries.containsKey(extendsId) &&
!newLibraries.containsKey(extendsId)) {
if (!librarySpecs.containsKey(extendsId)) {
throw new ExecutionException("Could not find library, "
+ extendsId + ", upon which library "
+ libraryId + " depends");
}
configLibrary(initConfig, librarySpecs, extendsId,
configuring, libraries, libPathsMap);
configuring, libraries, newLibraries, libPathsMap);
}
}

@@ -323,10 +330,14 @@ public class AntLibManager {
if (extendsId != null) {
AntLibrary extendsLibrary
= (AntLibrary) libraries.get(extendsId);
if (extendsLibrary == null) {
extendsLibrary = (AntLibrary) newLibraries.get(extendsId);
}
antLibrary.setExtendsLibrary(extendsLibrary);
}
antLibrary.setParentLoader(initConfig.getCommonLoader());
libraries.put(libraryId, antLibrary);
newLibraries.put(libraryId, antLibrary);

if (libPathsMap != null) {
List libPaths = (List) libPathsMap.get(libraryId);


+ 23
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java View File

@@ -88,6 +88,9 @@ public class AntLibrary implements ComponentLibrary {
/** The list of converter classnames defined in this library */
private List converterClassNames = new ArrayList();

/** The list of aspect classnames defined in this library */
private List aspectClassNames = new ArrayList();

/** The class name of this library's factory class, if any */
private String factoryClassName;

@@ -116,6 +119,7 @@ public class AntLibrary implements ComponentLibrary {
this.definitions = spec.getDefinitions();
this.isolated = spec.isIsolated();
this.converterClassNames.addAll(spec.getConverters());
this.aspectClassNames.addAll(spec.getAspects());
this.factoryClassName = spec.getFactory();
this.definitionURL = spec.getLibraryURL();
}
@@ -182,7 +186,7 @@ public class AntLibrary implements ComponentLibrary {
}

/**
* Gets an the converter class names of the AntLibrary
* Gets the converter class names of the AntLibrary
*
* @return an iterator over a list of String class names
*/
@@ -190,6 +194,15 @@ public class AntLibrary implements ComponentLibrary {
return converterClassNames.iterator();
}

/**
* Gets the aspect class names of the AntLibrary
*
* @return an iterator over a list of String class names
*/
public Iterator getAspectClassNames() {
return aspectClassNames.iterator();
}

/**
* Get the URL to where the library was loaded from
*
@@ -251,6 +264,15 @@ public class AntLibrary implements ComponentLibrary {
return !converterClassNames.isEmpty();
}

/**
* Indicate whether this library has any aspects defined
*
* @return true if any aspects have been defined
*/
public boolean hasAspects() {
return !aspectClassNames.isEmpty();
}

/**
* Add a library to path to this AntLibrary definition
*


+ 23
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java View File

@@ -85,6 +85,9 @@ public class AntLibrarySpec {
/** The list of converter classnames defined in this library */
private List converterClassNames = new ArrayList();

/** The list of aspect classnames defined in this library */
private List aspectClassNames = new ArrayList();

/** The name of the factory class for this library */
private String factoryClassName;

@@ -196,6 +199,16 @@ public class AntLibrarySpec {
return converterClassNames;
}


/**
* Get the list of aspect classnames defined in this library spec
*
* @return the aspect classnames list
*/
public List getAspects() {
return aspectClassNames;
}

/**
* Gets the factory classname of the AntLibrarySpec
*
@@ -262,7 +275,7 @@ public class AntLibrarySpec {
}

/**
* Add a converter to this library sec
* Add a converter to this library spec
*
* @param className the name of the converter class
*/
@@ -270,6 +283,15 @@ public class AntLibrarySpec {
converterClassNames.add(className);
}

/**
* Add an aspect to this the library spec
*
* @param className the name of the aspect class
*/
public void addAspect(String className) {
aspectClassNames.add(className);
}
/**
* Indicates if this library requires Ant's XML parser
*


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

@@ -66,7 +66,9 @@ import org.apache.ant.antcore.antlib.AntLibManager;
import org.apache.ant.antcore.antlib.AntLibrary;
import org.apache.ant.antcore.antlib.ComponentLibrary;
import org.apache.ant.antcore.antlib.DynamicLibrary;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.antlib.Aspect;
import org.apache.ant.common.antlib.Converter;
import org.apache.ant.common.antlib.DeferredTask;
import org.apache.ant.common.antlib.ExecutionComponent;
@@ -79,16 +81,21 @@ import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.Location;
import org.apache.ant.init.LoaderUtils;
import org.apache.ant.antcore.config.AntConfig;

/**
* The instance of the ComponentServices made available by the core to the
* ant libraries.
* The instance of the ComponentServices made available by the core to the ant
* libraries.
*
* @author Conor MacNeill
* @created 27 January 2002
*/
public class ComponentManager implements ComponentService {

/**
* These are AntLibraries which have been loaded into this component
* manager
*/
private static Map antLibraries = new HashMap();
/**
* Type converters for this frame. Converters are used when configuring
* Tasks to handle special type conversions.
@@ -98,6 +105,9 @@ public class ComponentManager implements ComponentService {
/** This is the set of libraries whose converters have been loaded */
private Set loadedConverters = new HashSet();

/** This is the set of libraries whose aspects have been loaded */
private Set loadedAspects = new HashSet();

/** The factory objects for each library, indexed by the library Id */
private Map libFactories = new HashMap();

@@ -108,20 +118,20 @@ public class ComponentManager implements ComponentService {
private AntLibManager libManager;

/**
* These are AntLibraries which have been loaded into this component
* manager
* This is the list of aspects which have been loaded from the various Ant
* libraries
*/
private static Map antLibraries = new HashMap();
private List aspects = new ArrayList();

/** dynamic libraries which have been defined */
private Map dynamicLibraries;

/** The definitions which have been imported into this frame. */
private Map definitions = new HashMap();
private Map imports = new HashMap();

/**
* This map stores a list of additional paths for each library indexed
* by the libraryId
* This map stores a list of additional paths for each library indexed by
* the libraryId
*/
private Map libPathsMap = new HashMap();

@@ -133,8 +143,11 @@ public class ComponentManager implements ComponentService {
* Constructor
*
* @param frame the frame containing this context
*
* @exception ExecutionException if the loaded libraries could not be
* imported.
*/
protected ComponentManager(Frame frame) {
protected ComponentManager(Frame frame) throws ExecutionException {
this.frame = frame;
AntConfig config = frame.getConfig();
libManager = new AntLibManager(config.isRemoteLibAllowed());
@@ -150,7 +163,7 @@ public class ComponentManager implements ComponentService {
* @param importAll if true all tasks are imported as the library is
* loaded
* @param autoImport true if libraries in the Ant namespace should be
* automatically imported.
* automatically imported.
* @exception ExecutionException if the library cannot be loaded
*/
public void loadLib(String libLocation, boolean importAll,
@@ -159,17 +172,19 @@ public class ComponentManager implements ComponentService {
try {
Map librarySpecs = new HashMap();
libManager.loadLibs(librarySpecs, libLocation);
libManager.configLibraries(frame.getInitConfig(), librarySpecs,
antLibraries, libPathsMap);
Map newLibraries = libManager.configLibraries(frame.getInitConfig(),
librarySpecs, antLibraries, libPathsMap);

Iterator i = librarySpecs.keySet().iterator();
antLibraries.putAll(newLibraries);
Iterator i = antLibraries.keySet().iterator();
while (i.hasNext()) {
String libraryId = (String) i.next();
boolean doAuto = autoImport
&& libraryId.startsWith(Constants.ANT_LIB_PREFIX);
boolean doAuto = autoImport
&& libraryId.startsWith(Constants.ANT_LIB_PREFIX);
if (importAll || doAuto) {
importLibrary(libraryId);
}
addAspects((AntLibrary) antLibraries.get(libraryId));
}
} catch (MalformedURLException e) {
throw new ExecutionException("Unable to load libraries from "
@@ -181,8 +196,7 @@ public class ComponentManager implements ComponentService {
* Experimental - define a new task
*
* @param taskName the name by which this task will be referred
* @param factory the library factory object to create the task
* instances
* @param factory the library factory object to create the task instances
* @param loader the class loader to use to create the particular tasks
* @param className the name of the class implementing the task
* @exception ExecutionException if the task cannot be defined
@@ -198,8 +212,7 @@ public class ComponentManager implements ComponentService {
* Experimental - define a new type
*
* @param typeName the name by which this type will be referred
* @param factory the library factory object to create the type
* instances
* @param factory the library factory object to create the type instances
* @param loader the class loader to use to create the particular types
* @param className the name of the class implementing the type
* @exception ExecutionException if the type cannot be defined
@@ -251,15 +264,15 @@ public class ComponentManager implements ComponentService {
String defName = (String) i.next();
importLibraryDef(library, defName, null);
}
addLibraryConverters(library);
addConverters(library);
}

/**
* Import a single component from a library, optionally aliasing it to a
* new name
*
* @param libraryId the unique id of the library from which the
* component is being imported
* @param libraryId the unique id of the library from which the component
* is being imported
* @param defName the name of the component within its library
* @param alias the name under which this component will be used in the
* build scripts. If this is null, the components default name is
@@ -274,11 +287,11 @@ public class ComponentManager implements ComponentService {
+ "library \"" + libraryId + "\" as it has not been loaded");
}
importLibraryDef(library, defName, alias);
addLibraryConverters(library);
addConverters(library);
}

/**
* Imports a component defined in a nother frame.
* Imports a component defined in another frame.
*
* @param relativeName the qualified name of the component relative to
* this execution frame
@@ -306,7 +319,7 @@ public class ComponentManager implements ComponentService {
+ "> as <" + label + "> from library \""
+ definition.getComponentLibrary().getLibraryId() + "\", class: "
+ definition.getClassName(), MessageLevel.MSG_DEBUG);
definitions.put(label, definition);
imports.put(label, definition);
}

/**
@@ -321,30 +334,36 @@ public class ComponentManager implements ComponentService {
*/
public Object createComponent(String componentName)
throws ExecutionException {
return createComponent(componentName, null);
return createComponent(componentName, (BuildElement) null);
}

/**
* Create a component given its class. The component will have a context
* but will not be configured. It should be configured using the
* appropriate set methods and then validated before being used.
* Create a component given its libraryId and local name within the
* library. This method is unambiguous in the face of imports, aliases and
* taskdefs performed in the build.
*
* @param componentClass the component's class
* @param factory the factory to create the component
* @param loader the classloader associated with the component
* @param addTaskAdapter whenther the returned component should be a
* task, potentially being wrapped in an adapter
* @param componentName the name of the component type
* @param libraryId the component's library identifier.
* @param localName the name component within the library.
* @return the created component. The return type of this method depends
* on the component type.
* @exception ExecutionException if the component cannot be created
*/
public Object createComponent(AntLibFactory factory, ClassLoader loader,
Class componentClass, boolean addTaskAdapter,
String componentName)
public Object createComponent(String libraryId, String localName)
throws ExecutionException {
return createComponent(loader, factory, componentClass,
componentName, componentName, addTaskAdapter, null);
AntLibrary library
= (AntLibrary) antLibraries.get(libraryId);
if (library == null) {
throw new ExecutionException("No library with libraryId \""
+ libraryId + "\" is available");
}

AntLibDefinition libDefinition = library.getDefinition(localName);
if (libDefinition == null) {
throw new ExecutionException("No component with name \""
+ localName + "\" was found in library with libraryId \""
+ libraryId + "\"");
}
return createComponentFromDef(localName, library, libDefinition, null);
}

/**
@@ -361,8 +380,8 @@ public class ComponentManager implements ComponentService {
* Get the collection of Ant Libraries defined for this frame Gets the
* factory object for the given library
*
* @param componentLibrary the compnent library for which a factory
* objetc is required
* @param componentLibrary the compnent library for which a factory objetc
* is required
* @return the library's factory object
* @exception ExecutionException if the factory cannot be created
*/
@@ -386,11 +405,11 @@ public class ComponentManager implements ComponentService {
* Get an imported definition from the component manager
*
* @param name the name under which the component has been imported
* @return the ImportInfo object detailing the import's library and
* other details
* @return the ImportInfo object detailing the import's library and other
* details
*/
protected ImportInfo getDefinition(String name) {
return (ImportInfo) definitions.get(name);
protected ImportInfo getImport(String name) {
return (ImportInfo) imports.get(name);
}

/**
@@ -409,10 +428,11 @@ public class ComponentManager implements ComponentService {
}

/**
* Create a component.
* Create a component. This method creates a component and then configures
* it from the given build model.
*
* @param componentName the name of the component which is used to
* select the object type to be created
* @param componentName the name of the component which is used to select
* the object type to be created
* @param model the build model of the component. If this is null, the
* component is created but not configured.
* @return the configured component
@@ -422,38 +442,119 @@ public class ComponentManager implements ComponentService {
protected Object createComponent(String componentName, BuildElement model)
throws ExecutionException {

Location location = Location.UNKNOWN_LOCATION;
if (model != null) {
location = model.getLocation();
}
ImportInfo definition = getDefinition(componentName);
if (definition == null) {
ImportInfo importInfo = getImport(componentName);
if (importInfo == null) {
throw new ExecutionException("There is no definition of the <"
+ componentName + "> component");
}
String className = definition.getClassName();
String className = importInfo.getClassName();

ComponentLibrary componentLibrary
= definition.getComponentLibrary();
boolean isTask = definition.getDefinitionType() == AntLibrary.TASKDEF;
String localName = definition.getLocalName();
= importInfo.getComponentLibrary();

return createComponentFromDef(componentName, componentLibrary,
importInfo.getDefinition(), model);
}

/**
* Create a component from its library definition.
*
* @param componentName The component's name in the global context
* @param componentLibrary the library which provides the deifnition of
* the component
* @param libDefinition the component's definition
* @param model the BuildElement model of the component's configuration.
* @return the required component potentially wrapped in a wrapper object.
* @exception ExecutionException if the component cannot be created
*/
private Object createComponentFromDef(String componentName,
ComponentLibrary componentLibrary,
AntLibDefinition libDefinition,
BuildElement model)
throws ExecutionException {

Location location = Location.UNKNOWN_LOCATION;
if (model != null) {
location = model.getLocation();
}

boolean isTask
= libDefinition.getDefinitionType() == AntLibrary.TASKDEF;
String localName = libDefinition.getDefinitionName();
String className = libDefinition.getClassName();
try {
ClassLoader componentLoader = componentLibrary.getClassLoader();
Class componentClass
= Class.forName(className, true, componentLoader);
AntLibFactory libFactory = getLibFactory(componentLibrary);
return createComponent(componentLoader, libFactory, componentClass,
componentName, localName, isTask, model);
// create the component using the factory
Object component
= libFactory.createComponent(componentClass, localName);

// wrap the component in an adapter if required.
ExecutionComponent execComponent = null;
if (isTask) {
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(componentLoader);

// 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(componentLoader);
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(libFactory, 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 (ClassNotFoundException e) {
throw new ExecutionException("Class " + className
+ " for component <" + componentName + "> was not found", e,
location);
} catch (NoClassDefFoundError e) {
throw new ExecutionException("Could not load a dependent class ("
+ e.getMessage() + ") for component " + componentName,
e, location);
+ e.getMessage() + ") for component " + componentName, e,
location);
} catch (InstantiationException e) {
throw new ExecutionException("Unable to instantiate component "
+ "class " + className + " for component <"
+ componentName + ">", e, location);
} catch (IllegalAccessException e) {
throw new ExecutionException("Unable to access task class "
+ className + " for component <"
+ componentName + ">", e, location);
} catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);
e.setLocation(location, false);
throw e;
}
}
@@ -477,7 +578,7 @@ public class ComponentManager implements ComponentService {
frame.log("Adding component <" + defName + "> as <" + label
+ "> from library \"" + library.getLibraryId() + "\", class: "
+ libDef.getClassName(), MessageLevel.MSG_DEBUG);
definitions.put(label, new ImportInfo(library, libDef));
imports.put(label, new ImportInfo(library, libDef));
}

/**
@@ -514,8 +615,7 @@ public class ComponentManager implements ComponentService {
* @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.
* @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,
@@ -616,8 +716,8 @@ public class ComponentManager implements ComponentService {
= libFactory.createComponent(typeClass, localName);

if (typeInstance instanceof ExecutionComponent) {
ExecutionComponent component
= (ExecutionComponent) typeInstance;
ExecutionComponent component
= (ExecutionComponent) typeInstance;
ExecutionContext context = new ExecutionContext(frame,
component, model.getLocation());
component.init(context, localName);
@@ -650,8 +750,8 @@ public class ComponentManager implements ComponentService {
* @param element the container element in which the nested element will
* be created
* @param model the model of the nested element
* @param factory Ant Library factory associated with the element to
* which the attribute is to be added.
* @param factory Ant Library factory associated with the element to which
* the attribute is to be added.
* @exception ExecutionException if the nested element cannot be created
*/
private void addNestedElement(AntLibFactory factory, Setter setter,
@@ -734,10 +834,9 @@ public class ComponentManager implements ComponentService {
* @param element the container object for which a nested element is
* required.
* @param model the build model for the nestd element
* @param factory Ant Library factory associated with the element
* creating the nested element
* @exception ExecutionException if the nested element cannot be
* created.
* @param factory Ant Library factory associated with the element creating
* the nested element
* @exception ExecutionException if the nested element cannot be created.
*/
private void createNestedElement(AntLibFactory factory, Setter setter,
Object element, BuildElement model)
@@ -807,7 +906,7 @@ public class ComponentManager implements ComponentService {
for (Iterator i = model.getNestedElements(); i.hasNext();) {
BuildElement nestedElementModel = (BuildElement) i.next();
String nestedElementName = nestedElementModel.getType();
ImportInfo info = getDefinition(nestedElementName);
ImportInfo info = getImport(nestedElementName);
if (element instanceof TaskContainer
&& info != null
&& info.getDefinitionType() == AntLibrary.TASKDEF
@@ -858,6 +957,63 @@ public class ComponentManager implements ComponentService {
}


/**
* Load any apsects from the given library.
*
* @param library the library from which the aspects are to be loaded.
*
* @exception ExecutionException if an aspect cannot be loaded.
*/
private void addAspects(AntLibrary library) throws ExecutionException {
if (!library.hasAspects()
|| loadedAspects.contains(library.getLibraryId())) {
return;
}

String className = null;
try {
AntLibFactory libFactory = getLibFactory(library);
ClassLoader aspectLoader = library.getClassLoader();
for (Iterator i = library.getAspectClassNames(); i.hasNext();) {
className = (String) i.next();
Class aspectClass
= Class.forName(className, true, aspectLoader);
if (!Aspect.class.isAssignableFrom(aspectClass)) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId() + "\" the aspect class "
+ aspectClass.getName()
+ " does not implement the Aspect interface");
}
Aspect aspect = (Aspect) libFactory.createInstance(aspectClass);
ExecutionContext context = new ExecutionContext(frame,
null, Location.UNKNOWN_LOCATION);
aspect.init(context);
aspects.add(aspect);
}
loadedAspects.add(library.getLibraryId());
} catch (ClassNotFoundException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId() + "\" aspect class "
+ className + " was not found", e);
} catch (NoClassDefFoundError e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" could not load a dependent class ("
+ e.getMessage() + ") for aspect " + className);
} catch (InstantiationException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" unable to instantiate aspect class "
+ className, e);
} catch (IllegalAccessException e) {
throw new ExecutionException("In Ant library \""
+ library.getLibraryId()
+ "\" unable to access aspect class "
+ className, e);
}
}


/**
* Add the converters from the given library to those managed by this
* frame.
@@ -866,7 +1022,7 @@ public class ComponentManager implements ComponentService {
* @exception ExecutionException if a converter defined in the library
* cannot be instantiated
*/
private void addLibraryConverters(AntLibrary library)
private void addConverters(AntLibrary library)
throws ExecutionException {
if (!library.hasConverters()
|| loadedConverters.contains(library.getLibraryId())) {
@@ -888,7 +1044,7 @@ public class ComponentManager implements ComponentService {
+ " does not implement the Converter interface");
}
Converter converter
= libFactory.createConverter(converterClass);
= (Converter) libFactory.createInstance(converterClass);
ExecutionContext context = new ExecutionContext(frame,
null, Location.UNKNOWN_LOCATION);
converter.init(context);
@@ -919,5 +1075,14 @@ public class ComponentManager implements ComponentService {
+ className, e);
}
}

/**
* Get the aspects which have been registered from ant libraries.
*
* @return the list of Aspect instances currently defined.
*/
protected List getAspects() {
return aspects;
}
}


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

@@ -59,13 +59,11 @@ import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.modelparser.XMLProjectParser;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitUtils;
import org.apache.ant.init.LoaderUtils;

/**
* This is the core's implementation of the Execution Service.
@@ -100,36 +98,7 @@ public class CoreExecService implements ExecService {
* @exception ExecutionException if there is an execution problem
*/
public void executeTask(Task task) throws ExecutionException {
AntContext context = task.getAntContext();

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

frame.getEventSupport().fireTaskStarted(task);

Throwable failureCause = null;

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

task.execute();
LoaderUtils.setContextLoader(currentLoader);
} catch (ExecutionException e) {
failureCause = e;
throw e;
} catch (Throwable e) {
ExecutionException ee =
new ExecutionException(e);

failureCause = ee;
throw ee;
} finally {
frame.getEventSupport().fireTaskFinished(task, failureCause);
}
frame.executeTask(task);
}




+ 4
- 2
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java View File

@@ -148,9 +148,11 @@ public class ExecutionManager implements DemuxOutputReceiver {
} catch (RuntimeException e) {
buildFailureCause = e;
throw e;
} catch (AntException e) {
} catch (ExecutionException e) {
ExecutionException ee = e instanceof ExecutionException
? e : new ExecutionException(e);
buildFailureCause = e;
throw e;
throw ee;
} finally {
eventSupport.fireBuildFinished(project, buildFailureCause);
}


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

@@ -61,8 +61,11 @@ import java.util.Map;
import java.util.StringTokenizer;
import java.util.List;
import java.util.ArrayList;
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;
@@ -79,6 +82,7 @@ import org.apache.ant.common.util.DemuxOutputReceiver;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
import org.apache.ant.init.InitConfig;
import org.apache.ant.init.LoaderUtils;

/**
* An Frame maintains the state of a project during an execution. The Frame
@@ -98,6 +102,13 @@ public class Frame implements DemuxOutputReceiver {
/** The referenced frames corresponding to the referenced projects */
private Map referencedFrames = new HashMap();

/**
* This is a Map of Maps. This map is keyed on an executing task.
* Each entry is itself a Map of Aspects to their context for the
* particular task.
*/
private Map aspectContextsMap = new HashMap();
/**
* The property overrides for the referenced frames. This map is indexed
* by the reference names of the frame. Each entry is another Map of
@@ -390,7 +401,7 @@ public class Frame implements DemuxOutputReceiver {
+ "to the name \"" + definitionName + "\"");
}
if (containingFrame == this) {
return componentManager.getDefinition(localName);
return componentManager.getImport(localName);
} else {
return containingFrame.getReferencedDefinition(localName);
}
@@ -656,8 +667,6 @@ public class Frame implements DemuxOutputReceiver {
referencedFrame.setInitialProperties(initialProperties);
overrides.remove(name);
}


referencedFrames.put(name, referencedFrame);
referencedFrame.initialize();
@@ -850,6 +859,68 @@ public class Frame implements DemuxOutputReceiver {
}
}

/**
* Execute a task notifiying all registered aspects of the fact
*
* @param task the Task instance to execute.
*
* @exception ExecutionException if the task has a problem.
*/
protected void executeTask(Task task) 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);
}
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;

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

task.execute();
LoaderUtils.setContextLoader(currentLoader);
} catch (Throwable e) {
failureCause = e;
}

// Now call back the aspects that registered interest
Set activeAspects = aspectContexts.keySet();
for (Iterator i = activeAspects.iterator(); i.hasNext();) {
Aspect aspect = (Aspect) i.next();
Object aspectContext = aspectContexts.get(aspect);
failureCause
= aspect.postExecuteTask(aspectContext, failureCause);
}
eventSupport.fireTaskFinished(task, failureCause);
if (aspectContexts.size() != 0) {
aspectContextsMap.remove(task);
}
if (failureCause != null) {
if (failureCause instanceof ExecutionException) {
throw (ExecutionException) failureCause;
}
throw new ExecutionException(failureCause);
}
}

/**
* Run the tasks returned by the given iterator
@@ -860,23 +931,26 @@ public class Frame implements DemuxOutputReceiver {
*/
protected void executeTasks(Iterator taskIterator)
throws ExecutionException {
while (taskIterator.hasNext()) {
BuildElement model = (BuildElement) taskIterator.next();

// what sort of element is this.
List aspects = componentManager.getAspects();
try {
Object component = componentManager.createComponent(model);

if (component instanceof Task) {
execService.executeTask((Task) component);
} else {
String typeId
= model.getAspectValue(Constants.ANT_ASPECT, "id");

if (typeId != null) {
setDataValue(typeId, component, true);
for (Iterator i = aspects.iterator(); i.hasNext();) {
Aspect aspect = (Aspect) i.next();
Object replacement
= aspect.postCreateComponent(component, model);
if (replacement != null) {
component = replacement;
}
}

if (component instanceof Task) {
executeTask((Task) component);
}
} catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);
throw e;
@@ -1009,8 +1083,11 @@ public class Frame implements DemuxOutputReceiver {
/**
* Configure the services that the frame makes available to its library
* components
*
* @exception ExecutionException if the services required by the core
* could not be configured.
*/
private void configureServices() {
private void configureServices() throws ExecutionException {
// create services and make them available in our services map
fileService = new CoreFileService(this);
componentManager = new ComponentManager(this);


+ 8
- 0
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java View File

@@ -116,5 +116,13 @@ public class ImportInfo {
return libDefinition.getDefinitionName();
}

/**
* Get the definition of the imported component.
*
* @return the component's library definition.
*/
public AntLibDefinition getDefinition() {
return libDefinition;
}
}


+ 18
- 18
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java View File

@@ -53,7 +53,6 @@
*/
package org.apache.tools.ant;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.Converter;
import org.apache.ant.common.antlib.StandardLibFactory;
import org.apache.ant.common.service.EventService;
import org.apache.ant.common.util.ExecutionException;
@@ -145,40 +144,41 @@ public class Ant1Factory extends StandardLibFactory {
}

/**
* Create a converter.
* Create an instance of the given class
*
* @param converterClass the class of the converter.
* @return an instance of the requested converter class
* @exception InstantiationException if the converter cannot be
* instantiated
* @exception IllegalAccessException if the converter cannot be accessed
* @exception ExecutionException if the converter cannot be created
* @param requiredClass the class for which an instance is
* required
* @return a instance of the required class
* @exception InstantiationException if the class cannot be instantiated
* @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the
* converter
*/
public Converter createConverter(Class converterClass)
public Object createInstance(Class requiredClass)
throws InstantiationException, IllegalAccessException,
ExecutionException {

java.lang.reflect.Constructor c = null;

Converter converter = null;
Object instance = null;
try {
try {
c = converterClass.getConstructor(new Class[0]);
converter = (Converter) c.newInstance(new Object[0]);
c = requiredClass.getConstructor(new Class[0]);
instance = c.newInstance(new Object[0]);
} catch (NoSuchMethodException nse) {
c = converterClass.getConstructor(new Class[]{Project.class});
converter = (Converter) c.newInstance(new Object[]{project});
c = requiredClass.getConstructor(new Class[]{Project.class});
instance = c.newInstance(new Object[]{project});
}

return converter;
return instance;
} catch (java.lang.reflect.InvocationTargetException ite) {
Throwable t = ite.getTargetException();
String msg = "Could not create converter of type: "
+ converterClass.getName() + " due to " + t;
String msg = "Could not create instance of type: "
+ requiredClass.getName() + " due to " + t;
throw new ExecutionException(msg, t);
} catch (NoSuchMethodException e) {
throw new ExecutionException("Unable to find an appropriate "
+ "constructor for converter " + converterClass.getName(), e);
+ "constructor for class " + requiredClass.getName(), e);
}
}



+ 2
- 5
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java View File

@@ -1058,8 +1058,7 @@ public class Project implements org.apache.ant.common.event.BuildListener {
}

try {
Object taskObject = componentService.createComponent(factory,
context.getClassLoader(), taskClass, false, taskType);
Object taskObject = componentService.createComponent(taskType);
if (taskObject instanceof Task) {
task = (Task) taskObject;
} else {
@@ -1093,9 +1092,7 @@ public class Project implements org.apache.ant.common.event.BuildListener {
}

try {
Object dataInstance = componentService.createComponent(factory,
context.getClassLoader(), typeClass, false, typeName);
return dataInstance;
return componentService.createComponent(typeName);
} catch (Throwable e) {
throw new BuildException(e);
}


+ 1
- 3
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/Ant.java View File

@@ -146,9 +146,7 @@ public class Ant extends Task {
ComponentService componentService = getComponentService();
AntLibFactory factory = getProject().getFactory();
realAnt = (org.apache.ant.antlib.system.Ant)
componentService.createComponent(factory,
context.getClassLoader(),
org.apache.ant.antlib.system.Ant.class, false, "antcall");
componentService.createComponent("ant.system", "ant");
} catch (ExecutionException e) {
throw new BuildException(e);
}


+ 2
- 2
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/CallTarget.java View File

@@ -102,8 +102,8 @@ public class CallTarget extends Task {
try {
ComponentService componentService = getComponentService();
AntLibFactory factory = getProject().getFactory();
antCall = (AntCall) componentService.createComponent(factory,
context.getClassLoader(), AntCall.class, false, "antcall");
antCall = (AntCall) componentService.createComponent("ant.system",
"antcall");
} catch (ExecutionException e) {
throw new BuildException(e);
}


+ 3
- 1
proposal/mutant/src/java/antlibs/system/antlib.xml View File

@@ -15,5 +15,7 @@
<converter classname="org.apache.ant.antlib.system.FileConverter"/>
<converter classname="org.apache.ant.antlib.system.URLConverter"/>
<converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/>
<converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/>

<aspect classname="org.apache.ant.antlib.system.AntAspect"/>
</antlib>

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

@@ -0,0 +1,107 @@
/*
* 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;
import org.apache.ant.common.antlib.AbstractAspect;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.model.BuildElement;

/**
* The Ant aspect - handles all ant aspects
*
* @author Conor MacNeill
*/
public class AntAspect extends AbstractAspect {
/** The Ant aspect used to identify Ant metadata */
public static final String ANT_ASPECT = "ant";
/** The core's data service implementation */
private DataService dataService = null;

/**
* Initialise the aspect with a context.
*
* @param context the aspect's context
* @exception ExecutionException if the aspect cannot be initialised
*/
public void init(AntContext context) throws ExecutionException {
super.init(context);
dataService = (DataService) context.getCoreService(DataService.class);
}
/**
* This join point is activated after a component has been created and
* configured. If the aspect wishes, an object can be returned in place
* of the one created by Ant.
*
* @param component the component that has been created.
* @param model the Build model used to create the component.
*
* @return a replacement for the component if desired. If null is returned
* the current component is used.
* @exception ExecutionException if the component cannot be processed.
*/
public Object postCreateComponent(Object component, BuildElement model)
throws ExecutionException {
String typeId = model.getAspectValue(ANT_ASPECT, "id");
if (typeId != null) {
dataService.setMutableDataValue(typeId, component);
}
return null;
}
}


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

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

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

/**
* An implementation of the Aspect interface providing default behaviour.
*
* @author Conor MacNeill
*/
public class AbstractAspect implements Aspect {
/**
* The Ant context for this aspect which can be used to access core
* services.
*/
private AntContext context;
/**
* Initialise the aspect with a context.
*
* @param context the aspect's context
* @exception ExecutionException if the aspect cannot be initialised
*/
public void init(AntContext context) throws ExecutionException {
this.context = context;
}

/**
* Get this aspect's context
*
* @return the aspect context
*/
protected AntContext getAntContext() {
return context;
}

/**
* This join point is activated after a component has been created and
* configured. If the aspect wishes, an object can be returned in place
* of the one created by Ant.
*
* @param component the component that has been created.
* @param model the Build model used to create the component.
*
* @return a replacement for the component if desired. If null is returned
* the current component is used.
* @exception ExecutionException if the aspect cannot process the component.
*/
public Object postCreateComponent(Object component, BuildElement model)
throws ExecutionException {
return null;
}

/**
* 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
* 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 {
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) {
return failureCause;
}

/**
* This point is activated when the task is to receive output that has
* been sent to output stream and redirected into the task.
*
* @param context the context the aspect provided in preExecuteTask.
* @param line the content sent to the output stream.
*
* @return the line to be forwarded onto the task.
*/
public String taskOutput(Object context, String line) {
return line;
}

/**
* This point is activated when the task is to receive error content that
* has been sent to error stream and redirected into the task.
*
* @param context the context the aspect provided in preExecuteTask.
* @param line the content sent to the error stream.
*
* @return the line to be forwarded onto the task.
*/
public String taskError(Object context, String line) {
return line;
}
}


+ 4
- 4
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java View File

@@ -88,17 +88,17 @@ public interface AntLibFactory {
ExecutionException;

/**
* Create an instance of the given converter class
* Create an instance of the given class
*
* @param converterClass the converter class for which an instance is
* @param requiredClass the class for which an instance is
* required
* @return a converter instance
* @return a instance of the required class
* @exception InstantiationException if the class cannot be instantiated
* @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the
* converter
*/
Converter createConverter(Class converterClass)
Object createInstance(Class requiredClass)
throws InstantiationException, IllegalAccessException,
ExecutionException;



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

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

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

/**
* An aspect is a component which is activated across all task and
* component operations. It allows a single implmentation to be applied
* to a number of tasks without requiring changes to the task implementations.
*
* @author Conor MacNeill
*/
public interface Aspect {
/**
* Initialise the aspect with a context.
*
* @param context the aspect's context
* @exception ExecutionException if the aspect cannot be initialised
*/
void init(AntContext context)
throws ExecutionException;

/**
* This join point is activated after a component has been created and
* configured. If the aspect wishes, an object can be returned in place
* of the one created by Ant.
*
* @param component the component that has been created.
* @param model the Build model used to create the component.
*
* @return a replacement for the component if desired. If null is returned
* the current component is used.
* @exception ExecutionException if the aspect cannot process the component.
*/
Object postCreateComponent(Object component, BuildElement model)
throws ExecutionException;

/**
* 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
* 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;
/**
* 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.
*/
Throwable postExecuteTask(Object context, Throwable failureCause);

/**
* This point is activated when the task is to receive output that has
* been sent to output stream and redirected into the task.
*
* @param context the context the aspect provided in preExecuteTask.
* @param line the content sent to the output stream.
*
* @return the line to be forwarded onto the task.
*/
String taskOutput(Object context, String line);

/**
* This point is activated when the task is to receive error content that
* has been sent to error stream and redirected into the task.
*
* @param context the context the aspect provided in preExecuteTask.
* @param line the content sent to the error stream.
*
* @return the line to be forwarded onto the task.
*/
String taskError(Object context, String line);
}


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

@@ -63,10 +63,10 @@ import org.apache.ant.common.util.ExecutionException;
*/
public interface ExecutionComponent {
/**
* Initialise the task. The task may use the AntContext to request
* Initialise the component. The component may use the AntContext to request
* services from the Ant core.
*
* @param context the Task's context
* @param context the Component's context
* @param componentType the type of the component
* @exception ExecutionException if the component cannot be initialised
*/


+ 5
- 5
proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java View File

@@ -93,20 +93,20 @@ public class StandardLibFactory implements AntLibFactory {
}

/**
* Create an instance of the given converter class
* Create an instance of the given class
*
* @param converterClass the converter class for which an instance is
* @param requiredClass the class for which an instance is
* required
* @return a converter instance
* @return a instance of the required class
* @exception InstantiationException if the class cannot be instantiated
* @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the
* converter
*/
public Converter createConverter(Class converterClass)
public Object createInstance(Class requiredClass)
throws InstantiationException, IllegalAccessException,
ExecutionException {
return (Converter) converterClass.newInstance();
return requiredClass.newInstance();
}

/**


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

@@ -174,22 +174,17 @@ public interface ComponentService {
Object createComponent(String componentName) throws ExecutionException;

/**
* Create a component given its class. The component will have a context
* but will not be configured. It should be configured using the
* appropriate set methods and then validated before being used.
* Create a component given its libraryId and local name within the
* library. This method is unambiguous in the face of imports, aliases and
* taskdefs performed in the build.
*
* @param componentClass the component's class
* @param factory the factory to create the component
* @param loader the classloader associated with the component
* @param addTaskAdapter whenther the returned component should be a
* task, potentially being wrapped in an adapter
* @param componentName the name of the component type
* @param libraryId the component's library identifier.
* @param localName the name component within the library.
* @return the created component. The return type of this method depends
* on the component type.
* @exception ExecutionException if the component cannot be created
*/
Object createComponent(AntLibFactory factory, ClassLoader loader,
Class componentClass, boolean addTaskAdapter,
String componentName) throws ExecutionException;
Object createComponent(String libraryId, String localName)
throws ExecutionException;
}


Loading…
Cancel
Save