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; | |||
| } | |||