git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272712 13f79535-47bb-0310-9956-ffa450edef68master
@@ -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(); | ||||
@@ -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); | ||||
@@ -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 | ||||
* | * | ||||
@@ -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 | ||||
* | * | ||||
@@ -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; | |||||
} | |||||
} | } | ||||
@@ -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); | |||||
} | } | ||||
@@ -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); | ||||
} | } | ||||
@@ -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); | ||||
@@ -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; | |||||
} | |||||
} | } | ||||
@@ -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); | |||||
} | } | ||||
} | } | ||||
@@ -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); | ||||
} | } | ||||
@@ -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); | ||||
} | } | ||||
@@ -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); | ||||
} | } | ||||
@@ -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> |
@@ -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; | |||||
} | |||||
} | |||||
@@ -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; | |||||
} | |||||
} | |||||
@@ -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; | ||||
@@ -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); | |||||
} | |||||
@@ -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 | ||||
*/ | */ | ||||
@@ -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(); | |||||
} | } | ||||
/** | /** | ||||
@@ -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; | |||||
} | } | ||||