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(), | |||
defnHandler.getName(), defnHandler.getClassName()); | |||
} else if (qualifiedName.equals("converter")) { | |||
ClassNameHandler converterHandler | |||
= new ClassNameHandler(); | |||
ClassNameHandler converterHandler = new ClassNameHandler(); | |||
converterHandler.start(getParseContext(), getXMLReader(), | |||
this, getLocator(), attributes, getElementSource(), | |||
qualifiedName); | |||
antLibrarySpec.addConverter(converterHandler.getClassName()); | |||
} else if (qualifiedName.equals("aspect")) { | |||
ClassNameHandler aspectHandler = new ClassNameHandler(); | |||
aspectHandler.start(getParseContext(), getXMLReader(), | |||
this, getLocator(), attributes, getElementSource(), | |||
qualifiedName); | |||
antLibrarySpec.addAspect(aspectHandler.getClassName()); | |||
} else if (qualifiedName.equals("factory")) { | |||
ClassNameHandler factoryHandler | |||
= new ClassNameHandler(); | |||
@@ -60,6 +60,7 @@ import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.HashMap; | |||
import org.apache.ant.antcore.xml.ParseContext; | |||
import org.apache.ant.antcore.xml.XMLParseException; | |||
import org.apache.ant.common.util.CircularDependencyChecker; | |||
@@ -153,10 +154,11 @@ public class AntLibManager { | |||
* @param initConfig the Ant initialization configuration | |||
* @param libraries the collection of libraries already configured | |||
* @param libPathsMap a map of lists of library paths for each library | |||
* @return A map of the newly configured libraries | |||
* @exception ExecutionException if a library cannot be configured from | |||
* the given specification | |||
*/ | |||
public void configLibraries(InitConfig initConfig, Map librarySpecs, | |||
public Map configLibraries(InitConfig initConfig, Map librarySpecs, | |||
Map libraries, Map libPathsMap) | |||
throws ExecutionException { | |||
@@ -180,15 +182,18 @@ public class AntLibManager { | |||
} | |||
} | |||
Map newLibraries = new HashMap(); | |||
CircularDependencyChecker configuring | |||
= new CircularDependencyChecker("configuring Ant libraries"); | |||
for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext();) { | |||
String libraryId = (String) i.next(); | |||
if (!libraries.containsKey(libraryId)) { | |||
configLibrary(initConfig, librarySpecs, libraryId, | |||
configuring, libraries, libPathsMap); | |||
configuring, libraries, newLibraries, libPathsMap); | |||
} | |||
} | |||
return newLibraries; | |||
} | |||
/** | |||
@@ -267,13 +272,14 @@ public class AntLibManager { | |||
* dependencies. | |||
* @param libraries the collection of libraries which have already been | |||
* configured | |||
* @param newLibraries the new libraries being configured. | |||
* @param libPathsMap a map of lists of library patsh fro each library | |||
* @exception ExecutionException if the library cannot be configured. | |||
*/ | |||
private void configLibrary(InitConfig initConfig, Map librarySpecs, | |||
String libraryId, | |||
CircularDependencyChecker configuring, | |||
Map libraries, Map libPathsMap) | |||
Map libraries, Map newLibraries, Map libPathsMap) | |||
throws ExecutionException { | |||
try { | |||
@@ -283,14 +289,15 @@ public class AntLibManager { | |||
= (AntLibrarySpec) librarySpecs.get(libraryId); | |||
String extendsId = librarySpec.getExtendsLibraryId(); | |||
if (extendsId != null) { | |||
if (!libraries.containsKey(extendsId)) { | |||
if (!libraries.containsKey(extendsId) && | |||
!newLibraries.containsKey(extendsId)) { | |||
if (!librarySpecs.containsKey(extendsId)) { | |||
throw new ExecutionException("Could not find library, " | |||
+ extendsId + ", upon which library " | |||
+ libraryId + " depends"); | |||
} | |||
configLibrary(initConfig, librarySpecs, extendsId, | |||
configuring, libraries, libPathsMap); | |||
configuring, libraries, newLibraries, libPathsMap); | |||
} | |||
} | |||
@@ -323,10 +330,14 @@ public class AntLibManager { | |||
if (extendsId != null) { | |||
AntLibrary extendsLibrary | |||
= (AntLibrary) libraries.get(extendsId); | |||
if (extendsLibrary == null) { | |||
extendsLibrary = (AntLibrary) newLibraries.get(extendsId); | |||
} | |||
antLibrary.setExtendsLibrary(extendsLibrary); | |||
} | |||
antLibrary.setParentLoader(initConfig.getCommonLoader()); | |||
libraries.put(libraryId, antLibrary); | |||
newLibraries.put(libraryId, antLibrary); | |||
if (libPathsMap != null) { | |||
List libPaths = (List) libPathsMap.get(libraryId); | |||
@@ -88,6 +88,9 @@ public class AntLibrary implements ComponentLibrary { | |||
/** The list of converter classnames defined in this library */ | |||
private List converterClassNames = new ArrayList(); | |||
/** The list of aspect classnames defined in this library */ | |||
private List aspectClassNames = new ArrayList(); | |||
/** The class name of this library's factory class, if any */ | |||
private String factoryClassName; | |||
@@ -116,6 +119,7 @@ public class AntLibrary implements ComponentLibrary { | |||
this.definitions = spec.getDefinitions(); | |||
this.isolated = spec.isIsolated(); | |||
this.converterClassNames.addAll(spec.getConverters()); | |||
this.aspectClassNames.addAll(spec.getAspects()); | |||
this.factoryClassName = spec.getFactory(); | |||
this.definitionURL = spec.getLibraryURL(); | |||
} | |||
@@ -182,7 +186,7 @@ public class AntLibrary implements ComponentLibrary { | |||
} | |||
/** | |||
* Gets an the converter class names of the AntLibrary | |||
* Gets the converter class names of the AntLibrary | |||
* | |||
* @return an iterator over a list of String class names | |||
*/ | |||
@@ -190,6 +194,15 @@ public class AntLibrary implements ComponentLibrary { | |||
return converterClassNames.iterator(); | |||
} | |||
/** | |||
* Gets the aspect class names of the AntLibrary | |||
* | |||
* @return an iterator over a list of String class names | |||
*/ | |||
public Iterator getAspectClassNames() { | |||
return aspectClassNames.iterator(); | |||
} | |||
/** | |||
* Get the URL to where the library was loaded from | |||
* | |||
@@ -251,6 +264,15 @@ public class AntLibrary implements ComponentLibrary { | |||
return !converterClassNames.isEmpty(); | |||
} | |||
/** | |||
* Indicate whether this library has any aspects defined | |||
* | |||
* @return true if any aspects have been defined | |||
*/ | |||
public boolean hasAspects() { | |||
return !aspectClassNames.isEmpty(); | |||
} | |||
/** | |||
* Add a library to path to this AntLibrary definition | |||
* | |||
@@ -85,6 +85,9 @@ public class AntLibrarySpec { | |||
/** The list of converter classnames defined in this library */ | |||
private List converterClassNames = new ArrayList(); | |||
/** The list of aspect classnames defined in this library */ | |||
private List aspectClassNames = new ArrayList(); | |||
/** The name of the factory class for this library */ | |||
private String factoryClassName; | |||
@@ -196,6 +199,16 @@ public class AntLibrarySpec { | |||
return converterClassNames; | |||
} | |||
/** | |||
* Get the list of aspect classnames defined in this library spec | |||
* | |||
* @return the aspect classnames list | |||
*/ | |||
public List getAspects() { | |||
return aspectClassNames; | |||
} | |||
/** | |||
* Gets the factory classname of the AntLibrarySpec | |||
* | |||
@@ -262,7 +275,7 @@ public class AntLibrarySpec { | |||
} | |||
/** | |||
* Add a converter to this library sec | |||
* Add a converter to this library spec | |||
* | |||
* @param className the name of the converter class | |||
*/ | |||
@@ -270,6 +283,15 @@ public class AntLibrarySpec { | |||
converterClassNames.add(className); | |||
} | |||
/** | |||
* Add an aspect to this the library spec | |||
* | |||
* @param className the name of the aspect class | |||
*/ | |||
public void addAspect(String className) { | |||
aspectClassNames.add(className); | |||
} | |||
/** | |||
* Indicates if this library requires Ant's XML parser | |||
* | |||
@@ -66,7 +66,9 @@ import org.apache.ant.antcore.antlib.AntLibManager; | |||
import org.apache.ant.antcore.antlib.AntLibrary; | |||
import org.apache.ant.antcore.antlib.ComponentLibrary; | |||
import org.apache.ant.antcore.antlib.DynamicLibrary; | |||
import org.apache.ant.antcore.config.AntConfig; | |||
import org.apache.ant.common.antlib.AntLibFactory; | |||
import org.apache.ant.common.antlib.Aspect; | |||
import org.apache.ant.common.antlib.Converter; | |||
import org.apache.ant.common.antlib.DeferredTask; | |||
import org.apache.ant.common.antlib.ExecutionComponent; | |||
@@ -79,16 +81,21 @@ import org.apache.ant.common.service.ComponentService; | |||
import org.apache.ant.common.util.ExecutionException; | |||
import org.apache.ant.common.util.Location; | |||
import org.apache.ant.init.LoaderUtils; | |||
import org.apache.ant.antcore.config.AntConfig; | |||
/** | |||
* The instance of the ComponentServices made available by the core to the | |||
* ant libraries. | |||
* The instance of the ComponentServices made available by the core to the ant | |||
* libraries. | |||
* | |||
* @author Conor MacNeill | |||
* @created 27 January 2002 | |||
*/ | |||
public class ComponentManager implements ComponentService { | |||
/** | |||
* These are AntLibraries which have been loaded into this component | |||
* manager | |||
*/ | |||
private static Map antLibraries = new HashMap(); | |||
/** | |||
* Type converters for this frame. Converters are used when configuring | |||
* Tasks to handle special type conversions. | |||
@@ -98,6 +105,9 @@ public class ComponentManager implements ComponentService { | |||
/** This is the set of libraries whose converters have been loaded */ | |||
private Set loadedConverters = new HashSet(); | |||
/** This is the set of libraries whose aspects have been loaded */ | |||
private Set loadedAspects = new HashSet(); | |||
/** The factory objects for each library, indexed by the library Id */ | |||
private Map libFactories = new HashMap(); | |||
@@ -108,20 +118,20 @@ public class ComponentManager implements ComponentService { | |||
private AntLibManager libManager; | |||
/** | |||
* These are AntLibraries which have been loaded into this component | |||
* manager | |||
* This is the list of aspects which have been loaded from the various Ant | |||
* libraries | |||
*/ | |||
private static Map antLibraries = new HashMap(); | |||
private List aspects = new ArrayList(); | |||
/** dynamic libraries which have been defined */ | |||
private Map dynamicLibraries; | |||
/** The definitions which have been imported into this frame. */ | |||
private Map definitions = new HashMap(); | |||
private Map imports = new HashMap(); | |||
/** | |||
* This map stores a list of additional paths for each library indexed | |||
* by the libraryId | |||
* This map stores a list of additional paths for each library indexed by | |||
* the libraryId | |||
*/ | |||
private Map libPathsMap = new HashMap(); | |||
@@ -133,8 +143,11 @@ public class ComponentManager implements ComponentService { | |||
* Constructor | |||
* | |||
* @param frame the frame containing this context | |||
* | |||
* @exception ExecutionException if the loaded libraries could not be | |||
* imported. | |||
*/ | |||
protected ComponentManager(Frame frame) { | |||
protected ComponentManager(Frame frame) throws ExecutionException { | |||
this.frame = frame; | |||
AntConfig config = frame.getConfig(); | |||
libManager = new AntLibManager(config.isRemoteLibAllowed()); | |||
@@ -150,7 +163,7 @@ public class ComponentManager implements ComponentService { | |||
* @param importAll if true all tasks are imported as the library is | |||
* loaded | |||
* @param autoImport true if libraries in the Ant namespace should be | |||
* automatically imported. | |||
* automatically imported. | |||
* @exception ExecutionException if the library cannot be loaded | |||
*/ | |||
public void loadLib(String libLocation, boolean importAll, | |||
@@ -159,17 +172,19 @@ public class ComponentManager implements ComponentService { | |||
try { | |||
Map librarySpecs = new HashMap(); | |||
libManager.loadLibs(librarySpecs, libLocation); | |||
libManager.configLibraries(frame.getInitConfig(), librarySpecs, | |||
antLibraries, libPathsMap); | |||
Map newLibraries = libManager.configLibraries(frame.getInitConfig(), | |||
librarySpecs, antLibraries, libPathsMap); | |||
Iterator i = librarySpecs.keySet().iterator(); | |||
antLibraries.putAll(newLibraries); | |||
Iterator i = antLibraries.keySet().iterator(); | |||
while (i.hasNext()) { | |||
String libraryId = (String) i.next(); | |||
boolean doAuto = autoImport | |||
&& libraryId.startsWith(Constants.ANT_LIB_PREFIX); | |||
boolean doAuto = autoImport | |||
&& libraryId.startsWith(Constants.ANT_LIB_PREFIX); | |||
if (importAll || doAuto) { | |||
importLibrary(libraryId); | |||
} | |||
addAspects((AntLibrary) antLibraries.get(libraryId)); | |||
} | |||
} catch (MalformedURLException e) { | |||
throw new ExecutionException("Unable to load libraries from " | |||
@@ -181,8 +196,7 @@ public class ComponentManager implements ComponentService { | |||
* Experimental - define a new task | |||
* | |||
* @param taskName the name by which this task will be referred | |||
* @param factory the library factory object to create the task | |||
* instances | |||
* @param factory the library factory object to create the task instances | |||
* @param loader the class loader to use to create the particular tasks | |||
* @param className the name of the class implementing the task | |||
* @exception ExecutionException if the task cannot be defined | |||
@@ -198,8 +212,7 @@ public class ComponentManager implements ComponentService { | |||
* Experimental - define a new type | |||
* | |||
* @param typeName the name by which this type will be referred | |||
* @param factory the library factory object to create the type | |||
* instances | |||
* @param factory the library factory object to create the type instances | |||
* @param loader the class loader to use to create the particular types | |||
* @param className the name of the class implementing the type | |||
* @exception ExecutionException if the type cannot be defined | |||
@@ -251,15 +264,15 @@ public class ComponentManager implements ComponentService { | |||
String defName = (String) i.next(); | |||
importLibraryDef(library, defName, null); | |||
} | |||
addLibraryConverters(library); | |||
addConverters(library); | |||
} | |||
/** | |||
* Import a single component from a library, optionally aliasing it to a | |||
* new name | |||
* | |||
* @param libraryId the unique id of the library from which the | |||
* component is being imported | |||
* @param libraryId the unique id of the library from which the component | |||
* is being imported | |||
* @param defName the name of the component within its library | |||
* @param alias the name under which this component will be used in the | |||
* build scripts. If this is null, the components default name is | |||
@@ -274,11 +287,11 @@ public class ComponentManager implements ComponentService { | |||
+ "library \"" + libraryId + "\" as it has not been loaded"); | |||
} | |||
importLibraryDef(library, defName, alias); | |||
addLibraryConverters(library); | |||
addConverters(library); | |||
} | |||
/** | |||
* Imports a component defined in a nother frame. | |||
* Imports a component defined in another frame. | |||
* | |||
* @param relativeName the qualified name of the component relative to | |||
* this execution frame | |||
@@ -306,7 +319,7 @@ public class ComponentManager implements ComponentService { | |||
+ "> as <" + label + "> from library \"" | |||
+ definition.getComponentLibrary().getLibraryId() + "\", class: " | |||
+ definition.getClassName(), MessageLevel.MSG_DEBUG); | |||
definitions.put(label, definition); | |||
imports.put(label, definition); | |||
} | |||
/** | |||
@@ -321,30 +334,36 @@ public class ComponentManager implements ComponentService { | |||
*/ | |||
public Object createComponent(String componentName) | |||
throws ExecutionException { | |||
return createComponent(componentName, null); | |||
return createComponent(componentName, (BuildElement) null); | |||
} | |||
/** | |||
* Create a component given its class. The component will have a context | |||
* but will not be configured. It should be configured using the | |||
* appropriate set methods and then validated before being used. | |||
* Create a component given its libraryId and local name within the | |||
* library. This method is unambiguous in the face of imports, aliases and | |||
* taskdefs performed in the build. | |||
* | |||
* @param componentClass the component's class | |||
* @param factory the factory to create the component | |||
* @param loader the classloader associated with the component | |||
* @param addTaskAdapter whenther the returned component should be a | |||
* task, potentially being wrapped in an adapter | |||
* @param componentName the name of the component type | |||
* @param libraryId the component's library identifier. | |||
* @param localName the name component within the library. | |||
* @return the created component. The return type of this method depends | |||
* on the component type. | |||
* @exception ExecutionException if the component cannot be created | |||
*/ | |||
public Object createComponent(AntLibFactory factory, ClassLoader loader, | |||
Class componentClass, boolean addTaskAdapter, | |||
String componentName) | |||
public Object createComponent(String libraryId, String localName) | |||
throws ExecutionException { | |||
return createComponent(loader, factory, componentClass, | |||
componentName, componentName, addTaskAdapter, null); | |||
AntLibrary library | |||
= (AntLibrary) antLibraries.get(libraryId); | |||
if (library == null) { | |||
throw new ExecutionException("No library with libraryId \"" | |||
+ libraryId + "\" is available"); | |||
} | |||
AntLibDefinition libDefinition = library.getDefinition(localName); | |||
if (libDefinition == null) { | |||
throw new ExecutionException("No component with name \"" | |||
+ localName + "\" was found in library with libraryId \"" | |||
+ libraryId + "\""); | |||
} | |||
return createComponentFromDef(localName, library, libDefinition, null); | |||
} | |||
/** | |||
@@ -361,8 +380,8 @@ public class ComponentManager implements ComponentService { | |||
* Get the collection of Ant Libraries defined for this frame Gets the | |||
* factory object for the given library | |||
* | |||
* @param componentLibrary the compnent library for which a factory | |||
* objetc is required | |||
* @param componentLibrary the compnent library for which a factory objetc | |||
* is required | |||
* @return the library's factory object | |||
* @exception ExecutionException if the factory cannot be created | |||
*/ | |||
@@ -386,11 +405,11 @@ public class ComponentManager implements ComponentService { | |||
* Get an imported definition from the component manager | |||
* | |||
* @param name the name under which the component has been imported | |||
* @return the ImportInfo object detailing the import's library and | |||
* other details | |||
* @return the ImportInfo object detailing the import's library and other | |||
* details | |||
*/ | |||
protected ImportInfo getDefinition(String name) { | |||
return (ImportInfo) definitions.get(name); | |||
protected ImportInfo getImport(String name) { | |||
return (ImportInfo) imports.get(name); | |||
} | |||
/** | |||
@@ -409,10 +428,11 @@ public class ComponentManager implements ComponentService { | |||
} | |||
/** | |||
* Create a component. | |||
* Create a component. This method creates a component and then configures | |||
* it from the given build model. | |||
* | |||
* @param componentName the name of the component which is used to | |||
* select the object type to be created | |||
* @param componentName the name of the component which is used to select | |||
* the object type to be created | |||
* @param model the build model of the component. If this is null, the | |||
* component is created but not configured. | |||
* @return the configured component | |||
@@ -422,38 +442,119 @@ public class ComponentManager implements ComponentService { | |||
protected Object createComponent(String componentName, BuildElement model) | |||
throws ExecutionException { | |||
Location location = Location.UNKNOWN_LOCATION; | |||
if (model != null) { | |||
location = model.getLocation(); | |||
} | |||
ImportInfo definition = getDefinition(componentName); | |||
if (definition == null) { | |||
ImportInfo importInfo = getImport(componentName); | |||
if (importInfo == null) { | |||
throw new ExecutionException("There is no definition of the <" | |||
+ componentName + "> component"); | |||
} | |||
String className = definition.getClassName(); | |||
String className = importInfo.getClassName(); | |||
ComponentLibrary componentLibrary | |||
= definition.getComponentLibrary(); | |||
boolean isTask = definition.getDefinitionType() == AntLibrary.TASKDEF; | |||
String localName = definition.getLocalName(); | |||
= importInfo.getComponentLibrary(); | |||
return createComponentFromDef(componentName, componentLibrary, | |||
importInfo.getDefinition(), model); | |||
} | |||
/** | |||
* Create a component from its library definition. | |||
* | |||
* @param componentName The component's name in the global context | |||
* @param componentLibrary the library which provides the deifnition of | |||
* the component | |||
* @param libDefinition the component's definition | |||
* @param model the BuildElement model of the component's configuration. | |||
* @return the required component potentially wrapped in a wrapper object. | |||
* @exception ExecutionException if the component cannot be created | |||
*/ | |||
private Object createComponentFromDef(String componentName, | |||
ComponentLibrary componentLibrary, | |||
AntLibDefinition libDefinition, | |||
BuildElement model) | |||
throws ExecutionException { | |||
Location location = Location.UNKNOWN_LOCATION; | |||
if (model != null) { | |||
location = model.getLocation(); | |||
} | |||
boolean isTask | |||
= libDefinition.getDefinitionType() == AntLibrary.TASKDEF; | |||
String localName = libDefinition.getDefinitionName(); | |||
String className = libDefinition.getClassName(); | |||
try { | |||
ClassLoader componentLoader = componentLibrary.getClassLoader(); | |||
Class componentClass | |||
= Class.forName(className, true, componentLoader); | |||
AntLibFactory libFactory = getLibFactory(componentLibrary); | |||
return createComponent(componentLoader, libFactory, componentClass, | |||
componentName, localName, isTask, model); | |||
// create the component using the factory | |||
Object component | |||
= libFactory.createComponent(componentClass, localName); | |||
// wrap the component in an adapter if required. | |||
ExecutionComponent execComponent = null; | |||
if (isTask) { | |||
if (component instanceof Task) { | |||
execComponent = (Task) component; | |||
} else { | |||
execComponent = new TaskAdapter(componentName, component); | |||
} | |||
} else if (component instanceof ExecutionComponent) { | |||
execComponent = (ExecutionComponent) component; | |||
} | |||
// set the context loader to that for the component | |||
ClassLoader currentLoader | |||
= LoaderUtils.setContextLoader(componentLoader); | |||
// if the component is an execution component create a context and | |||
// initialise the component with it. | |||
if (execComponent != null) { | |||
ExecutionContext context | |||
= new ExecutionContext(frame, execComponent, location); | |||
context.setClassLoader(componentLoader); | |||
execComponent.init(context, componentName); | |||
} | |||
// if we have a model, use it to configure the component. Otherwise | |||
// the caller is expected to configure thre object | |||
if (model != null) { | |||
configureElement(libFactory, component, model); | |||
// if the component is an execution component and we have a | |||
// model, validate it | |||
if (execComponent != null) { | |||
execComponent.validateComponent(); | |||
} | |||
} | |||
// reset the loader | |||
LoaderUtils.setContextLoader(currentLoader); | |||
// if we have an execution component, potentially a wrapper, | |||
// return it otherwise the component directly | |||
if (execComponent != null) { | |||
return execComponent; | |||
} else { | |||
return component; | |||
} | |||
} catch (ClassNotFoundException e) { | |||
throw new ExecutionException("Class " + className | |||
+ " for component <" + componentName + "> was not found", e, | |||
location); | |||
} catch (NoClassDefFoundError e) { | |||
throw new ExecutionException("Could not load a dependent class (" | |||
+ e.getMessage() + ") for component " + componentName, | |||
e, location); | |||
+ e.getMessage() + ") for component " + componentName, e, | |||
location); | |||
} catch (InstantiationException e) { | |||
throw new ExecutionException("Unable to instantiate component " | |||
+ "class " + className + " for component <" | |||
+ componentName + ">", e, location); | |||
} catch (IllegalAccessException e) { | |||
throw new ExecutionException("Unable to access task class " | |||
+ className + " for component <" | |||
+ componentName + ">", e, location); | |||
} catch (ExecutionException e) { | |||
e.setLocation(model.getLocation(), false); | |||
e.setLocation(location, false); | |||
throw e; | |||
} | |||
} | |||
@@ -477,7 +578,7 @@ public class ComponentManager implements ComponentService { | |||
frame.log("Adding component <" + defName + "> as <" + label | |||
+ "> from library \"" + library.getLibraryId() + "\", class: " | |||
+ libDef.getClassName(), MessageLevel.MSG_DEBUG); | |||
definitions.put(label, new ImportInfo(library, libDef)); | |||
imports.put(label, new ImportInfo(library, libDef)); | |||
} | |||
/** | |||
@@ -514,8 +615,7 @@ public class ComponentManager implements ComponentService { | |||
* @param localName The name of the component within its library | |||
* @param model the BuildElement model of the component's configuration | |||
* @param factory the facrtory object used to create the component | |||
* @return the required component potentially wrapped in a wrapper | |||
* object. | |||
* @return the required component potentially wrapped in a wrapper object. | |||
* @exception ExecutionException if the component cannot be created | |||
*/ | |||
private Object createComponent(ClassLoader loader, AntLibFactory factory, | |||
@@ -616,8 +716,8 @@ public class ComponentManager implements ComponentService { | |||
= libFactory.createComponent(typeClass, localName); | |||
if (typeInstance instanceof ExecutionComponent) { | |||
ExecutionComponent component | |||
= (ExecutionComponent) typeInstance; | |||
ExecutionComponent component | |||
= (ExecutionComponent) typeInstance; | |||
ExecutionContext context = new ExecutionContext(frame, | |||
component, model.getLocation()); | |||
component.init(context, localName); | |||
@@ -650,8 +750,8 @@ public class ComponentManager implements ComponentService { | |||
* @param element the container element in which the nested element will | |||
* be created | |||
* @param model the model of the nested element | |||
* @param factory Ant Library factory associated with the element to | |||
* which the attribute is to be added. | |||
* @param factory Ant Library factory associated with the element to which | |||
* the attribute is to be added. | |||
* @exception ExecutionException if the nested element cannot be created | |||
*/ | |||
private void addNestedElement(AntLibFactory factory, Setter setter, | |||
@@ -734,10 +834,9 @@ public class ComponentManager implements ComponentService { | |||
* @param element the container object for which a nested element is | |||
* required. | |||
* @param model the build model for the nestd element | |||
* @param factory Ant Library factory associated with the element | |||
* creating the nested element | |||
* @exception ExecutionException if the nested element cannot be | |||
* created. | |||
* @param factory Ant Library factory associated with the element creating | |||
* the nested element | |||
* @exception ExecutionException if the nested element cannot be created. | |||
*/ | |||
private void createNestedElement(AntLibFactory factory, Setter setter, | |||
Object element, BuildElement model) | |||
@@ -807,7 +906,7 @@ public class ComponentManager implements ComponentService { | |||
for (Iterator i = model.getNestedElements(); i.hasNext();) { | |||
BuildElement nestedElementModel = (BuildElement) i.next(); | |||
String nestedElementName = nestedElementModel.getType(); | |||
ImportInfo info = getDefinition(nestedElementName); | |||
ImportInfo info = getImport(nestedElementName); | |||
if (element instanceof TaskContainer | |||
&& info != null | |||
&& info.getDefinitionType() == AntLibrary.TASKDEF | |||
@@ -858,6 +957,63 @@ public class ComponentManager implements ComponentService { | |||
} | |||
/** | |||
* Load any apsects from the given library. | |||
* | |||
* @param library the library from which the aspects are to be loaded. | |||
* | |||
* @exception ExecutionException if an aspect cannot be loaded. | |||
*/ | |||
private void addAspects(AntLibrary library) throws ExecutionException { | |||
if (!library.hasAspects() | |||
|| loadedAspects.contains(library.getLibraryId())) { | |||
return; | |||
} | |||
String className = null; | |||
try { | |||
AntLibFactory libFactory = getLibFactory(library); | |||
ClassLoader aspectLoader = library.getClassLoader(); | |||
for (Iterator i = library.getAspectClassNames(); i.hasNext();) { | |||
className = (String) i.next(); | |||
Class aspectClass | |||
= Class.forName(className, true, aspectLoader); | |||
if (!Aspect.class.isAssignableFrom(aspectClass)) { | |||
throw new ExecutionException("In Ant library \"" | |||
+ library.getLibraryId() + "\" the aspect class " | |||
+ aspectClass.getName() | |||
+ " does not implement the Aspect interface"); | |||
} | |||
Aspect aspect = (Aspect) libFactory.createInstance(aspectClass); | |||
ExecutionContext context = new ExecutionContext(frame, | |||
null, Location.UNKNOWN_LOCATION); | |||
aspect.init(context); | |||
aspects.add(aspect); | |||
} | |||
loadedAspects.add(library.getLibraryId()); | |||
} catch (ClassNotFoundException e) { | |||
throw new ExecutionException("In Ant library \"" | |||
+ library.getLibraryId() + "\" aspect class " | |||
+ className + " was not found", e); | |||
} catch (NoClassDefFoundError e) { | |||
throw new ExecutionException("In Ant library \"" | |||
+ library.getLibraryId() | |||
+ "\" could not load a dependent class (" | |||
+ e.getMessage() + ") for aspect " + className); | |||
} catch (InstantiationException e) { | |||
throw new ExecutionException("In Ant library \"" | |||
+ library.getLibraryId() | |||
+ "\" unable to instantiate aspect class " | |||
+ className, e); | |||
} catch (IllegalAccessException e) { | |||
throw new ExecutionException("In Ant library \"" | |||
+ library.getLibraryId() | |||
+ "\" unable to access aspect class " | |||
+ className, e); | |||
} | |||
} | |||
/** | |||
* Add the converters from the given library to those managed by this | |||
* frame. | |||
@@ -866,7 +1022,7 @@ public class ComponentManager implements ComponentService { | |||
* @exception ExecutionException if a converter defined in the library | |||
* cannot be instantiated | |||
*/ | |||
private void addLibraryConverters(AntLibrary library) | |||
private void addConverters(AntLibrary library) | |||
throws ExecutionException { | |||
if (!library.hasConverters() | |||
|| loadedConverters.contains(library.getLibraryId())) { | |||
@@ -888,7 +1044,7 @@ public class ComponentManager implements ComponentService { | |||
+ " does not implement the Converter interface"); | |||
} | |||
Converter converter | |||
= libFactory.createConverter(converterClass); | |||
= (Converter) libFactory.createInstance(converterClass); | |||
ExecutionContext context = new ExecutionContext(frame, | |||
null, Location.UNKNOWN_LOCATION); | |||
converter.init(context); | |||
@@ -919,5 +1075,14 @@ public class ComponentManager implements ComponentService { | |||
+ className, e); | |||
} | |||
} | |||
/** | |||
* Get the aspects which have been registered from ant libraries. | |||
* | |||
* @return the list of Aspect instances currently defined. | |||
*/ | |||
protected List getAspects() { | |||
return aspects; | |||
} | |||
} | |||
@@ -59,13 +59,11 @@ import java.util.List; | |||
import java.util.Map; | |||
import org.apache.ant.antcore.modelparser.XMLProjectParser; | |||
import org.apache.ant.antcore.xml.XMLParseException; | |||
import org.apache.ant.common.antlib.AntContext; | |||
import org.apache.ant.common.antlib.Task; | |||
import org.apache.ant.common.model.Project; | |||
import org.apache.ant.common.service.ExecService; | |||
import org.apache.ant.common.util.ExecutionException; | |||
import org.apache.ant.init.InitUtils; | |||
import org.apache.ant.init.LoaderUtils; | |||
/** | |||
* This is the core's implementation of the Execution Service. | |||
@@ -100,36 +98,7 @@ public class CoreExecService implements ExecService { | |||
* @exception ExecutionException if there is an execution problem | |||
*/ | |||
public void executeTask(Task task) throws ExecutionException { | |||
AntContext context = task.getAntContext(); | |||
if (!(context instanceof ExecutionContext)) { | |||
throw new ExecutionException("The Task was not configured with an" | |||
+ " appropriate context"); | |||
} | |||
ExecutionContext execContext = (ExecutionContext) context; | |||
frame.getEventSupport().fireTaskStarted(task); | |||
Throwable failureCause = null; | |||
try { | |||
ClassLoader currentLoader | |||
= LoaderUtils.setContextLoader(execContext.getClassLoader()); | |||
task.execute(); | |||
LoaderUtils.setContextLoader(currentLoader); | |||
} catch (ExecutionException e) { | |||
failureCause = e; | |||
throw e; | |||
} catch (Throwable e) { | |||
ExecutionException ee = | |||
new ExecutionException(e); | |||
failureCause = ee; | |||
throw ee; | |||
} finally { | |||
frame.getEventSupport().fireTaskFinished(task, failureCause); | |||
} | |||
frame.executeTask(task); | |||
} | |||
@@ -148,9 +148,11 @@ public class ExecutionManager implements DemuxOutputReceiver { | |||
} catch (RuntimeException e) { | |||
buildFailureCause = e; | |||
throw e; | |||
} catch (AntException e) { | |||
} catch (ExecutionException e) { | |||
ExecutionException ee = e instanceof ExecutionException | |||
? e : new ExecutionException(e); | |||
buildFailureCause = e; | |||
throw e; | |||
throw ee; | |||
} finally { | |||
eventSupport.fireBuildFinished(project, buildFailureCause); | |||
} | |||
@@ -61,8 +61,11 @@ import java.util.Map; | |||
import java.util.StringTokenizer; | |||
import java.util.List; | |||
import java.util.ArrayList; | |||
import java.util.Set; | |||
import org.apache.ant.antcore.config.AntConfig; | |||
import org.apache.ant.common.antlib.Task; | |||
import org.apache.ant.common.antlib.Aspect; | |||
import org.apache.ant.common.antlib.AntContext; | |||
import org.apache.ant.common.event.BuildListener; | |||
import org.apache.ant.common.event.MessageLevel; | |||
import org.apache.ant.common.model.BuildElement; | |||
@@ -79,6 +82,7 @@ import org.apache.ant.common.util.DemuxOutputReceiver; | |||
import org.apache.ant.common.util.ExecutionException; | |||
import org.apache.ant.common.util.FileUtils; | |||
import org.apache.ant.init.InitConfig; | |||
import org.apache.ant.init.LoaderUtils; | |||
/** | |||
* An Frame maintains the state of a project during an execution. The Frame | |||
@@ -98,6 +102,13 @@ public class Frame implements DemuxOutputReceiver { | |||
/** The referenced frames corresponding to the referenced projects */ | |||
private Map referencedFrames = new HashMap(); | |||
/** | |||
* This is a Map of Maps. This map is keyed on an executing task. | |||
* Each entry is itself a Map of Aspects to their context for the | |||
* particular task. | |||
*/ | |||
private Map aspectContextsMap = new HashMap(); | |||
/** | |||
* The property overrides for the referenced frames. This map is indexed | |||
* by the reference names of the frame. Each entry is another Map of | |||
@@ -390,7 +401,7 @@ public class Frame implements DemuxOutputReceiver { | |||
+ "to the name \"" + definitionName + "\""); | |||
} | |||
if (containingFrame == this) { | |||
return componentManager.getDefinition(localName); | |||
return componentManager.getImport(localName); | |||
} else { | |||
return containingFrame.getReferencedDefinition(localName); | |||
} | |||
@@ -656,8 +667,6 @@ public class Frame implements DemuxOutputReceiver { | |||
referencedFrame.setInitialProperties(initialProperties); | |||
overrides.remove(name); | |||
} | |||
referencedFrames.put(name, referencedFrame); | |||
referencedFrame.initialize(); | |||
@@ -850,6 +859,68 @@ public class Frame implements DemuxOutputReceiver { | |||
} | |||
} | |||
/** | |||
* Execute a task notifiying all registered aspects of the fact | |||
* | |||
* @param task the Task instance to execute. | |||
* | |||
* @exception ExecutionException if the task has a problem. | |||
*/ | |||
protected void executeTask(Task task) throws ExecutionException { | |||
List aspects = componentManager.getAspects(); | |||
Map aspectContexts = new HashMap(); | |||
for (Iterator i = aspects.iterator(); i.hasNext();) { | |||
Aspect aspect = (Aspect) i.next(); | |||
Object context = aspect.preExecuteTask(task); | |||
aspectContexts.put(aspect, context); | |||
} | |||
if (aspectContexts.size() != 0) { | |||
aspectContextsMap.put(task, aspectContexts); | |||
} | |||
AntContext context = task.getAntContext(); | |||
if (!(context instanceof ExecutionContext)) { | |||
throw new ExecutionException("The Task was not configured with an" | |||
+ " appropriate context"); | |||
} | |||
ExecutionContext execContext = (ExecutionContext) context; | |||
eventSupport.fireTaskStarted(task); | |||
Throwable failureCause = null; | |||
try { | |||
ClassLoader currentLoader | |||
= LoaderUtils.setContextLoader(execContext.getClassLoader()); | |||
task.execute(); | |||
LoaderUtils.setContextLoader(currentLoader); | |||
} catch (Throwable e) { | |||
failureCause = e; | |||
} | |||
// Now call back the aspects that registered interest | |||
Set activeAspects = aspectContexts.keySet(); | |||
for (Iterator i = activeAspects.iterator(); i.hasNext();) { | |||
Aspect aspect = (Aspect) i.next(); | |||
Object aspectContext = aspectContexts.get(aspect); | |||
failureCause | |||
= aspect.postExecuteTask(aspectContext, failureCause); | |||
} | |||
eventSupport.fireTaskFinished(task, failureCause); | |||
if (aspectContexts.size() != 0) { | |||
aspectContextsMap.remove(task); | |||
} | |||
if (failureCause != null) { | |||
if (failureCause instanceof ExecutionException) { | |||
throw (ExecutionException) failureCause; | |||
} | |||
throw new ExecutionException(failureCause); | |||
} | |||
} | |||
/** | |||
* Run the tasks returned by the given iterator | |||
@@ -860,23 +931,26 @@ public class Frame implements DemuxOutputReceiver { | |||
*/ | |||
protected void executeTasks(Iterator taskIterator) | |||
throws ExecutionException { | |||
while (taskIterator.hasNext()) { | |||
BuildElement model = (BuildElement) taskIterator.next(); | |||
// what sort of element is this. | |||
List aspects = componentManager.getAspects(); | |||
try { | |||
Object component = componentManager.createComponent(model); | |||
if (component instanceof Task) { | |||
execService.executeTask((Task) component); | |||
} else { | |||
String typeId | |||
= model.getAspectValue(Constants.ANT_ASPECT, "id"); | |||
if (typeId != null) { | |||
setDataValue(typeId, component, true); | |||
for (Iterator i = aspects.iterator(); i.hasNext();) { | |||
Aspect aspect = (Aspect) i.next(); | |||
Object replacement | |||
= aspect.postCreateComponent(component, model); | |||
if (replacement != null) { | |||
component = replacement; | |||
} | |||
} | |||
if (component instanceof Task) { | |||
executeTask((Task) component); | |||
} | |||
} catch (ExecutionException e) { | |||
e.setLocation(model.getLocation(), false); | |||
throw e; | |||
@@ -1009,8 +1083,11 @@ public class Frame implements DemuxOutputReceiver { | |||
/** | |||
* Configure the services that the frame makes available to its library | |||
* components | |||
* | |||
* @exception ExecutionException if the services required by the core | |||
* could not be configured. | |||
*/ | |||
private void configureServices() { | |||
private void configureServices() throws ExecutionException { | |||
// create services and make them available in our services map | |||
fileService = new CoreFileService(this); | |||
componentManager = new ComponentManager(this); | |||
@@ -116,5 +116,13 @@ public class ImportInfo { | |||
return libDefinition.getDefinitionName(); | |||
} | |||
/** | |||
* Get the definition of the imported component. | |||
* | |||
* @return the component's library definition. | |||
*/ | |||
public AntLibDefinition getDefinition() { | |||
return libDefinition; | |||
} | |||
} | |||
@@ -53,7 +53,6 @@ | |||
*/ | |||
package org.apache.tools.ant; | |||
import org.apache.ant.common.antlib.AntContext; | |||
import org.apache.ant.common.antlib.Converter; | |||
import org.apache.ant.common.antlib.StandardLibFactory; | |||
import org.apache.ant.common.service.EventService; | |||
import org.apache.ant.common.util.ExecutionException; | |||
@@ -145,40 +144,41 @@ public class Ant1Factory extends StandardLibFactory { | |||
} | |||
/** | |||
* Create a converter. | |||
* Create an instance of the given class | |||
* | |||
* @param converterClass the class of the converter. | |||
* @return an instance of the requested converter class | |||
* @exception InstantiationException if the converter cannot be | |||
* instantiated | |||
* @exception IllegalAccessException if the converter cannot be accessed | |||
* @exception ExecutionException if the converter cannot be created | |||
* @param requiredClass the class for which an instance is | |||
* required | |||
* @return a instance of the required class | |||
* @exception InstantiationException if the class cannot be instantiated | |||
* @exception IllegalAccessException if the instance cannot be accessed | |||
* @exception ExecutionException if there is a problem creating the | |||
* converter | |||
*/ | |||
public Converter createConverter(Class converterClass) | |||
public Object createInstance(Class requiredClass) | |||
throws InstantiationException, IllegalAccessException, | |||
ExecutionException { | |||
java.lang.reflect.Constructor c = null; | |||
Converter converter = null; | |||
Object instance = null; | |||
try { | |||
try { | |||
c = converterClass.getConstructor(new Class[0]); | |||
converter = (Converter) c.newInstance(new Object[0]); | |||
c = requiredClass.getConstructor(new Class[0]); | |||
instance = c.newInstance(new Object[0]); | |||
} catch (NoSuchMethodException nse) { | |||
c = converterClass.getConstructor(new Class[]{Project.class}); | |||
converter = (Converter) c.newInstance(new Object[]{project}); | |||
c = requiredClass.getConstructor(new Class[]{Project.class}); | |||
instance = c.newInstance(new Object[]{project}); | |||
} | |||
return converter; | |||
return instance; | |||
} catch (java.lang.reflect.InvocationTargetException ite) { | |||
Throwable t = ite.getTargetException(); | |||
String msg = "Could not create converter of type: " | |||
+ converterClass.getName() + " due to " + t; | |||
String msg = "Could not create instance of type: " | |||
+ requiredClass.getName() + " due to " + t; | |||
throw new ExecutionException(msg, t); | |||
} catch (NoSuchMethodException e) { | |||
throw new ExecutionException("Unable to find an appropriate " | |||
+ "constructor for converter " + converterClass.getName(), e); | |||
+ "constructor for class " + requiredClass.getName(), e); | |||
} | |||
} | |||
@@ -1058,8 +1058,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { | |||
} | |||
try { | |||
Object taskObject = componentService.createComponent(factory, | |||
context.getClassLoader(), taskClass, false, taskType); | |||
Object taskObject = componentService.createComponent(taskType); | |||
if (taskObject instanceof Task) { | |||
task = (Task) taskObject; | |||
} else { | |||
@@ -1093,9 +1092,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { | |||
} | |||
try { | |||
Object dataInstance = componentService.createComponent(factory, | |||
context.getClassLoader(), typeClass, false, typeName); | |||
return dataInstance; | |||
return componentService.createComponent(typeName); | |||
} catch (Throwable e) { | |||
throw new BuildException(e); | |||
} | |||
@@ -146,9 +146,7 @@ public class Ant extends Task { | |||
ComponentService componentService = getComponentService(); | |||
AntLibFactory factory = getProject().getFactory(); | |||
realAnt = (org.apache.ant.antlib.system.Ant) | |||
componentService.createComponent(factory, | |||
context.getClassLoader(), | |||
org.apache.ant.antlib.system.Ant.class, false, "antcall"); | |||
componentService.createComponent("ant.system", "ant"); | |||
} catch (ExecutionException e) { | |||
throw new BuildException(e); | |||
} | |||
@@ -102,8 +102,8 @@ public class CallTarget extends Task { | |||
try { | |||
ComponentService componentService = getComponentService(); | |||
AntLibFactory factory = getProject().getFactory(); | |||
antCall = (AntCall) componentService.createComponent(factory, | |||
context.getClassLoader(), AntCall.class, false, "antcall"); | |||
antCall = (AntCall) componentService.createComponent("ant.system", | |||
"antcall"); | |||
} catch (ExecutionException e) { | |||
throw new BuildException(e); | |||
} | |||
@@ -15,5 +15,7 @@ | |||
<converter classname="org.apache.ant.antlib.system.FileConverter"/> | |||
<converter classname="org.apache.ant.antlib.system.URLConverter"/> | |||
<converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/> | |||
<converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/> | |||
<aspect classname="org.apache.ant.antlib.system.AntAspect"/> | |||
</antlib> |
@@ -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; | |||
/** | |||
* Create an instance of the given converter class | |||
* Create an instance of the given class | |||
* | |||
* @param converterClass the converter class for which an instance is | |||
* @param requiredClass the class for which an instance is | |||
* required | |||
* @return a converter instance | |||
* @return a instance of the required class | |||
* @exception InstantiationException if the class cannot be instantiated | |||
* @exception IllegalAccessException if the instance cannot be accessed | |||
* @exception ExecutionException if there is a problem creating the | |||
* converter | |||
*/ | |||
Converter createConverter(Class converterClass) | |||
Object createInstance(Class requiredClass) | |||
throws InstantiationException, IllegalAccessException, | |||
ExecutionException; | |||
@@ -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 { | |||
/** | |||
* Initialise the task. The task may use the AntContext to request | |||
* Initialise the component. The component may use the AntContext to request | |||
* services from the Ant core. | |||
* | |||
* @param context the Task's context | |||
* @param context the Component's context | |||
* @param componentType the type of the component | |||
* @exception ExecutionException if the component cannot be initialised | |||
*/ | |||
@@ -93,20 +93,20 @@ public class StandardLibFactory implements AntLibFactory { | |||
} | |||
/** | |||
* Create an instance of the given converter class | |||
* Create an instance of the given class | |||
* | |||
* @param converterClass the converter class for which an instance is | |||
* @param requiredClass the class for which an instance is | |||
* required | |||
* @return a converter instance | |||
* @return a instance of the required class | |||
* @exception InstantiationException if the class cannot be instantiated | |||
* @exception IllegalAccessException if the instance cannot be accessed | |||
* @exception ExecutionException if there is a problem creating the | |||
* converter | |||
*/ | |||
public Converter createConverter(Class converterClass) | |||
public Object createInstance(Class requiredClass) | |||
throws InstantiationException, IllegalAccessException, | |||
ExecutionException { | |||
return (Converter) converterClass.newInstance(); | |||
return requiredClass.newInstance(); | |||
} | |||
/** | |||
@@ -174,22 +174,17 @@ public interface ComponentService { | |||
Object createComponent(String componentName) throws ExecutionException; | |||
/** | |||
* Create a component given its class. The component will have a context | |||
* but will not be configured. It should be configured using the | |||
* appropriate set methods and then validated before being used. | |||
* Create a component given its libraryId and local name within the | |||
* library. This method is unambiguous in the face of imports, aliases and | |||
* taskdefs performed in the build. | |||
* | |||
* @param componentClass the component's class | |||
* @param factory the factory to create the component | |||
* @param loader the classloader associated with the component | |||
* @param addTaskAdapter whenther the returned component should be a | |||
* task, potentially being wrapped in an adapter | |||
* @param componentName the name of the component type | |||
* @param libraryId the component's library identifier. | |||
* @param localName the name component within the library. | |||
* @return the created component. The return type of this method depends | |||
* on the component type. | |||
* @exception ExecutionException if the component cannot be created | |||
*/ | |||
Object createComponent(AntLibFactory factory, ClassLoader loader, | |||
Class componentClass, boolean addTaskAdapter, | |||
String componentName) throws ExecutionException; | |||
Object createComponent(String libraryId, String localName) | |||
throws ExecutionException; | |||
} | |||