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(), antLibrarySpec.addDefinition(defnHandler.getDefinitionType(),
defnHandler.getName(), defnHandler.getClassName()); defnHandler.getName(), defnHandler.getClassName());
} else if (qualifiedName.equals("converter")) { } else if (qualifiedName.equals("converter")) {
ClassNameHandler converterHandler
= new ClassNameHandler();
ClassNameHandler converterHandler = new ClassNameHandler();
converterHandler.start(getParseContext(), getXMLReader(), converterHandler.start(getParseContext(), getXMLReader(),
this, getLocator(), attributes, getElementSource(), this, getLocator(), attributes, getElementSource(),
qualifiedName); qualifiedName);
antLibrarySpec.addConverter(converterHandler.getClassName()); 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")) { } else if (qualifiedName.equals("factory")) {
ClassNameHandler factoryHandler ClassNameHandler factoryHandler
= new ClassNameHandler(); = 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.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashMap;
import org.apache.ant.antcore.xml.ParseContext; import org.apache.ant.antcore.xml.ParseContext;
import org.apache.ant.antcore.xml.XMLParseException; import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.util.CircularDependencyChecker; import org.apache.ant.common.util.CircularDependencyChecker;
@@ -153,10 +154,11 @@ public class AntLibManager {
* @param initConfig the Ant initialization configuration * @param initConfig the Ant initialization configuration
* @param libraries the collection of libraries already configured * @param libraries the collection of libraries already configured
* @param libPathsMap a map of lists of library paths for each library * @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 * @exception ExecutionException if a library cannot be configured from
* the given specification * the given specification
*/ */
public void configLibraries(InitConfig initConfig, Map librarySpecs,
public Map configLibraries(InitConfig initConfig, Map librarySpecs,
Map libraries, Map libPathsMap) Map libraries, Map libPathsMap)
throws ExecutionException { throws ExecutionException {


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


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


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


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


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


if (libPathsMap != null) { if (libPathsMap != null) {
List libPaths = (List) libPathsMap.get(libraryId); 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 */ /** The list of converter classnames defined in this library */
private List converterClassNames = new ArrayList(); 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 */ /** The class name of this library's factory class, if any */
private String factoryClassName; private String factoryClassName;


@@ -116,6 +119,7 @@ public class AntLibrary implements ComponentLibrary {
this.definitions = spec.getDefinitions(); this.definitions = spec.getDefinitions();
this.isolated = spec.isIsolated(); this.isolated = spec.isIsolated();
this.converterClassNames.addAll(spec.getConverters()); this.converterClassNames.addAll(spec.getConverters());
this.aspectClassNames.addAll(spec.getAspects());
this.factoryClassName = spec.getFactory(); this.factoryClassName = spec.getFactory();
this.definitionURL = spec.getLibraryURL(); 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 * @return an iterator over a list of String class names
*/ */
@@ -190,6 +194,15 @@ public class AntLibrary implements ComponentLibrary {
return converterClassNames.iterator(); 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 * Get the URL to where the library was loaded from
* *
@@ -251,6 +264,15 @@ public class AntLibrary implements ComponentLibrary {
return !converterClassNames.isEmpty(); 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 * 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 */ /** The list of converter classnames defined in this library */
private List converterClassNames = new ArrayList(); 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 */ /** The name of the factory class for this library */
private String factoryClassName; private String factoryClassName;


@@ -196,6 +199,16 @@ public class AntLibrarySpec {
return converterClassNames; 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 * 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 * @param className the name of the converter class
*/ */
@@ -270,6 +283,15 @@ public class AntLibrarySpec {
converterClassNames.add(className); 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 * 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.AntLibrary;
import org.apache.ant.antcore.antlib.ComponentLibrary; import org.apache.ant.antcore.antlib.ComponentLibrary;
import org.apache.ant.antcore.antlib.DynamicLibrary; 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.AntLibFactory;
import org.apache.ant.common.antlib.Aspect;
import org.apache.ant.common.antlib.Converter; import org.apache.ant.common.antlib.Converter;
import org.apache.ant.common.antlib.DeferredTask; import org.apache.ant.common.antlib.DeferredTask;
import org.apache.ant.common.antlib.ExecutionComponent; 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.ExecutionException;
import org.apache.ant.common.util.Location; import org.apache.ant.common.util.Location;
import org.apache.ant.init.LoaderUtils; 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 * @author Conor MacNeill
* @created 27 January 2002 * @created 27 January 2002
*/ */
public class ComponentManager implements ComponentService { 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 * Type converters for this frame. Converters are used when configuring
* Tasks to handle special type conversions. * 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 */ /** This is the set of libraries whose converters have been loaded */
private Set loadedConverters = new HashSet(); 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 */ /** The factory objects for each library, indexed by the library Id */
private Map libFactories = new HashMap(); private Map libFactories = new HashMap();


@@ -108,20 +118,20 @@ public class ComponentManager implements ComponentService {
private AntLibManager libManager; 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 */ /** dynamic libraries which have been defined */
private Map dynamicLibraries; private Map dynamicLibraries;


/** The definitions which have been imported into this frame. */ /** 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(); private Map libPathsMap = new HashMap();


@@ -133,8 +143,11 @@ public class ComponentManager implements ComponentService {
* Constructor * Constructor
* *
* @param frame the frame containing this context * @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; this.frame = frame;
AntConfig config = frame.getConfig(); AntConfig config = frame.getConfig();
libManager = new AntLibManager(config.isRemoteLibAllowed()); 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 * @param importAll if true all tasks are imported as the library is
* loaded * loaded
* @param autoImport true if libraries in the Ant namespace should be * @param autoImport true if libraries in the Ant namespace should be
* automatically imported.
* automatically imported.
* @exception ExecutionException if the library cannot be loaded * @exception ExecutionException if the library cannot be loaded
*/ */
public void loadLib(String libLocation, boolean importAll, public void loadLib(String libLocation, boolean importAll,
@@ -159,17 +172,19 @@ public class ComponentManager implements ComponentService {
try { try {
Map librarySpecs = new HashMap(); Map librarySpecs = new HashMap();
libManager.loadLibs(librarySpecs, libLocation); 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()) { while (i.hasNext()) {
String libraryId = (String) i.next(); 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) { if (importAll || doAuto) {
importLibrary(libraryId); importLibrary(libraryId);
} }
addAspects((AntLibrary) antLibraries.get(libraryId));
} }
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
throw new ExecutionException("Unable to load libraries from " throw new ExecutionException("Unable to load libraries from "
@@ -181,8 +196,7 @@ public class ComponentManager implements ComponentService {
* Experimental - define a new task * Experimental - define a new task
* *
* @param taskName the name by which this task will be referred * @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 loader the class loader to use to create the particular tasks
* @param className the name of the class implementing the task * @param className the name of the class implementing the task
* @exception ExecutionException if the task cannot be defined * @exception ExecutionException if the task cannot be defined
@@ -198,8 +212,7 @@ public class ComponentManager implements ComponentService {
* Experimental - define a new type * Experimental - define a new type
* *
* @param typeName the name by which this type will be referred * @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 loader the class loader to use to create the particular types
* @param className the name of the class implementing the type * @param className the name of the class implementing the type
* @exception ExecutionException if the type cannot be defined * @exception ExecutionException if the type cannot be defined
@@ -251,15 +264,15 @@ public class ComponentManager implements ComponentService {
String defName = (String) i.next(); String defName = (String) i.next();
importLibraryDef(library, defName, null); importLibraryDef(library, defName, null);
} }
addLibraryConverters(library);
addConverters(library);
} }


/** /**
* Import a single component from a library, optionally aliasing it to a * Import a single component from a library, optionally aliasing it to a
* new name * 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 defName the name of the component within its library
* @param alias the name under which this component will be used in the * @param alias the name under which this component will be used in the
* build scripts. If this is null, the components default name is * 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"); + "library \"" + libraryId + "\" as it has not been loaded");
} }
importLibraryDef(library, defName, alias); 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 * @param relativeName the qualified name of the component relative to
* this execution frame * this execution frame
@@ -306,7 +319,7 @@ public class ComponentManager implements ComponentService {
+ "> as <" + label + "> from library \"" + "> as <" + label + "> from library \""
+ definition.getComponentLibrary().getLibraryId() + "\", class: " + definition.getComponentLibrary().getLibraryId() + "\", class: "
+ definition.getClassName(), MessageLevel.MSG_DEBUG); + 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) public Object createComponent(String componentName)
throws ExecutionException { 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 * @return the created component. The return type of this method depends
* on the component type. * on the component type.
* @exception ExecutionException if the component cannot be created * @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 { 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 * Get the collection of Ant Libraries defined for this frame Gets the
* factory object for the given library * 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 * @return the library's factory object
* @exception ExecutionException if the factory cannot be created * @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 * Get an imported definition from the component manager
* *
* @param name the name under which the component has been imported * @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 * @param model the build model of the component. If this is null, the
* component is created but not configured. * component is created but not configured.
* @return the configured component * @return the configured component
@@ -422,38 +442,119 @@ public class ComponentManager implements ComponentService {
protected Object createComponent(String componentName, BuildElement model) protected Object createComponent(String componentName, BuildElement model)
throws ExecutionException { 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 <" throw new ExecutionException("There is no definition of the <"
+ componentName + "> component"); + componentName + "> component");
} }
String className = definition.getClassName();
String className = importInfo.getClassName();


ComponentLibrary componentLibrary 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 { try {
ClassLoader componentLoader = componentLibrary.getClassLoader(); ClassLoader componentLoader = componentLibrary.getClassLoader();
Class componentClass Class componentClass
= Class.forName(className, true, componentLoader); = Class.forName(className, true, componentLoader);
AntLibFactory libFactory = getLibFactory(componentLibrary); 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) { } catch (ClassNotFoundException e) {
throw new ExecutionException("Class " + className throw new ExecutionException("Class " + className
+ " for component <" + componentName + "> was not found", e, + " for component <" + componentName + "> was not found", e,
location); location);
} catch (NoClassDefFoundError e) { } catch (NoClassDefFoundError e) {
throw new ExecutionException("Could not load a dependent class (" 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) { } catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);
e.setLocation(location, false);
throw e; throw e;
} }
} }
@@ -477,7 +578,7 @@ public class ComponentManager implements ComponentService {
frame.log("Adding component <" + defName + "> as <" + label frame.log("Adding component <" + defName + "> as <" + label
+ "> from library \"" + library.getLibraryId() + "\", class: " + "> from library \"" + library.getLibraryId() + "\", class: "
+ libDef.getClassName(), MessageLevel.MSG_DEBUG); + 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 localName The name of the component within its library
* @param model the BuildElement model of the component's configuration * @param model the BuildElement model of the component's configuration
* @param factory the facrtory object used to create the component * @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 * @exception ExecutionException if the component cannot be created
*/ */
private Object createComponent(ClassLoader loader, AntLibFactory factory, private Object createComponent(ClassLoader loader, AntLibFactory factory,
@@ -616,8 +716,8 @@ public class ComponentManager implements ComponentService {
= libFactory.createComponent(typeClass, localName); = libFactory.createComponent(typeClass, localName);


if (typeInstance instanceof ExecutionComponent) { if (typeInstance instanceof ExecutionComponent) {
ExecutionComponent component
= (ExecutionComponent) typeInstance;
ExecutionComponent component
= (ExecutionComponent) typeInstance;
ExecutionContext context = new ExecutionContext(frame, ExecutionContext context = new ExecutionContext(frame,
component, model.getLocation()); component, model.getLocation());
component.init(context, localName); component.init(context, localName);
@@ -650,8 +750,8 @@ public class ComponentManager implements ComponentService {
* @param element the container element in which the nested element will * @param element the container element in which the nested element will
* be created * be created
* @param model the model of the nested element * @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 * @exception ExecutionException if the nested element cannot be created
*/ */
private void addNestedElement(AntLibFactory factory, Setter setter, 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 * @param element the container object for which a nested element is
* required. * required.
* @param model the build model for the nestd element * @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, private void createNestedElement(AntLibFactory factory, Setter setter,
Object element, BuildElement model) Object element, BuildElement model)
@@ -807,7 +906,7 @@ public class ComponentManager implements ComponentService {
for (Iterator i = model.getNestedElements(); i.hasNext();) { for (Iterator i = model.getNestedElements(); i.hasNext();) {
BuildElement nestedElementModel = (BuildElement) i.next(); BuildElement nestedElementModel = (BuildElement) i.next();
String nestedElementName = nestedElementModel.getType(); String nestedElementName = nestedElementModel.getType();
ImportInfo info = getDefinition(nestedElementName);
ImportInfo info = getImport(nestedElementName);
if (element instanceof TaskContainer if (element instanceof TaskContainer
&& info != null && info != null
&& info.getDefinitionType() == AntLibrary.TASKDEF && 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 * Add the converters from the given library to those managed by this
* frame. * frame.
@@ -866,7 +1022,7 @@ public class ComponentManager implements ComponentService {
* @exception ExecutionException if a converter defined in the library * @exception ExecutionException if a converter defined in the library
* cannot be instantiated * cannot be instantiated
*/ */
private void addLibraryConverters(AntLibrary library)
private void addConverters(AntLibrary library)
throws ExecutionException { throws ExecutionException {
if (!library.hasConverters() if (!library.hasConverters()
|| loadedConverters.contains(library.getLibraryId())) { || loadedConverters.contains(library.getLibraryId())) {
@@ -888,7 +1044,7 @@ public class ComponentManager implements ComponentService {
+ " does not implement the Converter interface"); + " does not implement the Converter interface");
} }
Converter converter Converter converter
= libFactory.createConverter(converterClass);
= (Converter) libFactory.createInstance(converterClass);
ExecutionContext context = new ExecutionContext(frame, ExecutionContext context = new ExecutionContext(frame,
null, Location.UNKNOWN_LOCATION); null, Location.UNKNOWN_LOCATION);
converter.init(context); converter.init(context);
@@ -919,5 +1075,14 @@ public class ComponentManager implements ComponentService {
+ className, e); + 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 java.util.Map;
import org.apache.ant.antcore.modelparser.XMLProjectParser; import org.apache.ant.antcore.modelparser.XMLProjectParser;
import org.apache.ant.antcore.xml.XMLParseException; 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.antlib.Task;
import org.apache.ant.common.model.Project; import org.apache.ant.common.model.Project;
import org.apache.ant.common.service.ExecService; import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitUtils; import org.apache.ant.init.InitUtils;
import org.apache.ant.init.LoaderUtils;


/** /**
* This is the core's implementation of the Execution Service. * 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 * @exception ExecutionException if there is an execution problem
*/ */
public void executeTask(Task task) throws ExecutionException { public void executeTask(Task task) throws ExecutionException {
AntContext context = task.getAntContext();

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) { } catch (RuntimeException e) {
buildFailureCause = e; buildFailureCause = e;
throw e; throw e;
} catch (AntException e) {
} catch (ExecutionException e) {
ExecutionException ee = e instanceof ExecutionException
? e : new ExecutionException(e);
buildFailureCause = e; buildFailureCause = e;
throw e;
throw ee;
} finally { } finally {
eventSupport.fireBuildFinished(project, buildFailureCause); 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.StringTokenizer;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set;
import org.apache.ant.antcore.config.AntConfig; import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.common.antlib.Task; 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.BuildListener;
import org.apache.ant.common.event.MessageLevel; import org.apache.ant.common.event.MessageLevel;
import org.apache.ant.common.model.BuildElement; 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.ExecutionException;
import org.apache.ant.common.util.FileUtils; import org.apache.ant.common.util.FileUtils;
import org.apache.ant.init.InitConfig; 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 * 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 */ /** The referenced frames corresponding to the referenced projects */
private Map referencedFrames = new HashMap(); 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 * The property overrides for the referenced frames. This map is indexed
* by the reference names of the frame. Each entry is another Map of * 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 + "\""); + "to the name \"" + definitionName + "\"");
} }
if (containingFrame == this) { if (containingFrame == this) {
return componentManager.getDefinition(localName);
return componentManager.getImport(localName);
} else { } else {
return containingFrame.getReferencedDefinition(localName); return containingFrame.getReferencedDefinition(localName);
} }
@@ -656,8 +667,6 @@ public class Frame implements DemuxOutputReceiver {
referencedFrame.setInitialProperties(initialProperties); referencedFrame.setInitialProperties(initialProperties);
overrides.remove(name); overrides.remove(name);
} }


referencedFrames.put(name, referencedFrame); referencedFrames.put(name, referencedFrame);
referencedFrame.initialize(); 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 * Run the tasks returned by the given iterator
@@ -860,23 +931,26 @@ public class Frame implements DemuxOutputReceiver {
*/ */
protected void executeTasks(Iterator taskIterator) protected void executeTasks(Iterator taskIterator)
throws ExecutionException { throws ExecutionException {
while (taskIterator.hasNext()) { while (taskIterator.hasNext()) {
BuildElement model = (BuildElement) taskIterator.next(); BuildElement model = (BuildElement) taskIterator.next();


// what sort of element is this. // what sort of element is this.
List aspects = componentManager.getAspects();
try { try {
Object component = componentManager.createComponent(model); 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) { } catch (ExecutionException e) {
e.setLocation(model.getLocation(), false); e.setLocation(model.getLocation(), false);
throw e; throw e;
@@ -1009,8 +1083,11 @@ public class Frame implements DemuxOutputReceiver {
/** /**
* Configure the services that the frame makes available to its library * Configure the services that the frame makes available to its library
* components * 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 // create services and make them available in our services map
fileService = new CoreFileService(this); fileService = new CoreFileService(this);
componentManager = new ComponentManager(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(); 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; package org.apache.tools.ant;
import org.apache.ant.common.antlib.AntContext; 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.antlib.StandardLibFactory;
import org.apache.ant.common.service.EventService; import org.apache.ant.common.service.EventService;
import org.apache.ant.common.util.ExecutionException; 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, throws InstantiationException, IllegalAccessException,
ExecutionException { ExecutionException {


java.lang.reflect.Constructor c = null; java.lang.reflect.Constructor c = null;


Converter converter = null;
Object instance = null;
try { try {
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) { } 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) { } catch (java.lang.reflect.InvocationTargetException ite) {
Throwable t = ite.getTargetException(); 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); throw new ExecutionException(msg, t);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
throw new ExecutionException("Unable to find an appropriate " 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 { try {
Object taskObject = componentService.createComponent(factory,
context.getClassLoader(), taskClass, false, taskType);
Object taskObject = componentService.createComponent(taskType);
if (taskObject instanceof Task) { if (taskObject instanceof Task) {
task = (Task) taskObject; task = (Task) taskObject;
} else { } else {
@@ -1093,9 +1092,7 @@ public class Project implements org.apache.ant.common.event.BuildListener {
} }


try { try {
Object dataInstance = componentService.createComponent(factory,
context.getClassLoader(), typeClass, false, typeName);
return dataInstance;
return componentService.createComponent(typeName);
} catch (Throwable e) { } catch (Throwable e) {
throw new BuildException(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(); ComponentService componentService = getComponentService();
AntLibFactory factory = getProject().getFactory(); AntLibFactory factory = getProject().getFactory();
realAnt = (org.apache.ant.antlib.system.Ant) 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) { } catch (ExecutionException e) {
throw new BuildException(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 { try {
ComponentService componentService = getComponentService(); ComponentService componentService = getComponentService();
AntLibFactory factory = getProject().getFactory(); 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) { } catch (ExecutionException e) {
throw new BuildException(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.FileConverter"/>
<converter classname="org.apache.ant.antlib.system.URLConverter"/> <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> </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; 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 * required
* @return a converter instance
* @return a instance of the required class
* @exception InstantiationException if the class cannot be instantiated * @exception InstantiationException if the class cannot be instantiated
* @exception IllegalAccessException if the instance cannot be accessed * @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the * @exception ExecutionException if there is a problem creating the
* converter * converter
*/ */
Converter createConverter(Class converterClass)
Object createInstance(Class requiredClass)
throws InstantiationException, IllegalAccessException, throws InstantiationException, IllegalAccessException,
ExecutionException; 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 { 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. * services from the Ant core.
* *
* @param context the Task's context
* @param context the Component's context
* @param componentType the type of the component * @param componentType the type of the component
* @exception ExecutionException if the component cannot be initialised * @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 * required
* @return a converter instance
* @return a instance of the required class
* @exception InstantiationException if the class cannot be instantiated * @exception InstantiationException if the class cannot be instantiated
* @exception IllegalAccessException if the instance cannot be accessed * @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the * @exception ExecutionException if there is a problem creating the
* converter * converter
*/ */
public Converter createConverter(Class converterClass)
public Object createInstance(Class requiredClass)
throws InstantiationException, IllegalAccessException, throws InstantiationException, IllegalAccessException,
ExecutionException { 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; 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 * @return the created component. The return type of this method depends
* on the component type. * on the component type.
* @exception ExecutionException if the component cannot be created * @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