diff --git a/proposal/mutant/ant1compat.xml b/proposal/mutant/ant1compat.xml index 4048579f0..e198184fd 100644 --- a/proposal/mutant/ant1compat.xml +++ b/proposal/mutant/ant1compat.xml @@ -59,7 +59,7 @@ - + diff --git a/proposal/mutant/build.xml b/proposal/mutant/build.xml index 520f7528e..c4dc07e93 100644 --- a/proposal/mutant/build.xml +++ b/proposal/mutant/build.xml @@ -38,8 +38,8 @@ - - + + @@ -130,6 +130,7 @@ + @@ -139,10 +140,10 @@ - + - + diff --git a/proposal/mutant/lib/antlib/script/readme.txt b/proposal/mutant/lib/antlib/script/readme.txt new file mode 100644 index 000000000..3e289ee54 --- /dev/null +++ b/proposal/mutant/lib/antlib/script/readme.txt @@ -0,0 +1 @@ +Please any jars in here which should be used when building the script antlib diff --git a/proposal/mutant/script.xml b/proposal/mutant/script.xml new file mode 100644 index 000000000..eb01e3443 --- /dev/null +++ b/proposal/mutant/script.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java index b380fac2f..8232a7179 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java @@ -149,11 +149,12 @@ public class AntLibManager { * @param librarySpecs the loaded specifications of the Ant libraries * @param initConfig the Ant initialization configuration * @param libraries the collection of libraries already configured + * @param libPathsMap a map of lists of library patsh fro each library * @exception ExecutionException if a library cannot be configured from * the given specification */ public void configLibraries(InitConfig initConfig, Map librarySpecs, - Map libraries) + Map libraries, Map libPathsMap) throws ExecutionException { // check if any already defined @@ -174,7 +175,7 @@ public class AntLibManager { String libraryId = (String)i.next(); if (!libraries.containsKey(libraryId)) { configLibrary(initConfig, librarySpecs, libraryId, - configuring, libraries); + configuring, libraries, libPathsMap); } } } @@ -189,7 +190,7 @@ public class AntLibManager { * @exception MalformedURLException if the library's location cannot be * formed */ - public void loadLib(Map librarySpecs, String libLocationString) + public void loadLibs(Map librarySpecs, String libLocationString) throws ExecutionException, MalformedURLException { File libLocation = new File(libLocationString); @@ -212,6 +213,24 @@ public class AntLibManager { } } + /** + * add a library path to the given library + * + * @param antLibrary the library to which the path is to be added + * @param path the path to be added + * @exception ExecutionException if remote paths are not allowed by + * configuration + */ + public void addLibPath(AntLibrary antLibrary, URL path) + throws ExecutionException { + if (!path.getProtocol().equals("file") + && !remoteAllowed) { + throw new ExecutionException("Remote libpaths are not" + + " allowed: " + path); + } + antLibrary.addLibraryURL(path); + } + /** * Configure a library from a specification and the Ant init config. * @@ -223,12 +242,13 @@ public class AntLibManager { * dependencies. * @param libraries the collection of libraries which have already been * 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 libraries, Map libPathsMap) throws ExecutionException { try { @@ -245,7 +265,7 @@ public class AntLibManager { + libraryId + " depends"); } configLibrary(initConfig, librarySpecs, extendsId, - configuring, libraries); + configuring, libraries, libPathsMap); } } @@ -265,8 +285,8 @@ public class AntLibManager { urlsList.add(initConfig.getToolsJarURL()); } - URL[] parserURLs = initConfig.getParserURLs(); if (librarySpec.usesAntXML()) { + URL[] parserURLs = initConfig.getParserURLs(); for (int i = 0; i < parserURLs.length; ++i) { urlsList.add(parserURLs[i]); } @@ -282,12 +302,22 @@ public class AntLibManager { } antLibrary.setParentLoader(initConfig.getCommonLoader()); libraries.put(libraryId, antLibrary); + + List libPaths = (List)libPathsMap.get(libraryId); + if (libPaths != null) { + for (Iterator j = libPaths.iterator(); j.hasNext(); ) { + URL pathURL = (URL)j.next(); + addLibPath(antLibrary, pathURL); + } + } + configuring.leaveNode(libraryId); } catch (CircularDependencyException e) { throw new ExecutionException(e); } } + /** * Read an Ant library definition from a URL * diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java index 1cc62ebb1..d14176fc9 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java @@ -69,9 +69,6 @@ import org.apache.ant.common.util.ExecutionException; * @created 14 January 2002 */ public class AntLibrary implements ComponentLibrary { - /** A counter for generating unique ids */ - private static int implicitLibCount = 0; - /** * This is the globally unique name of this library. It uses the same * conventions as the Java package space - i.e. reverse order DNS names diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/DynamicLibrary.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/DynamicLibrary.java index 42fb4bc21..0c9e2a9f4 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/DynamicLibrary.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/DynamicLibrary.java @@ -97,7 +97,8 @@ public class DynamicLibrary implements ComponentLibrary { public DynamicLibrary(AntLibFactory factory, ClassLoader loader) { int dynamicId = 0; synchronized (DynamicLibrary.class) { - dynamicId = dynamicIdCounter++; + dynamicId = dynamicIdCounter; + dynamicIdCounter++; } this.libraryId = DYNAMIC_LIB_PREFIX + dynamicId; this.loader = loader; diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java index db777bc81..194cffa43 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfig.java @@ -142,6 +142,18 @@ public class AntConfig { return libraryPathList; } + + /** + * Get the map of library paths. This map contains a collection of List + * instances, indexed by the libraryIds. Each list is a set of + * additional classpath entries for the given library + * + * @return the library paths map + */ + public Map getLibraryPathsMap() { + return libPaths; + } + /** * Gets the libraryIds of the AntConfig * diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java index e586a3743..077caec44 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java @@ -191,13 +191,13 @@ public class BuildEventSupport { /** * Send a message event * - * @param element the build element with which the event is associated + * @param source the build element with which the event is associated * @param message the message to be sent * @param priority the priority of the message */ - public void fireMessageLogged(ModelElement element, + public void fireMessageLogged(Object source, String message, int priority) { - BuildEvent event = new BuildEvent(element, message, priority); + BuildEvent event = new BuildEvent(source, message, priority); for (Iterator i = listeners.iterator(); i.hasNext(); ) { BuildListener listener = (BuildListener)i.next(); listener.messageLogged(event); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java index 4ce85251b..5886450fd 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java @@ -53,9 +53,14 @@ */ package org.apache.ant.antcore.execution; import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.ant.antcore.antlib.AntLibDefinition; import org.apache.ant.antcore.antlib.AntLibManager; import org.apache.ant.antcore.antlib.AntLibrary; @@ -64,6 +69,7 @@ import org.apache.ant.antcore.antlib.DynamicLibrary; import org.apache.ant.common.antlib.AntLibFactory; import org.apache.ant.common.antlib.Converter; import org.apache.ant.common.antlib.StandardLibFactory; +import org.apache.ant.common.event.MessageLevel; import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.util.ExecutionException; @@ -84,6 +90,9 @@ public class ComponentManager implements ComponentService { */ private Map converters = new HashMap(); + /** This is the set of libraries whose converters have been loaded */ + private Set loadedConverters = new HashSet(); + /** The factory objects for each library, indexed by the library Id */ private Map libFactories = new HashMap(); @@ -105,18 +114,27 @@ public class ComponentManager implements ComponentService { /** The definitions which have been imported into this frame. */ private Map definitions = new HashMap(); + /** + * This map stores a list of additional paths for each library indexed + * by the libraryId + */ + private Map libPathsMap; + /** * Constructor * * @param frame the frame containing this context * @param allowRemoteLibs true if remote libraries can be loaded though * this service. + * @param configLibPaths the additional library paths specified in the + * configuration */ - protected ComponentManager(Frame frame, - boolean allowRemoteLibs) { + protected ComponentManager(Frame frame, boolean allowRemoteLibs, + Map configLibPaths) { this.frame = frame; libManager = new AntLibManager(allowRemoteLibs); dynamicLibraries = new HashMap(); + libPathsMap = new HashMap(configLibPaths); } /** @@ -132,9 +150,9 @@ public class ComponentManager implements ComponentService { throws ExecutionException { try { Map librarySpecs = new HashMap(); - libManager.loadLib(librarySpecs, libLocation); + libManager.loadLibs(librarySpecs, libLocation); libManager.configLibraries(frame.getInitConfig(), librarySpecs, - antLibraries); + antLibraries, libPathsMap); if (importAll) { Iterator i = librarySpecs.keySet().iterator(); @@ -183,6 +201,72 @@ public class ComponentManager implements ComponentService { typeName, className); } + /** + * Add a library path for the given library + * + * @param libraryId the unique id of the library for which an additional + * path is being defined + * @param libPath the library path (usually a jar) + * @exception ExecutionException if the path cannot be specified + */ + public void addLibPath(String libraryId, URL libPath) + throws ExecutionException { + List libPaths = (List)libPathsMap.get(libraryId); + if (libPaths == null) { + libPaths = new ArrayList(); + libPathsMap.put(libraryId, libPaths); + } + libPaths.add(libPath); + + // If this library already exists give it the new path now + AntLibrary library = (AntLibrary)antLibraries.get(libraryId); + if (library != null) { + libManager.addLibPath(library, libPath); + } + } + + /** + * Import a complete library into the current execution frame + * + * @param libraryId The id of the library to be imported + * @exception ExecutionException if the library cannot be imported + */ + public void importLibrary(String libraryId) throws ExecutionException { + AntLibrary library = (AntLibrary)antLibraries.get(libraryId); + if (library == null) { + throw new ExecutionException("Unable to import library " + libraryId + + " as it has not been loaded"); + } + for (Iterator i = library.getDefinitionNames(); i.hasNext(); ) { + String defName = (String)i.next(); + importLibraryDef(library, defName, null); + } + addLibraryConverters(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 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 + * used. + * @exception ExecutionException if the component cannot be imported + */ + public void importComponent(String libraryId, String defName, + String alias) throws ExecutionException { + AntLibrary library = (AntLibrary)antLibraries.get(libraryId); + if (library == null) { + throw new ExecutionException("Unable to import component from " + + "library \"" + libraryId + "\" as it has not been loaded"); + } + importLibraryDef(library, defName, alias); + addLibraryConverters(library); + } + /** * Set the standard libraries (i.e. those which are independent of the * build files) to be used in this component manager @@ -252,25 +336,6 @@ public class ComponentManager implements ComponentService { return (ImportInfo)definitions.get(name); } - /** - * Import a complete library into this frame - * - * @param libraryId The id of the library to be imported - * @exception ExecutionException if the library cannot be imported - */ - protected void importLibrary(String libraryId) throws ExecutionException { - AntLibrary library = (AntLibrary)antLibraries.get(libraryId); - if (library == null) { - throw new ExecutionException("Unable to import library " + libraryId - + " as it has not been loaded"); - } - for (Iterator i = library.getDefinitionNames(); i.hasNext(); ) { - String defName = (String)i.next(); - importLibraryDef(library, defName, null); - } - addLibraryConverters(library); - } - /** * Import a single component from the given library * @@ -287,6 +352,9 @@ public class ComponentManager implements ComponentService { } AntLibDefinition libDef = library.getDefinition(defName); + frame.log("Adding component <" + defName + "> as <" + label + + "> from library \"" + library.getLibraryId() + "\", class: " + + libDef.getClassName(), MessageLevel.MSG_DEBUG); definitions.put(label, new ImportInfo(library, libDef)); } @@ -313,6 +381,7 @@ public class ComponentManager implements ComponentService { importLibraryDef(dynamicLibrary, componentName, null); } + /** * Add the converters from the given library to those managed by this * frame. @@ -323,7 +392,8 @@ public class ComponentManager implements ComponentService { */ private void addLibraryConverters(AntLibrary library) throws ExecutionException { - if (!library.hasConverters()) { + if (!library.hasConverters() + || loadedConverters.contains(library.getLibraryId())) { return; } @@ -351,6 +421,7 @@ public class ComponentManager implements ComponentService { converters.put(converterTypes[j], converter); } } + loadedConverters.add(library.getLibraryId()); } catch (ClassNotFoundException e) { throw new ExecutionException("In Ant library \"" + library.getLibraryId() + "\" converter class " diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/DeferredSetter.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/DeferredSetter.java new file mode 100644 index 000000000..11df858a8 --- /dev/null +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/DeferredSetter.java @@ -0,0 +1,191 @@ +/* + * 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 + * . + */ +package org.apache.ant.antcore.execution; +import org.apache.ant.common.antlib.DeferredTask; +import org.apache.ant.common.util.ExecutionException; + +/** + * An implementation of the Setter interface for configuring instances of + * the DeferredTask interface + * + * @author Conor MacNeill + * @created 11 February 2002 + */ +public class DeferredSetter implements Setter { + /** + * Set an attribute value on an object + * + * @param obj the object on which the value is being set + * @param attributeName the name of the attribute + * @param value the string represenation of the attribute's value + * @exception ExecutionException if the object does not support the + * attribute or the object has a problem setting the value + */ + public void setAttribute(Object obj, String attributeName, + String value) throws ExecutionException { + DeferredTask task = (DeferredTask)obj; + task.setAttribute(attributeName, value); + } + + + /** + * Get the type of the given nested element + * + * @param elementName the nested element whose type is desired + * @return the class instance representing the type of the element adder + */ + public Class getType(String elementName) { + return null; + } + + /** + * Adds PCDATA to the element + * + * @param obj the instance whose content is being provided + * @param text the required content + * @exception ExecutionException if the object does not support + * contentor the object has a problem setting the content + */ + public void addText(Object obj, String text) + throws ExecutionException { + DeferredTask task = (DeferredTask)obj; + task.addText(text); + } + + /** + * Add an element to the given object + * + * @param obj The object to which the element is being added + * @param elementName the name of the element + * @param value the object to be added - the nested element + * @exception ExecutionException if the object does not support content + * or the object has a problem setting the content + */ + public void addElement(Object obj, String elementName, Object value) + throws ExecutionException { + DeferredTask task = (DeferredTask)obj; + task.addElement(elementName, value); + } + + /** + * Create a nested element using the object's element factory method. + * + * @param container the object in which the nested element is required. + * @param elementName the name of the nested element + * @return the new instance of the nested element + * @exception ExecutionException if the nested element cannot be + * created. + */ + public Object createElement(Object container, String elementName) + throws ExecutionException { + throw new ExecutionException("Deferred Tasks do not support " + + "creation of nested elements"); + } + + /** + * Indicate if the class assocated with this reflector supports the + * addition of text content. + * + * @return true if the class supports an addText method + */ + public boolean supportsText() { + return true; + } + + /** + * Indicate if the class assocated with this reflector supports the + * given attribute + * + * @param attributeName the name of the attribute + * @return true if the given attribute is supported + */ + public boolean supportsAttribute(String attributeName) { + return true; + } + + /** + * Determine if the class associated with this reflector supports a + * particular nested element via a create factory method + * + * @param elementName the name of the element + * @return true if the class supports creation of that element + */ + public boolean supportsNestedCreator(String elementName) { + return false; + } + + /** + * Determine if the class associated with this reflector supports a + * particular nested element via an add method + * + * @param elementName the name of the element + * @return true if the class supports addition of that element + */ + public boolean supportsNestedAdder(String elementName) { + return true; + } + + /** + * Determine if the class associated with this reflector supports a + * particular nested element + * + * @param elementName the name of the element + * @return true if the class supports the given type of nested element + */ + public boolean supportsNestedElement(String elementName) { + return true; + } + +} + diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java index 5725edeff..4b9e4e602 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java @@ -137,9 +137,12 @@ public class ExecutionContext implements AntContext { * @param level the priority level of the message */ public void log(String message, int level) { - ModelElement source = modelElement; - if (modelElement == null) { + Object source = modelElement; + if (source == null) { source = frame.getProject(); + if (source == null) { + source = frame; + } } eventSupport.fireMessageLogged(source, message, level); } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java index 1a29085c6..709c97c98 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java @@ -59,7 +59,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.ant.antcore.antlib.AntLibManager; -import org.apache.ant.antcore.antlib.AntLibrary; import org.apache.ant.antcore.config.AntConfig; import org.apache.ant.common.event.BuildListener; import org.apache.ant.common.model.Project; @@ -70,8 +69,8 @@ import org.apache.ant.init.InitConfig; /** * The ExecutionManager is used to manage the execution of a build. The * Execution manager is responsible for loading the Ant task libraries, - * creating Frames for each project that is part of the build and - * then executing the tasks within those Execution Frames. + * creating Frames for each project that is part of the build and then + * executing the tasks within those Execution Frames. * * @author Conor MacNeill * @created 12 January 2002 @@ -112,7 +111,15 @@ public class ExecutionManager { throws ExecutionException { this.config = config; this.initConfig = initConfig; + } + /** + * Initialise the execution manager + * + * @exception ExecutionException if the standard ant libraries cannot be + * loaded + */ + public void init() throws ExecutionException { Map librarySpecs = new HashMap(10); try { // start by loading the task libraries @@ -123,20 +130,19 @@ public class ExecutionManager { = new AntLibManager(config.isRemoteLibAllowed()); libManager.addAntLibraries(librarySpecs, standardLibsURL); - libManager.configLibraries(initConfig, librarySpecs, antLibraries); + libManager.configLibraries(initConfig, librarySpecs, antLibraries, + config.getLibraryPathsMap()); librarySpecs.clear(); // add any additional libraries. - for (Iterator i = config.getLibraryLocations(); i.hasNext(); ) { - // try file first - String libLocation = (String)i.next(); - libManager.loadLib(librarySpecs, libLocation); - } - libManager.configLibraries(initConfig, librarySpecs, antLibraries); - - addConfigLibPaths(); + for (Iterator i = config.getLibraryLocations(); i.hasNext(); ) { + // try file first + String libLocation = (String)i.next(); + libManager.loadLibs(librarySpecs, libLocation); + } + libManager.configLibraries(initConfig, librarySpecs, antLibraries, + config.getLibraryPathsMap()); - mainFrame = new Frame(antLibraries, initConfig, config); } catch (MalformedURLException e) { throw new ExecutionException("Unable to load Ant libraries", e); } @@ -156,6 +162,12 @@ public class ExecutionManager { // start by validating the project we have been given. project.validate(); + mainFrame = new Frame(antLibraries, initConfig, config); + for (Iterator j = eventSupport.getListeners(); j.hasNext(); ) { + BuildListener listener = (BuildListener)j.next(); + mainFrame.addBuildListener(listener); + } + mainFrame.setProject(project); mainFrame.setInitialProperties(commandProperties); @@ -178,7 +190,9 @@ public class ExecutionManager { */ public void addBuildListener(BuildListener listener) { eventSupport.addBuildListener(listener); - mainFrame.addBuildListener(listener); + if (mainFrame != null) { + mainFrame.addBuildListener(listener); + } } /** @@ -188,35 +202,10 @@ public class ExecutionManager { */ public void removeBuildListener(BuildListener listener) { eventSupport.removeBuildListener(listener); - mainFrame.removeBuildListener(listener); - } - - /** - * Add the library paths from the AntConfig instance to the Ant - * Libraries. - * - * @exception ExecutionException if remote libraries are not allowed. - */ - private void addConfigLibPaths() - throws ExecutionException { - // now add any additional library Paths specified by the config - for (Iterator i = config.getLibraryIds(); i.hasNext(); ) { - String libraryId = (String)i.next(); - if (antLibraries.containsKey(libraryId)) { - AntLibrary antLib - = (AntLibrary)antLibraries.get(libraryId); - List pathList = config.getLibraryPathList(libraryId); - for (Iterator j = pathList.iterator(); j.hasNext(); ) { - URL pathElementURL = (URL)j.next(); - if (!pathElementURL.getProtocol().equals("file") - && !config.isRemoteLibAllowed()) { - throw new ExecutionException("Remote libpaths are not" - + " allowed: " + pathElementURL); - } - antLib.addLibraryURL(pathElementURL); - } - } + if (mainFrame != null) { + mainFrame.removeBuildListener(listener); } } + } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java index 1db6dc2d2..39a5e057b 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java @@ -63,30 +63,31 @@ import org.apache.ant.antcore.antlib.AntLibrary; import org.apache.ant.antcore.antlib.ComponentLibrary; import org.apache.ant.antcore.config.AntConfig; import org.apache.ant.common.antlib.AntLibFactory; +import org.apache.ant.common.antlib.DeferredTask; import org.apache.ant.common.antlib.ExecutionComponent; import org.apache.ant.common.antlib.Task; import org.apache.ant.common.antlib.TaskContainer; import org.apache.ant.common.event.BuildListener; +import org.apache.ant.common.event.MessageLevel; import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.model.Project; import org.apache.ant.common.model.Target; import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.service.DataService; -import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.EventService; +import org.apache.ant.common.service.ExecService; +import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.MagicProperties; import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.ConfigException; import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.FileUtils; -import org.apache.ant.common.util.MessageLevel; import org.apache.ant.init.InitConfig; -import org.apache.ant.common.service.ExecService; /** - * An Frame maintains the state of a project during an execution. - * The Frame contains the data values set by Ant tasks as they are - * executed, including task definitions, property values, etc. + * An Frame maintains the state of a project during an execution. The Frame + * contains the data values set by Ant tasks as they are executed, including + * task definitions, property values, etc. * * @author Conor MacNeill * @created 14 January 2002 @@ -105,7 +106,7 @@ public class Frame { private Map referencedFrames = new HashMap(); /** Reflector objects used to configure Tasks from the Task models. */ - private Map reflectors = new HashMap(); + private Map setters = new HashMap(); /** * The context of this execution. This contains all data object's @@ -165,7 +166,7 @@ public class Frame { * imported */ protected Frame(Map standardLibs, InitConfig initConfig, - AntConfig config) throws ExecutionException { + AntConfig config) throws ExecutionException { this.standardLibs = standardLibs; this.config = config; this.initConfig = initConfig; @@ -202,7 +203,6 @@ public class Frame { = project.getReferencedProject(referenceName); Frame referencedFrame = createFrame(referencedProject); referencedFrames.put(referenceName, referencedFrame); - } configureServices(); @@ -359,8 +359,8 @@ public class Frame { * Get a referenced frame by its reference name * * @param referenceName the name under which the frame was imported. - * @return the Frame asscociated with the given reference name - * or null if there is no such project. + * @return the Frame asscociated with the given reference name or null + * if there is no such project. */ protected Frame getReferencedFrame(String referenceName) { return (Frame)referencedFrames.get(referenceName); @@ -672,20 +672,26 @@ public class Frame { /** - * Gets the reflector for the given class + * Gets the setter for the given class * * @param c the class for which the reflector is desired * @return the reflector */ - private Reflector getReflector(Class c) { - if (reflectors.containsKey(c)) { - return (Reflector)reflectors.get(c); + private Setter getSetter(Class c) { + if (setters.containsKey(c)) { + return (Setter)setters.get(c); } - ClassIntrospector introspector - = new ClassIntrospector(c, componentManager.getConverters()); - Reflector reflector = introspector.getReflector(); - reflectors.put(c, reflector); - return reflector; + Setter setter = null; + if (DeferredTask.class.isAssignableFrom(c)) { + setter = new DeferredSetter(); + } else { + ClassIntrospector introspector + = new ClassIntrospector(c, componentManager.getConverters()); + setter = introspector.getReflector(); + } + + setters.put(c, setter); + return setter; } @@ -759,15 +765,15 @@ public class Frame { private void configureServices() { // create services and make them available in our services map fileService = new CoreFileService(this); - componentManager - = new ComponentManager(this, config.isRemoteLibAllowed()); + componentManager = new ComponentManager(this, + config.isRemoteLibAllowed(), config.getLibraryPathsMap()); dataService = new CoreDataService(this, config.isUnsetPropertiesAllowed()); services.put(FileService.class, fileService); services.put(ComponentService.class, componentManager); services.put(DataService.class, dataService); - services.put(EventService.class, new CoreEventService(this)); + services.put(EventService.class, new CoreEventService(this)); services.put(ExecService.class, new CoreExecService(this)); } @@ -784,27 +790,27 @@ public class Frame { BuildElement model) throws ExecutionException { - Reflector reflector = getReflector(element.getClass()); + Setter setter = getSetter(element.getClass()); // start by setting the attributes of this element for (Iterator i = model.getAttributeNames(); i.hasNext(); ) { String attributeName = (String)i.next(); String attributeValue = model.getAttributeValue(attributeName); - if (!reflector.supportsAttribute(attributeName)) { + if (!setter.supportsAttribute(attributeName)) { throw new ExecutionException(model.getType() + " does not support the \"" + attributeName + "\" attribute", model.getLocation()); } - reflector.setAttribute(element, attributeName, + setter.setAttribute(element, attributeName, dataService.replacePropertyRefs(attributeValue)); } String modelText = model.getText().trim(); if (modelText.length() != 0) { - if (!reflector.supportsText()) { + if (!setter.supportsText()) { throw new ExecutionException(model.getType() + " does not support content", model.getLocation()); } - reflector.addText(element, + setter.addText(element, dataService.replacePropertyRefs(modelText)); } @@ -817,7 +823,7 @@ public class Frame { if (element instanceof TaskContainer && info != null && info.getDefinitionType() == AntLibrary.TASKDEF - && !reflector.supportsNestedElement(nestedElementName)) { + && !setter.supportsNestedElement(nestedElementName)) { // it is a nested task TaskContext nestedContext = configureTask(nestedElementModel); @@ -826,11 +832,11 @@ public class Frame { // method of executing tasks container.addTask(nestedContext.getTask()); } else { - if (reflector.supportsNestedAdder(nestedElementName)) { - addNestedElement(factory, reflector, element, + if (setter.supportsNestedAdder(nestedElementName)) { + addNestedElement(factory, setter, element, nestedElementModel); - } else if (reflector.supportsNestedCreator(nestedElementName)) { - createNestedElement(factory, reflector, element, + } else if (setter.supportsNestedCreator(nestedElementName)) { + createNestedElement(factory, setter, element, nestedElementModel); } else { throw new ExecutionException(model.getType() @@ -846,7 +852,7 @@ public class Frame { /** * Create a nested element for the given object according to the model. * - * @param reflector the reflector instance of the container object + * @param setter the Setter instance of the container object * @param element the container object for which a nested element is * required. * @param model the build model for the nestd element @@ -855,7 +861,7 @@ public class Frame { * @exception ExecutionException if the nested element cannot be * created. */ - private void createNestedElement(AntLibFactory factory, Reflector reflector, + private void createNestedElement(AntLibFactory factory, Setter setter, Object element, BuildElement model) throws ExecutionException { log("The use of create methods is deprecated - class: " @@ -864,7 +870,7 @@ public class Frame { String nestedElementName = model.getType(); try { Object nestedElement - = reflector.createElement(element, nestedElementName); + = setter.createElement(element, nestedElementName); factory.registerCreatedElement(nestedElement); if (nestedElement instanceof ExecutionComponent) { ExecutionComponent component @@ -891,7 +897,7 @@ public class Frame { /** * Create and add a nested element * - * @param reflector The reflector instance for the container element + * @param setter The Setter instance for the container element * @param element the container element in which the nested element will * be created * @param model the model of the nested element @@ -899,12 +905,12 @@ public class Frame { * which the attribute is to be added. * @exception ExecutionException if the nested element cannot be created */ - private void addNestedElement(AntLibFactory factory, Reflector reflector, + private void addNestedElement(AntLibFactory factory, Setter setter, Object element, BuildElement model) throws ExecutionException { String nestedElementName = model.getType(); - Class nestedType = reflector.getType(nestedElementName); + Class nestedType = setter.getType(nestedElementName); // is there a polymorph indicator - look in Ant aspects String typeName = model.getAspectValue(ANT_ASPECT, "type"); @@ -947,7 +953,7 @@ public class Frame { model.getLocation()); } - typeInstance = createTypeInstance(nestedType, factory, model); + typeInstance = createTypeInstance(nestedType, factory, model, null); } // is the typeInstance compatible with the type expected @@ -965,7 +971,7 @@ public class Frame { model.getLocation()); } } - reflector.addElement(element, nestedElementName, typeInstance); + setter.addElement(element, nestedElementName, typeInstance); } @@ -989,8 +995,9 @@ public class Frame { } String className = taskDefInfo.getClassName(); - ComponentLibrary componentLibrary - = taskDefInfo.getComponentLibrary(); + ComponentLibrary componentLibrary + = taskDefInfo.getComponentLibrary(); + String localName = taskDefInfo.getLocalName(); try { ClassLoader taskClassLoader = componentLibrary.getClassLoader(); @@ -998,7 +1005,8 @@ public class Frame { = Class.forName(className, true, taskClassLoader); AntLibFactory libFactory = componentManager.getLibFactory(componentLibrary); - Object element = libFactory.createTaskInstance(elementClass); + Object element + = libFactory.createTaskInstance(elementClass, localName); Task task = null; if (element instanceof Task) { @@ -1062,8 +1070,9 @@ public class Frame { } String className = typeDefInfo.getClassName(); - ComponentLibrary componentLibrary - = typeDefInfo.getComponentLibrary(); + ComponentLibrary componentLibrary + = typeDefInfo.getComponentLibrary(); + String localName = typeDefInfo.getLocalName(); try { ClassLoader typeClassLoader = componentLibrary.getClassLoader(); @@ -1074,7 +1083,7 @@ public class Frame { AntLibFactory libFactory = componentManager.getLibFactory(componentLibrary); Object typeInstance - = createTypeInstance(typeClass, libFactory, model); + = createTypeInstance(typeClass, libFactory, model, localName); setContextLoader(currentLoader); return typeInstance; @@ -1095,15 +1104,17 @@ public class Frame { * @param model the model describing the required configuration of the * instance * @param libFactory the factory object of the typeClass's Ant library + * @param localName the name of the type within its Ant library * @return an instance of the given class appropriately configured * @exception ExecutionException if there is a problem creating the type * instance */ private Object createTypeInstance(Class typeClass, AntLibFactory libFactory, - BuildElement model) + BuildElement model, String localName) throws ExecutionException { try { - Object typeInstance = libFactory.createTypeInstance(typeClass); + Object typeInstance + = libFactory.createTypeInstance(typeClass, localName); if (typeInstance instanceof ExecutionComponent) { ExecutionComponent component = (ExecutionComponent)typeInstance; diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java index b114f7b99..f45ff6a3f 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java @@ -107,5 +107,14 @@ public class ImportInfo { return libDefinition.getDefinitionType(); } + /** + * Get the name of the component within its library. + * + * @return the name of the component within its library + */ + public String getLocalName() { + return libDefinition.getDefinitionName(); + } + } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Reflector.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Reflector.java index 3aa991094..20efbf689 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Reflector.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Reflector.java @@ -69,7 +69,7 @@ import org.apache.ant.common.util.ExecutionException; * @author Conor MacNeill * @created 19 January 2002 */ -public class Reflector { +public class Reflector implements Setter { /** * AttributeSetter classes are created at introspection time for each diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Setter.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Setter.java new file mode 100644 index 000000000..b91459825 --- /dev/null +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Setter.java @@ -0,0 +1,166 @@ +/* + * 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 + * . + */ +package org.apache.ant.antcore.execution; +import org.apache.ant.common.util.ExecutionException; + +/** + * The Setter interface is used by the Ant core to set values and nested + * elements in objects being configured. + * + * @author Conor MacNeill + * @created 11 February 2002 + */ +public interface Setter { + /** + * Set an attribute value on an object + * + * @param obj the object on which the value is being set + * @param attributeName the name of the attribute + * @param value the string represenation of the attribute's value + * @exception ExecutionException if the object does not support the + * attribute or the object has a problem setting the value + */ + void setAttribute(Object obj, String attributeName, + String value) + throws ExecutionException; + + /** + * Get the type of the given nested element + * + * @param elementName the nested element whose type is desired + * @return the class instance representing the type of the element adder + */ + Class getType(String elementName); + + /** + * Adds PCDATA to the element + * + * @param obj the instance whose content is being provided + * @param text the required content + * @exception ExecutionException if the object does not support + * contentor the object has a problem setting the content + */ + void addText(Object obj, String text) + throws ExecutionException; + + /** + * Add an element to the given object + * + * @param obj The object to which the element is being added + * @param elementName the name of the element + * @param value the object to be added - the nested element + * @exception ExecutionException if the object does not support content + * or the object has a problem setting the content + */ + void addElement(Object obj, String elementName, Object value) + throws ExecutionException; + + /** + * Create a nested element using the object's element factory method. + * + * @param container the object in which the nested element is required. + * @param elementName the name of the nested element + * @return the new instance of the nested element + * @exception ExecutionException if the nested element cannot be + * created. + */ + Object createElement(Object container, String elementName) + throws ExecutionException; + + /** + * Indicate if the class assocated with this reflector supports the + * addition of text content. + * + * @return true if the class supports an addText method + */ + boolean supportsText(); + + /** + * Indicate if the class assocated with this reflector supports the + * given attribute + * + * @param attributeName the name of the attribute + * @return true if the given attribute is supported + */ + boolean supportsAttribute(String attributeName); + + /** + * Determine if the class associated with this reflector supports a + * particular nested element via a create factory method + * + * @param elementName the name of the element + * @return true if the class supports creation of that element + */ + boolean supportsNestedCreator(String elementName); + + /** + * Determine if the class associated with this reflector supports a + * particular nested element via an add method + * + * @param elementName the name of the element + * @return true if the class supports addition of that element + */ + boolean supportsNestedAdder(String elementName); + + /** + * Determine if the class associated with this reflector supports a + * particular nested element + * + * @param elementName the name of the element + * @return true if the class supports the given type of nested element + */ + boolean supportsNestedElement(String elementName); + +} + diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java index bdde0ce27..eb9ba10f6 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java @@ -68,7 +68,7 @@ import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.FileService; import org.apache.ant.common.util.ExecutionException; -import org.apache.ant.common.util.MessageLevel; +import org.apache.ant.common.event.MessageLevel; import org.apache.ant.common.util.PropertyUtils; import org.apache.tools.ant.types.FilterSet; import org.apache.tools.ant.types.FilterSetCollection; @@ -199,6 +199,14 @@ public class Project implements org.apache.ant.common.event.BuildListener { return javaVersion; } + /** + * get the target hashtable + * @return hashtable, the contents of which can be cast to Target + */ + public Hashtable getTargets() { + return new Hashtable(); // XXX can't get targets + } + /** * returns the boolean equivalent of a string, which is considered true * if either "on", "true", or "yes" is found, ignoring case. diff --git a/proposal/mutant/src/java/antlibs/script/antlib.xml b/proposal/mutant/src/java/antlibs/script/antlib.xml new file mode 100644 index 000000000..c573eba65 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/script/antlib.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java new file mode 100644 index 000000000..2af7b619f --- /dev/null +++ b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java @@ -0,0 +1,177 @@ +/* + * 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 + * . + */ +package org.apache.ant.antlib.script; +import com.ibm.bsf.BSFEngine; +import com.ibm.bsf.BSFException; +import com.ibm.bsf.BSFManager; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.ant.common.antlib.AbstractTask; +import org.apache.ant.common.antlib.DeferredTask; +import org.apache.ant.common.util.ExecutionException; + +/** + * Task to import a component or components from a library + * + * @author Conor MacNeill + * @created 27 January 2002 + */ +public class ScriptBase extends AbstractTask implements DeferredTask { + /** The script factory instance to be used by this script */ + private ScriptFactory factory; + /** the name to which this script has been defined */ + private String scriptName; + + /** the attribute values set by the core */ + private Map attributes = new HashMap(); + + /** Any embedded set by the core */ + private String text = ""; + + /** A list of the nested element names which have been configured */ + private List nestedElementNames = new ArrayList(); + /** A list of the nested elements objects which have been configured */ + private List nestedElements = new ArrayList(); + + /** + * Set the given attribute + * + * @param name the name of the attribute + * @param attributeValue the new attribute value + */ + public void setAttribute(String name, String attributeValue) { + attributes.put(name, attributeValue); + } + + /** + * Add a nested element + * + * @param nestedElementName the nested element's name + * @param value the object being added + */ + public void addElement(String nestedElementName, Object value) { + nestedElementNames.add(nestedElementName); + nestedElements.add(value); + } + + + /** + * Execute the script + * + * @exception ExecutionException if tghe script execution fails + */ + public void execute() throws ExecutionException { + String language = factory.getScriptLanguage(scriptName); + String script = factory.getScript(scriptName); + + try { + BSFManager manager = new BSFManager(); + + // execute the script + BSFEngine engine = manager.loadScriptingEngine(language); + engine.exec(scriptName, 0, 0, script); + for (Iterator i = attributes.keySet().iterator(); i.hasNext(); ) { + String attributeName = (String)i.next(); + String value = (String)attributes.get(attributeName); + StringBuffer setter = new StringBuffer(attributeName); + setter.setCharAt(0, Character.toUpperCase(setter.charAt(0))); + engine.call(null, "set" + setter, new Object[]{value}); + } + engine.call(null, "execute", new Object[]{}); + } catch (BSFException e) { + Throwable t = e; + Throwable te = e.getTargetException(); + if (te != null) { + if (te instanceof ExecutionException) { + throw (ExecutionException)te; + } else { + t = te; + } + } + throw new ExecutionException(t); + } + } + + /** + * Defines the script. + * + * @param text Sets the value for the script variable. + */ + public void addText(String text) { + this.text += text; + } + + /** + * Sets the factory of the ScriptBase + * + * @param factory the script factory this script instance will use + */ + protected void setFactory(ScriptFactory factory) { + this.factory = factory; + } + + /** + * set the name of the script + * + * @param scriptName the script's defined name + */ + protected void setScriptName(String scriptName) { + this.scriptName = scriptName; + } + +} + diff --git a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptDef.java b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptDef.java new file mode 100644 index 000000000..439d2aeea --- /dev/null +++ b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptDef.java @@ -0,0 +1,128 @@ +/* + * 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 + * . + */ +package org.apache.ant.antlib.script; + +import org.apache.ant.common.antlib.AbstractTask; +import org.apache.ant.common.util.ExecutionException; + +/** + * Define a task using a script + * + * @author Conor MacNeill + * @created 11 February 2002 + */ +public class ScriptDef extends AbstractTask { + /** The script factor to use */ + private ScriptFactory factory; + + /** the name by which this script will be activated */ + private String name; + + /** the scripting language used by the script */ + private String language; + + /** the script itself */ + private String script = ""; + + /** + * set the name under which this script will be activated in a build + * file + * + * @param name the name of the script + */ + public void setName(String name) { + this.name = name; + } + + /** + * Set the scripting language used by this script + * + * @param language the scripting language used by this script. + */ + public void setLanguage(String language) { + this.language = language; + } + + /** + * Define the script. The script itself is stored in the factory where + * it is retried by the ScriptBase instance + * + * @exception ExecutionException if the script cannot be defined + */ + public void execute() throws ExecutionException { + // tell the factory about this script, under this name. + factory.defineScript(name, language, script); + } + + /** + * Defines the script. + * + * @param text Sets the value for the script variable. + */ + public void addText(String text) { + this.script += text; + } + + /** + * Set the script factory that will be used to store the script for + * later execution + * + * @param factory the script factory used to store script information. + */ + protected void setFactory(ScriptFactory factory) { + this.factory = factory; + } + +} + diff --git a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java new file mode 100644 index 000000000..53d3c0ad6 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java @@ -0,0 +1,206 @@ +/* + * 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 + * . + */ +package org.apache.ant.antlib.script; +import java.util.HashMap; +import java.util.Map; + +import org.apache.ant.common.antlib.AntContext; +import org.apache.ant.common.antlib.StandardLibFactory; +import org.apache.ant.common.service.ComponentService; +import org.apache.ant.common.util.ExecutionException; + +/** + * The ScriptFactory class is a factory for the Scripting tasks. It stores + * the scripts as they are defined + * + * @author Conor MacNeill + * @created 11 February 2002 + */ +public class ScriptFactory extends StandardLibFactory { + /** + * An inner class used to record information about defined scripts. + * + * @author Conor MacNeill + * @created 11 February 2002 + */ + private static class ScriptInfo { + /** the scripting langauge to use */ + private String language; + /** the script itself */ + private String script; + + /** + * Constructor for the ScriptInfo object + * + * @param language the language the script is written in + * @param script the script + */ + public ScriptInfo(String language, String script) { + this.language = language; + this.script = script; + } + + /** + * Gets the language of the Script + * + * @return the language value + */ + public String getLanguage() { + return language; + } + + /** + * Gets the script. + * + * @return the script text + */ + public String getScript() { + return script; + } + } + + /** The core's Component Service instance */ + private ComponentService componentService; + + /** the scripts that have been defined */ + private Map scripts = new HashMap(); + + /** + * Initialise the factory + * + * @param context the factory's context + * @exception ExecutionException if the factory cannot be initialized + */ + public void init(AntContext context) throws ExecutionException { + super.init(context); + componentService + = (ComponentService)context.getCoreService(ComponentService.class); + try { + Class.forName("com.ibm.bsf.BSFManager"); + } catch (ClassNotFoundException e) { + throw new ExecutionException("The script Ant library requires " + + "bsf.jar to be available"); + } catch (NoClassDefFoundError e) { + throw new ExecutionException("The script Ant library requires " + + "bsf.jar to be available. The class " + e.getMessage() + + "appears to be missing"); + } + } + + /** + * Create an instance of the given task class + * + * @param taskClass the class for which an instance is required + * @param localName the name within the library undeer which the task is + * defined + * @return an 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 task + */ + public Object createTaskInstance(Class taskClass, String localName) + throws InstantiationException, IllegalAccessException, + ExecutionException { + Object task = super.createTaskInstance(taskClass, localName); + + if (task instanceof ScriptDef) { + ScriptDef scriptDef = (ScriptDef)task; + scriptDef.setFactory(this); + } else if (task instanceof ScriptBase) { + ScriptBase scriptBase = (ScriptBase)task; + scriptBase.setFactory(this); + scriptBase.setScriptName(localName); + } + return task; + } + + /** + * Get the script language of a script + * + * @param scriptName the name the script is defined under + * @return the script language name + */ + protected String getScriptLanguage(String scriptName) { + ScriptInfo scriptInfo = (ScriptInfo)scripts.get(scriptName); + return scriptInfo.getLanguage(); + } + + /** + * Get a script. + * + * @param scriptName the name the script is defined under + * @return the script text + */ + protected String getScript(String scriptName) { + ScriptInfo scriptInfo = (ScriptInfo)scripts.get(scriptName); + return scriptInfo.getScript(); + } + + /** + * Define a script + * + * @param name the name the script is to be defined under + * @param language the language of the scripr + * @param script the script text + * @exception ExecutionException if the script cannot be defined + */ + protected void defineScript(String name, String language, String script) + throws ExecutionException { + ScriptInfo scriptDefinition = new ScriptInfo(language, script); + scripts.put(name, scriptDefinition); + componentService.taskdef(this, ScriptBase.class.getClassLoader(), + name, ScriptBase.class.getName()); + } +} + diff --git a/proposal/mutant/src/java/antlibs/system/antlib.xml b/proposal/mutant/src/java/antlibs/system/antlib.xml index e4f1892ec..a210aa2a6 100644 --- a/proposal/mutant/src/java/antlibs/system/antlib.xml +++ b/proposal/mutant/src/java/antlibs/system/antlib.xml @@ -1,9 +1,9 @@ - + diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LibPath.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LibPath.java deleted file mode 100644 index 115b7f67e..000000000 --- a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LibPath.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 - * . - */ -package org.apache.ant.antlib.system; - -import org.apache.ant.common.antlib.AbstractTask; - -/** - * Task to add an additional classpath search path to the given library - * - * @author Conor MacNeill - * @created 27 January 2002 - */ -public class LibPath extends AbstractTask { - /** The id of the library for which this additional path is being set */ - private String libraryId; - - /** Add the libpath to the set of paths associated with the library */ - public void execute() { - } -} - diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Ant.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Ant.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntBase.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntBase.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntCall.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntCall.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/FileConverter.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/FileConverter.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/FileConverter.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/FileConverter.java diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java new file mode 100644 index 000000000..764ec7039 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java @@ -0,0 +1,135 @@ +/* + * 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 + * . + */ +package org.apache.ant.antlib.system; + +import org.apache.ant.common.antlib.AbstractTask; +import org.apache.ant.common.antlib.AntContext; +import org.apache.ant.common.service.ComponentService; +import org.apache.ant.common.util.ExecutionException; + +/** + * Task to import a component or components from a library + * + * @author Conor MacNeill + * @created 27 January 2002 + */ +public class Import extends AbstractTask { + /** The Ant LIbrary Id from which the component must be imported */ + private String libraryId = null; + /** The name of the component to be imported */ + private String name = null; + + /** The alias that is to be used for the name */ + private String alias = null; + + /** + * Sets the libraryId of the Import + * + * @param libraryId the new libraryId value + */ + public void setLibraryId(String libraryId) { + this.libraryId = libraryId; + } + + /** + * Sets the name of the Import + * + * @param name the new name value + */ + public void setName(String name) { + this.name = name; + } + + /** + * Sets the alias of the Import + * + * @param alias the new alias value + */ + public void setAlias(String alias) { + this.alias = alias; + } + + /** + * Validate this task is properly configured + * + * @exception ExecutionException if the task is not configured correctly + */ + public void validateComponent() throws ExecutionException { + if (libraryId == null) { + throw new ExecutionException("You must specify a library identifier" + + " with the \"libraryid\" attribute"); + } + if (alias != null && name == null) { + throw new ExecutionException("You may only specify an alias" + + " when you specify the component name"); + } + } + + /** + * Do the work and import the component or components + * + * @exception ExecutionException if the components cannot be imported + */ + public void execute() throws ExecutionException { + AntContext context = getContext(); + ComponentService componentService = (ComponentService) + context.getCoreService(ComponentService.class); + if (name == null) { + componentService.importLibrary(libraryId); + } else { + componentService.importComponent(libraryId, name, alias); + } + } +} + diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java new file mode 100644 index 000000000..c25703344 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java @@ -0,0 +1,172 @@ +/* + * 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 + * . + */ +package org.apache.ant.antlib.system; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.ant.common.antlib.AbstractTask; +import org.apache.ant.common.antlib.AntContext; +import org.apache.ant.common.service.ComponentService; +import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.init.InitUtils; + +/** + * Task to add an additional classpath to the given library + * + * @author Conor MacNeill + * @created 27 January 2002 + */ +public class LibPath extends AbstractTask { + /** The id of the library for which this additional path is being set */ + private String libraryId; + /** + * This is the location, either file or URL of the library or libraries + * to be loaded + */ + private URL url; + + /** + * Sets the libraryId of the LibPath + * + * @param libraryId the new libraryId value + */ + public void setLibraryId(String libraryId) { + this.libraryId = libraryId; + } + + /** + * Sets the URL of the library to be loaded + * + * @param url the URL from which the library is to be loaded + * @exception ExecutionException if the URL cannot be set + */ + public void setURL(URL url) throws ExecutionException { + checkNullURL(); + this.url = url; + } + + /** + * Set the file from which the library should be loaded. + * + * @param file the file from which the library should be loaded + * @exception ExecutionException if the file attribute cannot be set + */ + public void setFile(File file) throws ExecutionException { + checkNullURL(); + try { + this.url = InitUtils.getFileURL(file); + } catch (MalformedURLException e) { + throw new ExecutionException(e); + } + } + + /** + * Set the dir in which to search for AntLibraries. + * + * @param dir the dir from which all Ant Libraries found will be loaded. + * @exception ExecutionException if the dir attribute cannot be set + */ + public void setDir(File dir) throws ExecutionException { + checkNullURL(); + try { + this.url = InitUtils.getFileURL(dir); + } catch (MalformedURLException e) { + throw new ExecutionException(e); + } + } + + /** + * Validate this task is configured correctly + * + * @exception ExecutionException if the task is not configured correctly + */ + public void validateComponent() throws ExecutionException { + if (libraryId == null) { + throw new ExecutionException("You must specify the id of the" + + "library for which you are providing additional classpaths"); + } + if (url == null) { + throw new ExecutionException("You must provide an additional " + + "classpath using one of the file, dir or url attributes"); + } + } + + /** + * Add the libpath to the set of paths associated with the library + * + * @exception ExecutionException if the library path cannot be addded to + * the library + */ + public void execute() throws ExecutionException { + AntContext context = getContext(); + ComponentService componentService = (ComponentService) + context.getCoreService(ComponentService.class); + componentService.addLibPath(libraryId, url); + } + + /** + * Check if any of the location specifying attributes have already been + * set. + * + * @exception ExecutionException if the search URL has already been set + */ + private void checkNullURL() throws ExecutionException { + if (url != null) { + throw new ExecutionException("Location of library has already been " + + "set. Please use only one of file, dir or url attributes"); + } + } +} + diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LoadLib.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java similarity index 96% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LoadLib.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java index 431956636..061f4e70c 100644 --- a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LoadLib.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java @@ -128,6 +128,18 @@ public class LoadLib extends AbstractTask { this.importAll = importAll; } + /** + * Validate this task is configured correctly + * + * @exception ExecutionException if the task is not configured correctly + */ + public void validateComponent() throws ExecutionException { + if (url == null) { + throw new ExecutionException("A location from which to load " + + "libraries must be provided"); + } + } + /** * Load the library or libraries and optiinally import their components @@ -136,10 +148,6 @@ public class LoadLib extends AbstractTask { * loaded. */ public void execute() throws ExecutionException { - if (url == null) { - throw new ExecutionException("A location from which to load " - + "libraries must be provided"); - } AntContext context = getContext(); ComponentService componentService = (ComponentService) context.getCoreService(ComponentService.class); diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/PrimitiveConverter.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/PrimitiveConverter.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/PrimitiveConverter.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/PrimitiveConverter.java diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Taskdef.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Taskdef.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Taskdef.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Taskdef.java diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Typedef.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Typedef.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Typedef.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Typedef.java diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/URLConverter.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/URLConverter.java similarity index 100% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/URLConverter.java rename to proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/URLConverter.java diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java b/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java index c54daee59..46eb63b5f 100755 --- a/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java +++ b/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java @@ -75,7 +75,7 @@ import org.apache.ant.common.model.Project; import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.ConfigException; import org.apache.ant.common.util.Location; -import org.apache.ant.common.util.MessageLevel; +import org.apache.ant.common.event.MessageLevel; import org.apache.ant.init.InitConfig; import org.apache.ant.init.InitUtils; @@ -234,7 +234,8 @@ public class Commandline { * Get an option value * * @param args the full list of command line arguments - * @param position the position in the args array where the value shoudl be + * @param position the position in the args array where the value shoudl + * be * @param argType the option type * @return the value of the option * @exception ConfigException if the option cannot be read @@ -262,6 +263,7 @@ public class Commandline { this.initConfig = initConfig; try { parseArguments(args); + determineBuildFile(); AntConfig config = new AntConfig(); AntConfig userConfig = getAntConfig(initConfig.getUserConfigArea()); @@ -293,6 +295,7 @@ public class Commandline { ExecutionManager executionManager = new ExecutionManager(initConfig, config); addBuildListeners(executionManager); + executionManager.init(); executionManager.runBuild(project, targets, definedProperties); } catch (Throwable t) { if (t instanceof AntException) { @@ -332,6 +335,79 @@ public class Commandline { return project; } + /** + * Handle build file argument + * + * @param url the build file's URL + * @exception ConfigException if the build file location is not valid + */ + private void argBuildFile(String url) throws ConfigException { + try { + if (url.indexOf(":") == -1) { + // We convert any hash characters to their URL escape. + buildFileURL = InitUtils.getFileURL(new File(url)); + } else { + buildFileURL = new URL(url); + } + } catch (MalformedURLException e) { + throw new ConfigException("Build file is not valid", e); + } + } + + /** + * Handle the log file option + * + * @param arg the value of the log file option + * @exception ConfigException if the log file is not writeable + */ + private void argLogFile(String arg) throws ConfigException { + try { + File logFile = new File(arg); + out = new PrintStream(new FileOutputStream(logFile)); + err = out; + } catch (IOException ioe) { + throw new ConfigException("Cannot write on the specified log " + + "file. Make sure the path exists and " + + "you have write permissions.", ioe); + } + } + + /** + * Handle the logger attribute + * + * @param arg the logger classname + * @exception ConfigException if a logger has already been defined + */ + private void argLogger(String arg) throws ConfigException { + if (loggerClassname != null) { + throw new ConfigException("Only one logger class may be " + + "specified."); + } + loggerClassname = arg; + } + + + /** + * Determine the build file to use + * + * @exception ConfigException if the build file cannot be found + */ + private void determineBuildFile() throws ConfigException { + if (buildFileURL == null) { + File defaultBuildFile = new File(DEFAULT_BUILD_FILENAME); + if (!defaultBuildFile.exists()) { + File ant1BuildFile = new File(DEFAULT_ANT1_FILENAME); + if (ant1BuildFile.exists()) { + defaultBuildFile = ant1BuildFile; + } + } + try { + buildFileURL = InitUtils.getFileURL(defaultBuildFile); + } catch (MalformedURLException e) { + throw new ConfigException("Build file is not valid", e); + } + } + } /** * Parse the command line arguments. @@ -349,30 +425,9 @@ public class Commandline { if (arg.equals("-buildfile") || arg.equals("-file") || arg.equals("-f")) { - try { - String url = getOption(args, i++, arg); - if (url.indexOf(":") == -1) { - // We convert any hash characters to their URL escape. - buildFileURL = InitUtils.getFileURL(new File(url)); - } else { - buildFileURL = new URL(url); - } - } catch (MalformedURLException e) { - System.err.println("Buildfile is not valid: " + - e.getMessage()); - throw new ConfigException("Build file is not valid", e); - } + argBuildFile(getOption(args, i++, arg)); } else if (arg.equals("-logfile") || arg.equals("-l")) { - try { - File logFile = new File(getOption(args, i++, arg)); - out = new PrintStream(new FileOutputStream(logFile)); - err = out; - } catch (IOException ioe) { - System.err.println("Cannot write on the specified log " + - "file. Make sure the path exists and " + - "you have write permissions."); - return; - } + argLogFile(getOption(args, i++, arg)); } else if (arg.equals("-quiet") || arg.equals("-q")) { messageOutputLevel = MessageLevel.MSG_WARN; } else if (arg.equals("-verbose") || arg.equals("-v")) { @@ -386,12 +441,7 @@ public class Commandline { } else if (arg.equals("-listener")) { listeners.add(getOption(args, i++, arg)); } else if (arg.equals("-logger")) { - if (loggerClassname != null) { - System.err.println("Only one logger class may be " + - "specified."); - return; - } - loggerClassname = getOption(args, i++, arg); + argLogger(getOption(args, i++, arg)); } else if (arg.startsWith("-D")) { String name = arg.substring(2, arg.length()); String value = null; @@ -413,21 +463,6 @@ public class Commandline { } } - if (buildFileURL == null) { - File defaultBuildFile = new File(DEFAULT_BUILD_FILENAME); - if (!defaultBuildFile.exists()) { - File ant1BuildFile = new File(DEFAULT_ANT1_FILENAME); - if (ant1BuildFile.exists()) { - defaultBuildFile = ant1BuildFile; - } - } - try { - buildFileURL = InitUtils.getFileURL(defaultBuildFile); - } catch (MalformedURLException e) { - System.err.println("Buildfile is not valid: " + e.getMessage()); - throw new ConfigException("Build file is not valid", e); - } - } } /** diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java b/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java index 31ab9c56b..a64ba7680 100755 --- a/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java +++ b/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java @@ -59,7 +59,7 @@ import org.apache.ant.common.model.Target; import org.apache.ant.common.event.BuildEvent; import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.Location; -import org.apache.ant.common.util.MessageLevel; +import org.apache.ant.common.event.MessageLevel; /** * Writes build event to a PrintStream. Currently, it only writes which @@ -235,20 +235,22 @@ public class DefaultLogger implements BuildLogger { = event.getPriority() == MessageLevel.MSG_ERR ? err : out; // Filter out messages based on priority - if (event.getPriority() <= messageOutputLevel - && event.getModelElement() instanceof BuildElement) { - // Print out the name of the task if we're in one - BuildElement buildElement - = (BuildElement)event.getModelElement(); - String name = buildElement.getType(); + if (event.getPriority() <= messageOutputLevel) { + + if (event.getModelElement() instanceof BuildElement) { + // Print out the name of the task if we're in one + BuildElement buildElement + = (BuildElement)event.getModelElement(); + String name = buildElement.getType(); - if (!emacsMode) { - String msg = "[" + name + "] "; - int indentSize = LEFT_COLUMN_SIZE - msg.length(); - for (int i = 0; i < indentSize; i++) { - logTo.print(" "); + if (!emacsMode) { + String msg = "[" + name + "] "; + int indentSize = LEFT_COLUMN_SIZE - msg.length(); + for (int i = 0; i < indentSize; i++) { + logTo.print(" "); + } + logTo.print(msg); } - logTo.print(msg); } // Print the message diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java index d90fea972..ce6736c62 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java @@ -68,12 +68,14 @@ public interface AntLibFactory { * Create an instance of the given type class * * @param typeClass the class for which an instance is required + * @param localName the name within the library under which the type is + * defined * @return an 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 type */ - Object createTypeInstance(Class typeClass) + Object createTypeInstance(Class typeClass, String localName) throws InstantiationException, IllegalAccessException, ExecutionException; @@ -89,12 +91,14 @@ public interface AntLibFactory { * Create an instance of the given task class * * @param taskClass the class for which an instance is required + * @param localName the name within the library under which the task is + * defined * @return an 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 task */ - Object createTaskInstance(Class taskClass) + Object createTaskInstance(Class taskClass, String localName) throws InstantiationException, IllegalAccessException, ExecutionException; diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Import.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/DeferredTask.java similarity index 75% rename from proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Import.java rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/DeferredTask.java index 1313b4431..8da1147d2 100644 --- a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Import.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/DeferredTask.java @@ -51,24 +51,38 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.antlib.system; - -import org.apache.ant.common.antlib.AbstractTask; +package org.apache.ant.common.antlib; /** - * Task to import a component or components from a library + * A deferred task is one where the task task responsibility for configuring + * itself at execution time. The attributes and nested elements are stored + * by the task for later use * * @author Conor MacNeill - * @created 27 January 2002 + * @created 11 February 2002 */ -public class Import extends AbstractTask { - /** The Ant LIbrary Id from which the component must be imported */ - private String antlibId = null; - /** The name of the component to be imported */ - private String componentName = null; +public interface DeferredTask extends Task { + /** + * Sets the attribute of the DeferredTask + * + * @param name the attribute name + * @param attributeValue the new attribute value + */ + void setAttribute(String name, String attributeValue); + + /** + * Add a nested element + * + * @param nestedElementName the name of the nested element + * @param value the object which is the nested element + */ + void addElement(String nestedElementName, Object value); - /** Do thw work and import the components */ - public void execute() { - } + /** + * Add any text content + * + * @param text the value of the content + */ + void addText(String text); } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java index b5f4a28b3..8f86faaff 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java @@ -62,16 +62,21 @@ import org.apache.ant.common.util.ExecutionException; * @see AntLibFactory */ public class StandardLibFactory implements AntLibFactory { + /** The context the factory can use to interact with the core */ + private AntContext context; + /** * Create an instance of the given task class * * @param taskClass the class for which an instance is required + * @param localName the name within the library under which the task is + * defined * @return an 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 task */ - public Object createTaskInstance(Class taskClass) + public Object createTaskInstance(Class taskClass, String localName) throws InstantiationException, IllegalAccessException, ExecutionException { return taskClass.newInstance(); @@ -81,12 +86,14 @@ public class StandardLibFactory implements AntLibFactory { * Create an instance of the given type class * * @param typeClass the class for which an instance is required + * @param localName the name within the library under which the type is + * defined, if any. * @return an 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 type */ - public Object createTypeInstance(Class typeClass) + public Object createTypeInstance(Class typeClass, String localName) throws InstantiationException, IllegalAccessException, ExecutionException { return typeClass.newInstance(); @@ -99,7 +106,7 @@ public class StandardLibFactory implements AntLibFactory { * @exception ExecutionException if the factory cannot be initialized */ public void init(AntContext context) throws ExecutionException { - // do nothing + this.context = context; } /** @@ -132,5 +139,14 @@ public class StandardLibFactory implements AntLibFactory { // do nothing } + /** + * Gets the context of the factory + * + * @return the context object + */ + protected AntContext getContext() { + return context; + } + } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java index 826a2db36..a2f7644de 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java @@ -122,9 +122,10 @@ public class BuildEvent extends EventObject { * @param message the message associated with this event * @param priority the message priority */ - public BuildEvent(ModelElement source, String message, + public BuildEvent(Object source, String message, int priority) { - this(source, MESSAGE); + super(source); + this.eventType = MESSAGE; this.message = message; this.messagePriority = priority; } @@ -175,7 +176,12 @@ public class BuildEvent extends EventObject { * @return the model element this event is associated with */ public ModelElement getModelElement() { - return (ModelElement)getSource(); + Object source = getSource(); + if (source instanceof ModelElement) { + return (ModelElement)getSource(); + } + + return null; } } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/MessageLevel.java b/proposal/mutant/src/java/common/org/apache/ant/common/event/MessageLevel.java old mode 100755 new mode 100644 similarity index 98% rename from proposal/mutant/src/java/common/org/apache/ant/common/util/MessageLevel.java rename to proposal/mutant/src/java/common/org/apache/ant/common/event/MessageLevel.java index bdcdc673f..2700df0e9 --- a/proposal/mutant/src/java/common/org/apache/ant/common/util/MessageLevel.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/event/MessageLevel.java @@ -51,7 +51,7 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.common.util; +package org.apache.ant.common.event; /** * The levels at which a log message may be sent. diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java index ddde6b699..b35e571d5 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java @@ -52,6 +52,7 @@ * . */ package org.apache.ant.common.service; +import java.net.URL; import org.apache.ant.common.antlib.AntLibFactory; import org.apache.ant.common.util.ExecutionException; @@ -82,11 +83,23 @@ public interface ComponentService { void loadLib(String libLocation, boolean importAll) throws ExecutionException; + /** + * Add a library path to the given library. The library path is used in + * the construction of the library's classloader + * + * @param libraryId the library's unique identifier + * @param libPath the path to be added to the list of paths used by the + * library. + * @exception ExecutionException if the path cannot be used. + */ + void addLibPath(String libraryId, URL libPath) throws ExecutionException; + /** * 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 @@ -99,7 +112,8 @@ public interface 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 @@ -108,5 +122,28 @@ public interface ComponentService { String taskName, String className) throws ExecutionException; + + /** + * 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 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 + * used. + * @exception ExecutionException if the component cannot be imported + */ + void importComponent(String libraryId, String defName, + String alias) throws ExecutionException; + + /** + * Import a complete library into the current execution frame + * + * @param libraryId The id of the library to be imported + * @exception ExecutionException if the library cannot be imported + */ + void importLibrary(String libraryId) throws ExecutionException; }