From f9d1c1691c7e9d80b793f5178f6113c949fc2441 Mon Sep 17 00:00:00 2001 From: Conor MacNeill Date: Mon, 27 May 2002 15:52:27 +0000 Subject: [PATCH] Change Exception hierarchy Much better Ant1 compatability New monitoring aspect git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272784 13f79535-47bb-0310-9956-ffa450edef68 --- proposal/mutant/build.xml | 60 ++- proposal/mutant/build/ant1compat.xml | 388 +++++++++++++-- .../ant/antcore/antlib/AntLibException.java} | 23 +- .../ant/antcore/antlib/AntLibHandler.java | 7 +- .../ant/antcore/antlib/AntLibManager.java | 260 +++++----- .../apache/ant/antcore/antlib/AntLibrary.java | 14 +- .../ant/antcore/antlib/AntLibrarySpec.java | 11 +- .../ant/antcore/antlib/ComponentLibrary.java | 6 +- .../apache/ant/antcore/config/AntConfig.java | 82 ++- .../ant/antcore/config/AntConfigHandler.java | 30 +- .../antcore/execution/AttributeSetter.java | 52 +- .../antcore/execution/BuildEventSupport.java | 8 +- .../antcore/execution/ComponentManager.java | 247 +++++---- .../antcore/execution/CoreDataService.java | 10 +- .../antcore/execution/CoreEventService.java | 1 - .../antcore/execution/CoreExecService.java | 116 +++-- .../antcore/execution/CoreFileService.java | 6 +- .../antcore/execution/CoreInputService.java | 1 - .../ant/antcore/execution/DeferredSetter.java | 1 - .../antcore/execution/ExecutionContext.java | 5 +- .../antcore/execution/ExecutionManager.java | 201 -------- .../apache/ant/antcore/execution/Frame.java | 447 ++++++++++++----- .../ant/antcore/execution/Reflector.java | 26 +- .../apache/ant/antcore/execution/Setter.java | 6 +- .../ant/antcore/execution/TaskAdapter.java | 13 +- .../apache/tools/ant/Ant1CompatException.java | 129 +++++ .../org/apache/tools/ant/Ant1Converter.java | 12 +- .../org/apache/tools/ant/Ant1Factory.java | 28 +- .../apache/tools/ant/Ant1InputHandler.java | 4 +- .../org/apache/tools/ant/Project.java | 468 ++++++++++++++---- .../apache/tools/ant/ProjectComponent.java | 8 +- .../org/apache/tools/ant/ProjectHelper.java | 16 +- .../ant1compat/org/apache/tools/ant/Task.java | 24 +- .../org/apache/tools/ant/taskdefs/Ant.java | 16 +- .../apache/tools/ant/taskdefs/CallTarget.java | 14 +- .../src/java/antlibs/monitor/antlib.xml | 4 + .../ant/antlib/monitor/MonitorAspect.java | 176 +++++++ .../ant/antlib/monitor/MonitorRecord.java | 94 ++++ .../apache/ant/antlib/script/ScriptBase.java | 19 +- .../apache/ant/antlib/script/ScriptDef.java | 6 +- .../ant/antlib/script/ScriptException.java | 129 +++++ .../ant/antlib/script/ScriptFactory.java | 21 +- .../org/apache/ant/antlib/system/Ant.java | 49 +- .../apache/ant/antlib/system/AntAspect.java | 65 +-- .../org/apache/ant/antlib/system/AntBase.java | 15 +- .../org/apache/ant/antlib/system/AntCall.java | 12 +- .../ant/antlib/system/FileConverter.java | 10 +- .../org/apache/ant/antlib/system/Import.java | 17 +- .../org/apache/ant/antlib/system/LibPath.java | 44 +- .../org/apache/ant/antlib/system/LoadLib.java | 40 +- .../apache/ant/antlib/system/Parallel.java | 18 +- .../ant/antlib/system/PrimitiveConverter.java | 18 +- .../org/apache/ant/antlib/system/Ref.java | 10 +- .../apache/ant/antlib/system/Sequential.java | 6 +- .../apache/ant/antlib/system/SubBuild.java | 41 +- .../ant/antlib/system/SystemException.java | 129 +++++ .../ant/antlib/system/URLConverter.java | 10 +- .../ant/common/antlib/AbstractAspect.java | 58 ++- .../ant/common/antlib/AbstractComponent.java | 14 +- .../ant/common/antlib/AbstractTask.java | 10 +- .../apache/ant/common/antlib/AntContext.java | 6 +- .../ant/common/antlib/AntLibFactory.java | 18 +- .../org/apache/ant/common/antlib/Aspect.java | 46 +- .../ant/common/antlib/AspectException.java | 129 +++++ .../apache/ant/common/antlib/Converter.java | 10 +- .../ant/common/antlib/ConverterException.java | 129 +++++ .../ant/common/antlib/ExecutionComponent.java | 10 +- .../ant/common/antlib/StandardLibFactory.java | 18 +- .../org/apache/ant/common/antlib/Task.java | 14 +- .../ant/common/antlib/TaskContainer.java | 6 +- .../common/antlib/ValidationException.java | 130 +++++ .../ant/common/logger}/BuildLogger.java | 2 +- .../ant/common/logger}/DefaultLogger.java | 2 +- .../apache/ant/common/service/BuildKey.java | 63 +++ .../ant/common/service/ComponentService.java | 50 +- .../ant/common/service/DataService.java | 26 +- .../ant/common/service/EventService.java | 10 +- .../ant/common/service/ExecService.java | 97 +++- .../ant/common/service/FileService.java | 6 +- .../ant/common/service/InputService.java | 6 +- .../ant/common/service/MagicProperties.java | 12 + .../org/apache/ant/common/util/FileUtils.java | 16 +- ...onException.java => GeneralException.java} | 25 +- .../apache/ant/common/util/PropertyUtils.java | 6 +- .../org/apache/ant/cli/Commandline.java | 91 ++-- .../ant/frontend/FrontendException.java | 129 +++++ .../apache/ant/frontend/FrontendUtils.java | 17 +- 87 files changed, 3431 insertions(+), 1398 deletions(-) rename proposal/mutant/src/java/{common/org/apache/ant/common/util/ConfigException.java => antcore/org/apache/ant/antcore/antlib/AntLibException.java} (88%) delete mode 100755 proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java create mode 100644 proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1CompatException.java create mode 100644 proposal/mutant/src/java/antlibs/monitor/antlib.xml create mode 100644 proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java create mode 100644 proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorRecord.java create mode 100644 proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptException.java create mode 100644 proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SystemException.java create mode 100644 proposal/mutant/src/java/common/org/apache/ant/common/antlib/AspectException.java create mode 100644 proposal/mutant/src/java/common/org/apache/ant/common/antlib/ConverterException.java create mode 100644 proposal/mutant/src/java/common/org/apache/ant/common/antlib/ValidationException.java rename proposal/mutant/src/java/{frontend/org/apache/ant/cli => common/org/apache/ant/common/logger}/BuildLogger.java (98%) rename proposal/mutant/src/java/{frontend/org/apache/ant/cli => common/org/apache/ant/common/logger}/DefaultLogger.java (99%) create mode 100644 proposal/mutant/src/java/common/org/apache/ant/common/service/BuildKey.java rename proposal/mutant/src/java/common/org/apache/ant/common/util/{ExecutionException.java => GeneralException.java} (88%) create mode 100644 proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendException.java diff --git a/proposal/mutant/build.xml b/proposal/mutant/build.xml index a6e4e87e4..830e89922 100644 --- a/proposal/mutant/build.xml +++ b/proposal/mutant/build.xml @@ -8,13 +8,13 @@ - + - + @@ -29,13 +29,13 @@ - + - @@ -123,7 +123,7 @@ - + @@ -138,38 +138,46 @@ - + - - + + + + + + + + + + - - - - + + + + - + - + - - + - - - + + + @@ -184,7 +192,7 @@ - @@ -194,14 +202,14 @@ - + + + + + + + + + diff --git a/proposal/mutant/build/ant1compat.xml b/proposal/mutant/build/ant1compat.xml index c7593bfc4..79867529f 100644 --- a/proposal/mutant/build/ant1compat.xml +++ b/proposal/mutant/build/ant1compat.xml @@ -1,36 +1,72 @@ + + + + + + + + + + + + + + - + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + - - + @@ -51,7 +87,17 @@ - + + + + + + + + + + + @@ -71,13 +117,8 @@ - - - - - - - + + - + + - + - @@ -154,7 +199,7 @@ unless="xalan2.present" /> - @@ -165,15 +210,15 @@ unless="jakarta.regexp.present" /> - - - - @@ -184,12 +229,16 @@ + + + - - @@ -205,7 +254,7 @@ unless="netrexx.present" /> - @@ -215,7 +264,7 @@ - @@ -231,7 +280,7 @@ unless="starteam.present" /> - @@ -253,6 +302,8 @@ + + - + @@ -379,7 +433,14 @@ - + + + + + + + + @@ -389,17 +450,29 @@ + + + + + + + + + + - + - + @@ -421,7 +494,7 @@ - + csc.found=${csc.found} @@ -431,21 +504,23 @@ - - + + @@ -485,14 +560,235 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + offline=${offline} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/ConfigException.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibException.java similarity index 88% rename from proposal/mutant/src/java/common/org/apache/ant/common/util/ConfigException.java rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibException.java index 4055bcc62..b42eab7e7 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/util/ConfigException.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibException.java @@ -51,22 +51,23 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.common.util; +package org.apache.ant.antcore.antlib; + +import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.Location; /** - * A ConfigException indicates a problem with Ant's configuration or the - * commandline used to start Ant. + * An AntLibException indicates a problem in an ant library * * @author Conor MacNeill - * @created 9 January 2002 */ -public class ConfigException extends AntException { +public class AntLibException extends AntException { /** * Constructs an exception with the given descriptive message. * * @param msg Description of or information about the exception. */ - public ConfigException(String msg) { + public AntLibException(String msg) { super(msg); } @@ -78,7 +79,7 @@ public class ConfigException extends AntException { * @param msg Description of or information about the exception. * @param location Location in the project file where the error occured. */ - public ConfigException(String msg, Location location) { + public AntLibException(String msg, Location location) { super(msg, location); } @@ -90,7 +91,7 @@ public class ConfigException extends AntException { * @param msg Description of or information about the exception. * @param cause Throwable that might have cause this one. */ - public ConfigException(String msg, Throwable cause) { + public AntLibException(String msg, Throwable cause) { super(msg, cause); } @@ -103,7 +104,7 @@ public class ConfigException extends AntException { * @param cause Exception that might have cause this one. * @param location Location in the project file where the error occured. */ - public ConfigException(String msg, Throwable cause, Location location) { + public AntLibException(String msg, Throwable cause, Location location) { super(msg, cause, location); } @@ -113,7 +114,7 @@ public class ConfigException extends AntException { * * @param cause Exception that might have caused this one. */ - public ConfigException(Throwable cause) { + public AntLibException(Throwable cause) { super(cause); } @@ -125,7 +126,7 @@ public class ConfigException extends AntException { * @param cause Exception that might have cause this one. * @param location Location in the project file where the error occured. */ - public ConfigException(Throwable cause, Location location) { + public AntLibException(Throwable cause, Location location) { super(cause, location); } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java index 4a63541fb..761fc1b88 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java @@ -52,7 +52,6 @@ * . */ package org.apache.ant.antcore.antlib; -import org.apache.ant.common.util.ConfigException; import org.apache.ant.antcore.xml.ElementHandler; import org.xml.sax.Attributes; import org.xml.sax.SAXParseException; @@ -80,7 +79,7 @@ public class AntLibHandler extends ElementHandler { /** The extends attribute name */ public static final String ISOLATED_ATTR = "isolated"; - + /** The list of allowed Attributes */ public static final String[] ALLOWED_ATTRIBUTES = {LIBID_ATTR, HOME_ATTR, REQXML_ATTR, REQTOOLS_ATTR, @@ -166,8 +165,8 @@ public class AntLibHandler extends ElementHandler { } else { super.startElement(uri, localName, qualifiedName, attributes); } - } catch (ConfigException e) { - throw new SAXParseException(e.getMessage(), getLocator()); + } catch (AntLibException e) { + throw new SAXParseException(e.getMessage(), getLocator(), e); } } 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 da6880e8e..5f9c156b4 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 @@ -52,7 +52,6 @@ * . */ package org.apache.ant.antcore.antlib; -import java.io.File; import java.io.FileNotFoundException; import java.net.MalformedURLException; import java.net.URL; @@ -65,18 +64,22 @@ import org.apache.ant.antcore.xml.ParseContext; import org.apache.ant.antcore.xml.XMLParseException; import org.apache.ant.common.util.CircularDependencyChecker; import org.apache.ant.common.util.CircularDependencyException; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.init.InitConfig; -import org.apache.ant.init.InitUtils; import org.apache.ant.init.LoaderUtils; /** - * This class manages the configuration of Ant Libraries + * This class manages Ant Libraries. This class forms a global + * repository of loaded libraries so that only one copy of a library is + * used across all frames. * * @author Conor MacNeill * @created 29 January 2002 */ public class AntLibManager { + /** + * These are AntLibraries which have been loaded into the system + */ + private Map antLibraries = new HashMap(); /** The list of extensions which are examined for ant libraries */ public static final String[] ANTLIB_EXTENSIONS @@ -85,14 +88,25 @@ public class AntLibManager { /** Flag which indicates whether non-file URLS are used */ private boolean remoteAllowed; + /** The Ant initialization config - location of vital components */ + private InitConfig initConfig; + + /** + * This map stores a list of additional paths for each library indexed by + * the libraryId + */ + private Map libPathsMap = new HashMap(); + /** * Constructor for the AntLibManager object * + * @param initConfig the init config of the system. * @param remoteAllowed true if remote libraries can be used and * configured */ - public AntLibManager(boolean remoteAllowed) { + public AntLibManager(InitConfig initConfig, boolean remoteAllowed) { this.remoteAllowed = remoteAllowed; + this.initConfig = initConfig; } /** @@ -101,47 +115,53 @@ public class AntLibManager { * @param librarySpecs A map to which additional library specifications * are added. * @param libURL the URL from which Ant libraries are to be loaded - * @exception MalformedURLException if the URL for the individual - * library components cannot be formed - * @exception ExecutionException if the library specs cannot be parsed + * @exception AntLibException if the library specs cannot be parsed */ public void addAntLibraries(Map librarySpecs, URL libURL) - throws MalformedURLException, ExecutionException { - URL[] libURLs = LoaderUtils.getLocationURLs(libURL, libURL.toString(), - ANTLIB_EXTENSIONS); + throws AntLibException { + try { + URL[] libURLs = LoaderUtils.getLocationURLs(libURL, + libURL.toString(), ANTLIB_EXTENSIONS); - if (libURLs == null) { - return; - } + if (libURLs == null) { + return; + } - // parse each task library to get its library definition - for (int i = 0; i < libURLs.length; ++i) { - URL antLibraryURL = new URL("jar:" + libURLs[i] - + "!/META-INF/antlib.xml"); - try { - AntLibrarySpec antLibrarySpec = parseLibraryDef(antLibraryURL); - if (antLibrarySpec != null) { - String libraryId = antLibrarySpec.getLibraryId(); - if (librarySpecs.containsKey(libraryId)) { - AntLibrarySpec currentSpec - = (AntLibrarySpec) librarySpecs.get(libraryId); - throw new ExecutionException("Found more than one " - + "copy of library with id = " + libraryId - + " (" + libURLs[i] + ") + existing library at (" - + currentSpec.getLibraryURL() + ")"); + // parse each task library to get its library definition + for (int i = 0; i < libURLs.length; ++i) { + URL antLibraryURL = new URL("jar:" + libURLs[i] + + "!/META-INF/antlib.xml"); + try { + AntLibrarySpec antLibrarySpec + = parseLibraryDef(antLibraryURL); + if (antLibrarySpec != null) { + String libraryId = antLibrarySpec.getLibraryId(); + if (librarySpecs.containsKey(libraryId)) { + AntLibrarySpec currentSpec + = (AntLibrarySpec) librarySpecs.get(libraryId); + throw new AntLibException("Found more than one " + + "copy of library with id = " + libraryId + + " (" + libURLs[i] + ") + existing library " + + "at (" + currentSpec.getLibraryURL() + ")"); + } + antLibrarySpec.setLibraryURL(libURLs[i]); + librarySpecs.put(libraryId, antLibrarySpec); + } + } catch (XMLParseException e) { + Throwable t = e.getCause(); + // ignore file not found exceptions - means the + // jar does not provide META-INF/antlib.xml + if (t instanceof AntLibException) { + throw (AntLibException) t; + } else if (!(t instanceof FileNotFoundException)) { + throw new AntLibException("Unable to parse Ant " + + "library " + libURLs[i], e); } - antLibrarySpec.setLibraryURL(libURLs[i]); - librarySpecs.put(libraryId, antLibrarySpec); - } - } catch (XMLParseException e) { - Throwable t = e.getCause(); - // ignore file not found exceptions - means the - // jar does not provide META-INF/antlib.xml - if (!(t instanceof FileNotFoundException)) { - throw new ExecutionException("Unable to parse Ant library " - + libURLs[i], e); } } + } catch (MalformedURLException e) { + throw new AntLibException("Unable to load libraries from " + + libURL, e); } } @@ -151,32 +171,27 @@ public class AntLibManager { * creating the class loaders for the library * * @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 paths for each library * @return A map of the newly configured libraries - * @exception ExecutionException if a library cannot be configured from + * @exception AntLibException if a library cannot be configured from * the given specification */ - public Map configLibraries(InitConfig initConfig, Map librarySpecs, - Map libraries, Map libPathsMap) - throws ExecutionException { + private Map configLibraries(Map librarySpecs) + throws AntLibException { // check if any already defined for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext();) { String libraryId = (String) i.next(); - if (libraries.containsKey(libraryId)) { - AntLibrary currentVersion - = (AntLibrary) libraries.get(libraryId); + if (antLibraries.containsKey(libraryId)) { + AntLibrary currentVersion = getLibrary(libraryId); // same location? - AntLibrarySpec spec - = (AntLibrarySpec) librarySpecs.get(libraryId); + AntLibrarySpec spec + = (AntLibrarySpec) librarySpecs.get(libraryId); URL specURL = spec.getLibraryURL(); if (!specURL.equals(currentVersion.getDefinitionURL())) { - throw new ExecutionException("Ant Library \"" + libraryId + throw new AntLibException("Ant Library \"" + libraryId + "\" is already loaded from " - + currentVersion.getDefinitionURL() - + " new version found at " + + currentVersion.getDefinitionURL() + + " new version found at " + specURL); } } @@ -187,12 +202,12 @@ public class AntLibManager { = new CircularDependencyChecker("configuring Ant libraries"); for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext();) { String libraryId = (String) i.next(); - if (!libraries.containsKey(libraryId)) { - configLibrary(initConfig, librarySpecs, libraryId, - configuring, libraries, newLibraries, libPathsMap); + if (!antLibraries.containsKey(libraryId)) { + configLibrary(librarySpecs, libraryId, + configuring, newLibraries); } } - + return newLibraries; } @@ -200,87 +215,74 @@ public class AntLibManager { * Load either a set of libraries or a single library. * * @param libLocationURL URL where libraries can be found - * @param librarySpecs A collection of library specs which will be - * populated with the libraries found - * @exception ExecutionException if the libraries cannot be loaded - * @exception MalformedURLException if the library's location cannot be - * formed + * @exception AntLibException if the libraries cannot be loaded + * + * @return a map containing the newly loaded libraries indexed by their + * library ids. */ - public void loadLibs(Map librarySpecs, URL libLocationURL) - throws ExecutionException, MalformedURLException { + public Map loadLibs(URL libLocationURL) + throws AntLibException { if (!libLocationURL.getProtocol().equals("file") && !remoteAllowed) { - throw new ExecutionException("The config library " + throw new AntLibException("The config library " + "location \"" + libLocationURL + "\" cannot be used because config does " + "not allow remote libraries"); } + + Map librarySpecs = new HashMap(); addAntLibraries(librarySpecs, libLocationURL); - } - - /** - * Load either a set of libraries or a single library. - * - * @param libLocationString URL or file where libraries can be found - * @param librarySpecs A collection of library specs which will be - * populated with the libraries found - * @exception ExecutionException if the libraries cannot be loaded - * @exception MalformedURLException if the library's location cannot be - * formed - */ - public void loadLibs(Map librarySpecs, String libLocationString) - throws ExecutionException, MalformedURLException { - - File libLocation = new File(libLocationString); - if (!libLocation.exists()) { - try { - loadLibs(librarySpecs, new URL(libLocationString)); - } catch (MalformedURLException e) { - // XXX - } - } else { - addAntLibraries(librarySpecs, InitUtils.getFileURL(libLocation)); - } + Map newLibraries = configLibraries(librarySpecs); + + antLibraries.putAll(newLibraries); + return newLibraries; } /** * 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 + * @param libraryId the id of the library to which the path is to be added + * @param libPath the path to be added + * @exception AntLibException if remote paths are not allowed by * configuration */ - public void addLibPath(AntLibrary antLibrary, URL path) - throws ExecutionException { - if (!path.getProtocol().equals("file") + public void addLibPath(String libraryId, URL libPath) + throws AntLibException { + System.out.println("Adding path " + libPath + " for " + libraryId); + if (!libPath.getProtocol().equals("file") && !remoteAllowed) { - throw new ExecutionException("Remote libpaths are not" - + " allowed: " + path); + throw new AntLibException("Remote libpaths are not" + + " allowed: " + libPath); + } + + List libPaths = (List) libPathsMap.get(libraryId); + if (libPaths == null) { + libPaths = new ArrayList(); + libPathsMap.put(libraryId, libPaths); + } + libPaths.add(libPath); + + AntLibrary antLibrary = getLibrary(libraryId); + if (antLibrary != null) { + antLibrary.addLibraryURL(libPath); } - antLibrary.addLibraryURL(path); } /** * Configure a library from a specification and the Ant init config. * - * @param initConfig Ant's init config passed in from the front end. * @param librarySpecs the library specs from which this library is to * be configured. * @param libraryId the global identifier for the library * @param configuring A circualr dependency chcker for library * dependencies. - * @param libraries the collection of libraries which have already been - * configured - * @param newLibraries the new libraries being configured. - * @param libPathsMap a map of lists of library patsh fro each library - * @exception ExecutionException if the library cannot be configured. + * @param newLibraries the new libraries being configured. + * @exception AntLibException if the library cannot be configured. */ - private void configLibrary(InitConfig initConfig, Map librarySpecs, - String libraryId, + private void configLibrary(Map librarySpecs, String libraryId, CircularDependencyChecker configuring, - Map libraries, Map newLibraries, Map libPathsMap) - throws ExecutionException { + Map newLibraries) + throws AntLibException { try { configuring.visitNode(libraryId); @@ -289,15 +291,15 @@ public class AntLibManager { = (AntLibrarySpec) librarySpecs.get(libraryId); String extendsId = librarySpec.getExtendsLibraryId(); if (extendsId != null) { - if (!libraries.containsKey(extendsId) && + if (!antLibraries.containsKey(extendsId) && !newLibraries.containsKey(extendsId)) { if (!librarySpecs.containsKey(extendsId)) { - throw new ExecutionException("Could not find library, " + throw new AntLibException("Could not find library, " + extendsId + ", upon which library " + libraryId + " depends"); } - configLibrary(initConfig, librarySpecs, extendsId, - configuring, libraries, newLibraries, libPathsMap); + configLibrary(librarySpecs, extendsId, + configuring, newLibraries); } } @@ -328,12 +330,11 @@ public class AntLibManager { antLibrary.addLibraryURL((URL) i.next()); } if (extendsId != null) { - AntLibrary extendsLibrary - = (AntLibrary) libraries.get(extendsId); + AntLibrary extendsLibrary = getLibrary(extendsId); if (extendsLibrary == null) { extendsLibrary = (AntLibrary) newLibraries.get(extendsId); } - + antLibrary.setExtendsLibrary(extendsLibrary); } antLibrary.setParentLoader(initConfig.getCommonLoader()); @@ -344,14 +345,13 @@ public class AntLibManager { if (libPaths != null) { for (Iterator j = libPaths.iterator(); j.hasNext();) { URL pathURL = (URL) j.next(); - addLibPath(antLibrary, pathURL); + antLibrary.addLibraryURL(pathURL); } } } - configuring.leaveNode(libraryId); } catch (CircularDependencyException e) { - throw new ExecutionException(e); + throw new AntLibException(e); } } @@ -374,5 +374,25 @@ public class AntLibManager { return libHandler.getAntLibrarySpec(); } + + /** + * Get a loaded library by its id. + * + * @param libraryId the library's global id + * + * @return the requested library or null if it has not been loaded + */ + public AntLibrary getLibrary(String libraryId) { + return (AntLibrary) antLibraries.get(libraryId); + } + + /** + * Get all the library ids of the currently loaded libraries. + * + * @return an iterator over the library identifier strings. + */ + public Iterator getLibraryIds() { + return antLibraries.keySet().iterator(); + } } 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 a0d186072..cf9aafc07 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 @@ -60,7 +60,7 @@ import java.util.List; import java.util.Map; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.AntLibFactory; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * This class represents the Ant library. @@ -221,10 +221,10 @@ public class AntLibrary implements ComponentLibrary { * required * @return an instance of the factory, or null if this library does not * support a factory - * @exception ExecutionException if the factory cannot be created + * @exception AntException if the factory cannot be created */ public AntLibFactory getFactory(AntContext context) - throws ExecutionException { + throws AntException { try { AntLibFactory libFactory = null; if (factoryClassName != null) { @@ -236,20 +236,20 @@ public class AntLibrary implements ComponentLibrary { } return libFactory; } catch (ClassNotFoundException e) { - throw new ExecutionException("Unable to create factory " + throw new AntLibException("Unable to create factory " + factoryClassName + " for the \"" + libraryId + "\" Ant library", e); } catch (NoClassDefFoundError e) { - throw new ExecutionException("Could not load a dependent class (" + throw new AntLibException("Could not load a dependent class (" + e.getMessage() + ") to create the factory " + factoryClassName + " for the \"" + libraryId + "\" Ant library", e); } catch (InstantiationException e) { - throw new ExecutionException("Unable to instantiate factory " + throw new AntLibException("Unable to instantiate factory " + factoryClassName + " for the \"" + libraryId + "\" Ant library", e); } catch (IllegalAccessException e) { - throw new ExecutionException("Unable to access factory " + throw new AntLibException("Unable to access factory " + factoryClassName + " for the \"" + libraryId + "\" Ant library", e); } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java index 3550eeb17..bd4d051c2 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrarySpec.java @@ -57,7 +57,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.ant.common.util.ConfigException; /** * This class represents the specification of an Ant library. It is merely @@ -291,7 +290,7 @@ public class AntLibrarySpec { public void addAspect(String className) { aspectClassNames.add(className); } - + /** * Indicates if this library requires Ant's XML parser * @@ -308,13 +307,13 @@ public class AntLibrarySpec { * @param classname the name of the class implementing the element * @param definitionTypeName the name of the definition type. This is * converted to its symbolic value - * @exception ConfigException if the definition has already been defined + * @exception AntLibException if the definition has already been defined */ public void addDefinition(String definitionTypeName, String name, String classname) - throws ConfigException { + throws AntLibException { if (definitions.containsKey(name)) { - throw new ConfigException("More than one definition " + throw new AntLibException("More than one definition " + "in library for " + name); } int definitionType = 0; @@ -324,7 +323,7 @@ public class AntLibrarySpec { } else if (definitionTypeName.equals("taskdef")) { definitionType = AntLibrary.TASKDEF; } else { - throw new ConfigException("Unknown type of definition " + throw new AntLibException("Unknown type of definition " + definitionTypeName); } definitions.put(name, diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ComponentLibrary.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ComponentLibrary.java index 4e89117f3..91b7a6b2c 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ComponentLibrary.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ComponentLibrary.java @@ -54,7 +54,7 @@ package org.apache.ant.antcore.antlib; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.AntLibFactory; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * A Component Library supplies components to the Ant core. @@ -83,9 +83,9 @@ public interface ComponentLibrary { * required * @return an instance of the factory, or null if this library does not * support a factory - * @exception ExecutionException if the factory cannot be created + * @exception AntException if the factory cannot be created */ - AntLibFactory getFactory(AntContext context) throws ExecutionException; + AntLibFactory getFactory(AntContext context) throws AntException; /** * Gets the libraryId of the AntLibrary 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 ed16ce7e1..5d78e895c 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 @@ -52,9 +52,7 @@ * . */ package org.apache.ant.antcore.config; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import org.apache.ant.common.model.BuildElement; /** @@ -75,10 +73,15 @@ public class AntConfig { private boolean unsetProperties = true; /** - * Configuration tasks. + * Global Configuration tasks. These are run only once. */ - private List tasks = new ArrayList(); - + private BuildElement globalTasks; + + /** + * Frame tasks - these are run in each new frame. + */ + private BuildElement frameTasks; + /** * Indicate if unset properties are OK. * @@ -107,21 +110,47 @@ public class AntConfig { } /** - * Get the configuration tasks + * Get the global configuration tasks * * @return an iterator over the set of config tasks. */ - public Iterator getTasks() { - return tasks.iterator(); + public Iterator getGlobalTasks() { + if (globalTasks == null) { + return null; + } + return globalTasks.getNestedElements(); } /** - * Add a config task. + * Get the per-frame configuration tasks * - * @param task a task to be executed as part of the configuration process. + * @return an iterator over the set of config tasks. */ - public void addTask(BuildElement task) { - tasks.add(task); + public Iterator getFrameTasks() { + if (frameTasks == null) { + return null; + } + return frameTasks.getNestedElements(); + } + + /** + * Add a global config task. + * + * @param globalTasks a collection of tasks to be executed as part of + * the configuration process. + */ + public void addGlobalTasks(BuildElement globalTasks) { + this.globalTasks = globalTasks; + } + + /** + * Add a per-frame config task. + * + * @param frameTasks a collection of tasks to be executed as part of the + * setup of each new frame. + */ + public void addFrameTasks(BuildElement frameTasks) { + this.frameTasks = frameTasks; } /** @@ -151,7 +180,7 @@ public class AntConfig { public void allowUnsetProperties(boolean allowUnsetProperties) { this.unsetProperties = allowUnsetProperties; } - + /** * Merge in another configuration. The configuration being merged in * takes precedence @@ -162,7 +191,32 @@ public class AntConfig { remoteLibs = otherConfig.remoteLibs; remoteProjects = otherConfig.remoteProjects; unsetProperties = otherConfig.unsetProperties; - tasks.addAll(otherConfig.tasks); + globalTasks = combineTasks(globalTasks, otherConfig.globalTasks); + frameTasks = combineTasks(frameTasks, otherConfig.frameTasks); + } + + /** + * Combine two task collections + * + * @param lhs the lefthand collection + * @param rhs the right hand collection + * + * @return the combined collection of tasks + */ + private BuildElement combineTasks(BuildElement lhs, BuildElement rhs) { + if (rhs == null) { + return lhs; + } + + if (lhs == null) { + return rhs; + } + + for (Iterator i = rhs.getNestedElements(); i.hasNext();) { + lhs.addNestedElement((BuildElement) i.next()); + } + + return lhs; } } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java index 124ff1dbc..973d139a4 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java @@ -54,6 +54,7 @@ package org.apache.ant.antcore.config; import org.apache.ant.antcore.xml.ElementHandler; import org.apache.ant.antcore.modelparser.BuildElementHandler; +import org.apache.ant.common.model.BuildElement; import org.xml.sax.Attributes; import org.xml.sax.SAXParseException; @@ -66,13 +67,19 @@ import org.xml.sax.SAXParseException; public class AntConfigHandler extends ElementHandler { /** The allowRemoteProject attribute name */ public static final String REMOTE_PROJECT_ATTR = "allow-remote-project"; - + /** The allowRemoteLibrary attribute name */ public static final String REMOTE_LIBRARY_ATTR = "allow-remote-library"; /** The allowReportProject attribute name */ public static final String UNSET_PROPS_ATTR = "allow-unset-properties"; + /** The global tasks element */ + public static final String GLOBAL_TASKS_ELEMENT = "global-tasks"; + + /** The per-frame tasks element */ + public static final String PERFRAME_TASKS_ELEMENT = "frame-tasks"; + /** The list of allowed Attributes */ public static final String[] ALLOWED_ATTRIBUTES = {REMOTE_PROJECT_ATTR, REMOTE_LIBRARY_ATTR, UNSET_PROPS_ATTR}; @@ -108,8 +115,8 @@ public class AntConfigHandler extends ElementHandler { allowUnsetProperties = getBooleanAttribute(UNSET_PROPS_ATTR); } config.allowUnsetProperties(allowUnsetProperties); - } - + } + /** * Start a new element in the ant config. * @@ -123,17 +130,20 @@ public class AntConfigHandler extends ElementHandler { Attributes attributes) throws SAXParseException { - // everything else is a task + // configs support two task collections as elements BuildElementHandler buildElementHandler = new BuildElementHandler(); buildElementHandler.start(getParseContext(), getXMLReader(), this, getLocator(), attributes, getElementSource(), qualifiedName); - config.addTask(buildElementHandler.getBuildElement()); -// try { -// } catch (ConfigException e) { -// throw new SAXParseException("Unable to process config", -// getLocator(), e); -// } + BuildElement element = buildElementHandler.getBuildElement(); + if (element.getType().equals(GLOBAL_TASKS_ELEMENT)) { + config.addGlobalTasks(element); + } else if (element.getType().equals(PERFRAME_TASKS_ELEMENT)) { + config.addFrameTasks(element); + } else { + throw new SAXParseException(" does not support the <" + + element.getType() + "> element", getLocator()); + } } /** diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/AttributeSetter.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/AttributeSetter.java index 336749dcb..370b7f053 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/AttributeSetter.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/AttributeSetter.java @@ -56,7 +56,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.ant.common.antlib.Converter; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * AttributeSetters are created at introspection time for each @@ -69,25 +69,25 @@ import org.apache.ant.common.util.ExecutionException; public class AttributeSetter { /** The method that will perform the setting */ private Method method; - - /** - * A converter to convert the string value to a value to be given to - * the setter method - */ + + /** + * A converter to convert the string value to a value to be given to + * the setter method + */ private Converter converter; - + /** * A constructor used to create the string value to an object to be used - * by the setter + * by the setter */ private Constructor valueConstructor; - + /** The depth of the setter in the class hierarchy */ private int depth; /** - * Create a setter which just uses string values - * + * Create a setter which just uses string values + * * @param method the method to be invoked. * @param depth the depth of this method declaraion in the class hierarchy. */ @@ -97,8 +97,8 @@ public class AttributeSetter { } /** - * Create a setter which just uses string values - * + * Create a setter which just uses string values + * * @param method the method to be invoked. * @param depth the depth of this method declaraion in the class hierarchy. * @param converter a converter to convert string values into instances of @@ -110,19 +110,19 @@ public class AttributeSetter { } /** - * Create a setter which just uses string values - * + * Create a setter which just uses string values + * * @param method the method to be invoked. * @param depth the depth of this method declaraion in the class hierarchy. - * @param valueConstructor an object constructor used to convert string + * @param valueConstructor an object constructor used to convert string * values into instances of the type expected by the method. */ - public AttributeSetter(Method method, int depth, + public AttributeSetter(Method method, int depth, Constructor valueConstructor) { this(method, depth); this.valueConstructor = valueConstructor; } - + /** * Set the attribute value on an object * @@ -131,17 +131,17 @@ public class AttributeSetter { * @exception InvocationTargetException if the method cannot be * invoked * @exception IllegalAccessException if the method cannot be invoked - * @exception ExecutionException if the conversion of the value + * @exception AntException if the conversion of the value * fails */ void set(Object obj, String stringValue) throws InvocationTargetException, IllegalAccessException, - ExecutionException { - + AntException { + Object value = null; if (converter != null) { Class type = getType(); - value = converter.convert(stringValue, type); + value = converter.convert(stringValue, type); } else if (valueConstructor != null) { try { value = valueConstructor.newInstance(new String[]{stringValue}); @@ -151,19 +151,19 @@ public class AttributeSetter { } else { value = stringValue; } - + method.invoke(obj, new Object[]{value}); } - + /** - * Get the declaration depth of this setter. + * Get the declaration depth of this setter. * * @return the attribute setter's declaration depth. */ public int getDepth() { return depth; } - + /** * Get the type expected by this setter's method * 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 0b47ae060..a04595485 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 @@ -63,7 +63,7 @@ import org.apache.ant.common.event.BuildListener; import org.apache.ant.common.model.ModelElement; import org.apache.ant.common.util.DemuxOutputReceiver; import org.apache.ant.common.event.MessageLevel; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * BuildEventSupport is used by classes which which to send build events to @@ -239,11 +239,11 @@ public class BuildEventSupport implements DemuxOutputReceiver { task.handleSystemOut(line); } return; - } catch (ExecutionException e) { - // ignore just log normally + } catch (AntException e) { + // ignore just log as a non-task message } } - fireMessageLogged(this, line, + fireMessageLogged(this, line, isError ? MessageLevel.MSG_ERR : MessageLevel.MSG_INFO); } } 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 a2aa510f2..179679e60 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 @@ -52,7 +52,6 @@ * . */ package org.apache.ant.antcore.execution; -import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; @@ -78,7 +77,7 @@ import org.apache.ant.common.antlib.TaskContainer; import org.apache.ant.common.event.MessageLevel; import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.service.ComponentService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.Location; import org.apache.ant.init.LoaderUtils; @@ -91,11 +90,6 @@ import org.apache.ant.init.LoaderUtils; */ public class ComponentManager implements ComponentService { - /** - * These are AntLibraries which have been loaded into this component - * manager - */ - private static Map antLibraries = new HashMap(); /** * Type converters for this frame. Converters are used when configuring * Tasks to handle special type conversions. @@ -129,12 +123,6 @@ public class ComponentManager implements ComponentService { /** The definitions which have been imported into this frame. */ private Map imports = new HashMap(); - /** - * This map stores a list of additional paths for each library indexed by - * the libraryId - */ - private Map libPathsMap = new HashMap(); - /** Reflector objects used to configure Tasks from the Task models. */ private Map setters = new HashMap(); @@ -143,16 +131,17 @@ public class ComponentManager implements ComponentService { * Constructor * * @param frame the frame containing this context - * - * @exception ExecutionException if the loaded libraries could not be + * @param libManager the library manager with the library definitions + * which are shared across all component manager instances. + * @exception ExecutionException if the loaded libraries could not be * imported. */ - protected ComponentManager(Frame frame) throws ExecutionException { + protected ComponentManager(Frame frame, AntLibManager libManager) + throws ExecutionException { this.frame = frame; AntConfig config = frame.getConfig(); - libManager = new AntLibManager(config.isRemoteLibAllowed()); + this.libManager = libManager; dynamicLibraries = new HashMap(); - libPathsMap = new HashMap(); } /** @@ -162,32 +151,32 @@ public class ComponentManager implements ComponentService { * @param libLocation the file or URL of the library location * @param importAll if true all tasks are imported as the library is * loaded - * @param autoImport true if libraries in the Ant namespace should be - * automatically imported. - * @exception ExecutionException if the library cannot be loaded + * @exception AntException if the library cannot be loaded */ - public void loadLib(String libLocation, boolean importAll, - boolean autoImport) - throws ExecutionException { - try { - Map librarySpecs = new HashMap(); - libManager.loadLibs(librarySpecs, libLocation); - Map newLibraries = libManager.configLibraries(frame.getInitConfig(), - librarySpecs, antLibraries, libPathsMap); - - antLibraries.putAll(newLibraries); - Iterator i = antLibraries.keySet().iterator(); - while (i.hasNext()) { - String libraryId = (String) i.next(); - boolean doAuto = autoImport - && libraryId.startsWith(Constants.ANT_LIB_PREFIX); - if (importAll || doAuto) { - importLibrary(libraryId); - } + public void loadLib(URL libLocation, boolean importAll) + throws AntException { + Map newLibraries = libManager.loadLibs(libLocation); + Iterator i = newLibraries.keySet().iterator(); + while (i.hasNext()) { + String libraryId = (String) i.next(); + if (importAll) { + importLibrary(libraryId); + } + } + } + + /** + * Examine all the libraries defined in the Library manager and import + * those which are in the ant library namespace. + * + * @exception AntException if the standard components cannot be imported. + */ + protected void importStandardComponents() throws AntException { + for (Iterator i = libManager.getLibraryIds(); i.hasNext();) { + String libraryId = (String) i.next(); + if (libraryId.startsWith(Constants.ANT_LIB_PREFIX)) { + importLibrary(libraryId); } - } catch (MalformedURLException e) { - throw new ExecutionException("Unable to load libraries from " - + libLocation, e); } } @@ -229,32 +218,21 @@ public class ComponentManager implements ComponentService { * @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 + * @exception AntException 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); - } + throws AntException { + libManager.addLibPath(libraryId, 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 + * @exception AntException if the library cannot be imported */ - public void importLibrary(String libraryId) throws ExecutionException { - AntLibrary library = (AntLibrary) antLibraries.get(libraryId); + public void importLibrary(String libraryId) throws AntException { + AntLibrary library = libManager.getLibrary(libraryId); if (library == null) { throw new ExecutionException("Unable to import library " + libraryId + " as it has not been loaded"); @@ -277,11 +255,11 @@ public class ComponentManager implements ComponentService { * @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 + * @exception AntException if the component cannot be imported */ public void importComponent(String libraryId, String defName, - String alias) throws ExecutionException { - AntLibrary library = (AntLibrary) antLibraries.get(libraryId); + String alias) throws AntException { + AntLibrary library = libManager.getLibrary(libraryId); if (library == null) { throw new ExecutionException("Unable to import component from " + "library \"" + libraryId + "\" as it has not been loaded"); @@ -331,10 +309,10 @@ public class ComponentManager implements ComponentService { * @param componentName the name of the component * @return the created component. The return type of this method depends * on the component type. - * @exception ExecutionException if the component cannot be created + * @exception AntException if the component cannot be created */ public Object createComponent(String componentName) - throws ExecutionException { + throws AntException { return createComponent(componentName, (BuildElement) null); } @@ -347,12 +325,11 @@ public class ComponentManager implements ComponentService { * @param localName the name component within the library. * @return the created component. The return type of this method depends * on the component type. - * @exception ExecutionException if the component cannot be created + * @exception AntException if the component cannot be created */ public Object createComponent(String libraryId, String localName) - throws ExecutionException { - AntLibrary library - = (AntLibrary) antLibraries.get(libraryId); + throws AntException { + AntLibrary library = libManager.getLibrary(libraryId); if (library == null) { throw new ExecutionException("No library with libraryId \"" + libraryId + "\" is available"); @@ -377,6 +354,21 @@ public class ComponentManager implements ComponentService { return converters; } + /** + * Initialize a library. + * + * @param libraryId the library's identifier. + * + * @exception AntException if the library cannot be initalized. + */ + protected void initializeLibrary(String libraryId) + throws AntException { + AntLibrary library = libManager.getLibrary(libraryId); + if (library != null) { + getLibFactory(library); + } + } + /** * Get the collection of Ant Libraries defined for this frame Gets the * factory object for the given library @@ -384,10 +376,10 @@ public class ComponentManager implements ComponentService { * @param componentLibrary the compnent library for which a factory objetc * is required * @return the library's factory object - * @exception ExecutionException if the factory cannot be created + * @exception AntException if the factory cannot be created */ protected AntLibFactory getLibFactory(ComponentLibrary componentLibrary) - throws ExecutionException { + throws AntException { String libraryId = componentLibrary.getLibraryId(); if (libFactories.containsKey(libraryId)) { return (AntLibFactory) libFactories.get(libraryId); @@ -419,11 +411,11 @@ public class ComponentManager implements ComponentService { * @param model the build model representing the component and its * configuration * @return the configured component - * @exception ExecutionException if there is a problem creating or + * @exception AntException if there is a problem creating or * configuring the component */ protected Object createComponent(BuildElement model) - throws ExecutionException { + throws AntException { String componentName = model.getType(); return createComponent(componentName, model); } @@ -437,20 +429,20 @@ public class ComponentManager implements ComponentService { * @param model the build model of the component. If this is null, the * component is created but not configured. * @return the configured component - * @exception ExecutionException if there is a problem creating or + * @exception AntException if there is a problem creating or * configuring the component */ private Object createComponent(String componentName, BuildElement model) - throws ExecutionException { + throws AntException { Object component = null; - if (model != null) { + if (model != null) { for (Iterator i = aspects.iterator(); i.hasNext();) { Aspect aspect = (Aspect) i.next(); component = aspect.preCreateComponent(component, model); } } - + if (component == null) { ImportInfo importInfo = getImport(componentName); if (importInfo == null) { @@ -458,21 +450,21 @@ public class ComponentManager implements ComponentService { + componentName + "> component"); } String className = importInfo.getClassName(); - + ComponentLibrary componentLibrary = importInfo.getComponentLibrary(); - + component = createComponentFromDef(componentName, componentLibrary, importInfo.getDefinition(), model); } - + if (model != null) { for (Iterator i = aspects.iterator(); i.hasNext();) { Aspect aspect = (Aspect) i.next(); component = aspect.postCreateComponent(component, model); } } - + return component; } @@ -485,13 +477,13 @@ public class ComponentManager implements ComponentService { * @param libDefinition the component's definition * @param model the BuildElement model of the component's configuration. * @return the required component potentially wrapped in a wrapper object. - * @exception ExecutionException if the component cannot be created + * @exception AntException if the component cannot be created */ private Object createComponentFromDef(String componentName, ComponentLibrary componentLibrary, AntLibDefinition libDefinition, BuildElement model) - throws ExecutionException { + throws AntException { Location location = Location.UNKNOWN_LOCATION; if (model != null) { @@ -633,12 +625,12 @@ public class ComponentManager implements ComponentService { * @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 + * @exception AntException if there is a problem creating the type * instance */ private Object createTypeInstance(Class typeClass, AntLibFactory libFactory, BuildElement model, String localName) - throws ExecutionException { + throws AntException { try { Object typeInstance = libFactory.createComponent(typeClass, localName); @@ -646,7 +638,7 @@ public class ComponentManager implements ComponentService { if (typeInstance instanceof ExecutionComponent) { ExecutionComponent component = (ExecutionComponent) typeInstance; - ExecutionContext context + ExecutionContext context = new ExecutionContext(frame, component, model); component.init(context, localName); configureElement(libFactory, typeInstance, model); @@ -680,16 +672,16 @@ public class ComponentManager implements ComponentService { * @param model the model of the nested element * @param factory Ant Library factory associated with the element to which * the attribute is to be added. - * @exception ExecutionException if the nested element cannot be created + * @exception AntException if the nested element cannot be created */ private void addNestedElement(AntLibFactory factory, Setter setter, Object element, BuildElement model) - throws ExecutionException { + throws AntException { String nestedElementName = model.getType(); Class nestedType = setter.getType(nestedElementName); // is there a polymorph indicator - look in Ant aspects - String typeName + String typeName = model.getAspectAttributeValue(Constants.ANT_ASPECT, "type"); Object typeInstance = null; @@ -734,11 +726,11 @@ public class ComponentManager implements ComponentService { * @param model the build model for the nestd element * @param factory Ant Library factory associated with the element creating * the nested element - * @exception ExecutionException if the nested element cannot be created. + * @exception AntException if the nested element cannot be created. */ private void createNestedElement(AntLibFactory factory, Setter setter, Object element, BuildElement model) - throws ExecutionException { + throws AntException { String nestedElementName = model.getType(); try { Object nestedElement @@ -747,7 +739,7 @@ public class ComponentManager implements ComponentService { if (nestedElement instanceof ExecutionComponent) { ExecutionComponent component = (ExecutionComponent) nestedElement; - ExecutionContext context + ExecutionContext context = new ExecutionContext(frame, component, model); component.init(context, nestedElementName); configureElement(factory, nestedElement, model); @@ -770,12 +762,12 @@ public class ComponentManager implements ComponentService { * @param attributeValues a map containing named attribute values. * @param ignoreUnsupported if this is true, attribute names for which no * setter method exists are ignored. - * @exception ExecutionException if the object does not support an + * @exception AntException if the object does not support an * attribute in the map. */ public void configureAttributes(Object object, Map attributeValues, boolean ignoreUnsupported) - throws ExecutionException { + throws AntException { Setter setter = getSetter(object.getClass()); for (Iterator i = attributeValues.keySet().iterator(); i.hasNext();) { String attributeName = (String) i.next(); @@ -800,36 +792,13 @@ public class ComponentManager implements ComponentService { * @param model the BuildElement describing the object in the build file * @param factory Ant Library factory associated with the element being * configured - * @exception ExecutionException if the element cannot be configured + * @exception AntException if the element cannot be configured */ private void configureElement(AntLibFactory factory, Object element, BuildElement model) - throws ExecutionException { + throws AntException { 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 (!setter.supportsAttribute(attributeName)) { - throw new ExecutionException(model.getType() - + " does not support the \"" + attributeName - + "\" attribute", model.getLocation()); - } - setter.setAttribute(element, attributeName, - frame.replacePropertyRefs(attributeValue)); - } - - String modelText = model.getText().trim(); - if (modelText.length() != 0) { - if (!setter.supportsText()) { - throw new ExecutionException(model.getType() - + " does not support content", model.getLocation()); - } - setter.addText(element, - frame.replacePropertyRefs(modelText)); - } - - // now do the nested elements + // do the nested elements for (Iterator i = model.getNestedElements(); i.hasNext();) { BuildElement nestedElementModel = (BuildElement) i.next(); String nestedElementName = nestedElementModel.getType(); @@ -851,13 +820,37 @@ public class ComponentManager implements ComponentService { createNestedElement(factory, setter, element, nestedElementModel); } else { - throw new ExecutionException(model.getType() + throw new ExecutionException("<" + model.getType() + ">" + " does not support the \"" + nestedElementName + "\" nested element", nestedElementModel.getLocation()); } } } + + // Set the attributes of this element + for (Iterator i = model.getAttributeNames(); i.hasNext();) { + String attributeName = (String) i.next(); + String attributeValue = model.getAttributeValue(attributeName); + if (!setter.supportsAttribute(attributeName)) { + throw new ExecutionException("<" + model.getType() + ">" + + " does not support the \"" + attributeName + + "\" attribute", model.getLocation()); + } + setter.setAttribute(element, attributeName, + frame.replacePropertyRefs(attributeValue)); + } + + String modelText = model.getText(); + if (modelText.length() != 0) { + if (!setter.supportsText()) { + throw new ExecutionException("<" + model.getType() + ">" + + " does not support content", model.getLocation()); + } + setter.addText(element, + frame.replacePropertyRefs(modelText)); + } + } /** @@ -889,9 +882,9 @@ public class ComponentManager implements ComponentService { * * @param library the library from which the aspects are to be loaded. * - * @exception ExecutionException if an aspect cannot be loaded. + * @exception AntException if an aspect cannot be loaded. */ - private void addAspects(AntLibrary library) throws ExecutionException { + private void addAspects(AntLibrary library) throws AntException { if (!library.hasAspects() || loadedAspects.contains(library.getLibraryId())) { return; @@ -912,7 +905,7 @@ public class ComponentManager implements ComponentService { + " does not implement the Aspect interface"); } Aspect aspect = (Aspect) libFactory.createInstance(aspectClass); - ExecutionContext context + ExecutionContext context = new ExecutionContext(frame, null, null); aspect.init(context); aspects.add(aspect); @@ -946,11 +939,11 @@ public class ComponentManager implements ComponentService { * frame. * * @param library the library from which the converters are required - * @exception ExecutionException if a converter defined in the library + * @exception AntException if a converter defined in the library * cannot be instantiated */ private void addConverters(AntLibrary library) - throws ExecutionException { + throws AntException { if (!library.hasConverters() || loadedConverters.contains(library.getLibraryId())) { return; @@ -972,7 +965,7 @@ public class ComponentManager implements ComponentService { } Converter converter = (Converter) libFactory.createInstance(converterClass); - ExecutionContext context + ExecutionContext context = new ExecutionContext(frame, null, null); converter.init(context); Class[] converterTypes = converter.getTypes(); @@ -1004,7 +997,7 @@ public class ComponentManager implements ComponentService { } /** - * Get the aspects which have been registered from ant libraries. + * Get the aspects which have been registered from ant libraries. * * @return the list of Aspect instances currently defined. */ diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java index ec54346b3..1b6f8e699 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java @@ -57,8 +57,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.ant.common.service.DataService; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.PropertyUtils; +import org.apache.ant.common.util.AntException; /** * This is the core's implementation of the DataService service interface. @@ -156,10 +156,10 @@ public class CoreDataService implements DataService { * * @param value the string to be scanned for property references. * @return the string with all property references replaced - * @exception ExecutionException if any of the properties do not exist + * @exception AntException if any of the properties do not exist */ public String replacePropertyRefs(String value) - throws ExecutionException { + throws AntException { if (value == null) { return null; } @@ -199,10 +199,10 @@ public class CoreDataService implements DataService { * @param value the string to be scanned for property references. * @param replacementValues the collection of replacement values * @return the string with all property references replaced - * @exception ExecutionException if any of the properties do not exist + * @exception AntException if any of the properties do not exist */ public String replacePropertyRefs(String value, Map replacementValues) - throws ExecutionException { + throws AntException { if (value == null) { return null; } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreEventService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreEventService.java index ca9d1c87e..9ac09fb93 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreEventService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreEventService.java @@ -54,7 +54,6 @@ package org.apache.ant.antcore.execution; import org.apache.ant.common.event.BuildListener; import org.apache.ant.common.service.EventService; -import org.apache.ant.common.util.ExecutionException; /** * Core implementation of the event service diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java index 2f17c4521..bb9a0c5c8 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java @@ -64,9 +64,11 @@ import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.model.Project; import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.service.ExecService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.service.BuildKey; import org.apache.ant.init.InitUtils; import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.event.BuildListener; +import org.apache.ant.common.util.AntException; /** * This is the core's implementation of the Execution Service. @@ -98,9 +100,9 @@ public class CoreExecService implements ExecService { * core. This is checked * * @param task the task to be executed - * @exception ExecutionException if there is an execution problem + * @exception AntException if there is an execution problem */ - public void executeTask(Task task) throws ExecutionException { + public void executeTask(Task task) throws AntException { ExecutionContext execContext = getTaskExecutionContext(task); BuildElement model = execContext.getModel(); @@ -110,7 +112,7 @@ public class CoreExecService implements ExecService { } frame.executeTask(task, aspectValues); } - + /** * Retrieve the execution context from a task and verify that the context * is valid. @@ -120,7 +122,7 @@ public class CoreExecService implements ExecService { * * @exception ExecutionException if the task's context is not valid. */ - private ExecutionContext getTaskExecutionContext(Task task) + private ExecutionContext getTaskExecutionContext(Task task) throws ExecutionException { AntContext context = task.getAntContext(); @@ -130,25 +132,25 @@ public class CoreExecService implements ExecService { } return (ExecutionContext) context; } - + /** - * Execute a task with a set of aspect values. Normally aspect values come + * Execute a task with a set of aspect values. Normally aspect values come * from a build model but not all tasks will be created from a build model. - * Some may be created dynamically and configured programatically. This + * Some may be created dynamically and configured programatically. This * method allows aspect values to provided for execution of such tasks since * by their nature, aspect values are not part of the task configuration. * * @param task the task to be executed * @param aspectValues the aspect attribute values. - * @exception ExecutionException if there is an execution problem + * @exception AntException if there is an execution problem */ - public void executeTask(Task task, AspectValueCollection aspectValues) - throws ExecutionException { + public void executeTask(Task task, AspectValueCollection aspectValues) + throws AntException { ExecutionContext execContext = getTaskExecutionContext(task); frame.executeTask(task, aspectValues); } - + /** @@ -160,6 +162,17 @@ public class CoreExecService implements ExecService { return frame.getBaseDir(); } + /** + * Set the basedir for the current execution + * + * @param baseDir the new base directory for this execution of Ant + * + * @exception AntException if the baseDir cannot be set to the given value. + */ + public void setBaseDir(File baseDir) throws AntException { + frame.setBaseDir(baseDir); + } + /** * get the name of the project associated with this execution. @@ -203,15 +216,54 @@ public class CoreExecService implements ExecService { } + /** + * Force initialisation of a particular ant library in the context of the + * given subbuild. + * + * @param key the build key. + * @param libraryId the id of the library to be initialized. + * @exception AntException if the build cannot be run + */ + public void initializeBuildLibrary(BuildKey key, String libraryId) + throws AntException { + Frame subFrame = getSubbuildFrame(key); + subFrame.initializeLibrary(libraryId); + } + + /** + * Add a listener to a subbuild + * + * @param key the key identifying the build previously setup + * @param listener the listener to add to the build. + * + * @exception ExecutionException if the build cannot be found. + */ + public void addBuildListener(BuildKey key, BuildListener listener) + throws ExecutionException { + getSubbuildFrame(key).addBuildListener(listener); + } + + /** * Run a build which have been previously setup * * @param targets A list of targets to be run * @param key Description of the Parameter - * @exception ExecutionException if the build cannot be run + * @exception AntException if the build cannot be run */ - public void runBuild(Object key, List targets) throws ExecutionException { + public void runBuild(BuildKey key, List targets) throws AntException { getSubbuildFrame(key).runBuild(targets); + } + + + /** + * Release a subbuild that is no longer in use. + * + * @param key the BuildKey identifiying the subbuild. + * + * @exception ExecutionException if the build was not registered. + */ + public void releaseBuild(BuildKey key) throws ExecutionException { subBuilds.remove(key); } @@ -245,12 +297,12 @@ public class CoreExecService implements ExecService { * referenced. * @param model the project model. * @param initialData the project's initial data load. - * @exception ExecutionException if the project cannot be referenced. + * @exception AntException if the project cannot be referenced. */ - public void createProjectReference(String referenceName, Project model, + public void createProjectReference(String referenceName, Project model, Map initialData) - throws ExecutionException { - frame.createProjectReference(referenceName, model, initialData); + throws AntException { + frame.createProjectReference(referenceName, model, initialData); } @@ -259,16 +311,22 @@ public class CoreExecService implements ExecService { * * @param model the project model to be used for the build * @param properties the initiali properties to be used in the build + * @param addListeners true if the current frame's listeners should be + * added to the created Frame * @return Description of the Return Value - * @exception ExecutionException if the subbuild cannot be run + * @exception AntException if the subbuild cannot be run */ - public Object setupBuild(Project model, Map properties) - throws ExecutionException { + public BuildKey setupBuild(Project model, Map properties, + boolean addListeners) + throws AntException { Frame newFrame = frame.createFrame(model); + if (addListeners) { + frame.addListeners(newFrame); + } + newFrame.initialize(properties); - newFrame.setInitialProperties(properties); - - Object key = new Object(); + // create an anonymous inner class key. + BuildKey key = new BuildKey() {}; subBuilds.put(key, newFrame); return key; @@ -279,12 +337,14 @@ public class CoreExecService implements ExecService { * Setup a sub-build using the current frame's project model * * @param properties the initiali properties to be used in the build + * @param addListeners true if the current frame's listeners should be + * added to the created Frame * @return Description of the Return Value - * @exception ExecutionException if the subbuild cannot be run + * @exception AntException if the subbuild cannot be run */ - public Object setupBuild(Map properties) - throws ExecutionException { - return setupBuild(frame.getProject(), properties); + public BuildKey setupBuild(Map properties, boolean addListeners) + throws AntException { + return setupBuild(frame.getProject(), properties, addListeners); } } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreFileService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreFileService.java index d860b4aaf..4d1ddc401 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreFileService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreFileService.java @@ -54,8 +54,8 @@ package org.apache.ant.antcore.execution; import java.io.File; import org.apache.ant.common.service.FileService; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.FileUtils; +import org.apache.ant.common.util.AntException; /** * The core's implementation of the File Service. The File Service is used @@ -86,9 +86,9 @@ public class CoreFileService implements FileService { * * @param fileName the file name to be resolved. * @return the file resolved to the project's base dir - * @exception ExecutionException if the file cannot be resolved. + * @exception AntException if the file cannot be resolved. */ - public File resolveFile(String fileName) throws ExecutionException { + public File resolveFile(String fileName) throws AntException { File base = frame.getBaseDir(); return fileUtils.resolveFile(fileUtils.normalize(base.getPath()), fileName); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreInputService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreInputService.java index 690dee1c0..d88cda06d 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreInputService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreInputService.java @@ -53,7 +53,6 @@ */ package org.apache.ant.antcore.execution; import org.apache.ant.common.service.InputService; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.input.InputRequest; /** 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 index 0f7dbcbed..7e070a173 100644 --- 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 @@ -53,7 +53,6 @@ */ 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 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 c91539c7f..80b5213f2 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 @@ -54,7 +54,6 @@ package org.apache.ant.antcore.execution; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.ExecutionComponent; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.Location; import org.apache.ant.common.model.BuildElement; @@ -90,7 +89,7 @@ public class ExecutionContext implements AntContext { * * @param frame the frame containing this context * @param component the component associated with this context - may be null - * @param model the build model associated with this component if any. + * @param model the build model associated with this component if any. */ protected ExecutionContext(Frame frame, ExecutionComponent component, BuildElement model) { @@ -170,7 +169,7 @@ public class ExecutionContext implements AntContext { protected ExecutionComponent getExecutionComponent() { return component; } - + /** * Get the build model associated with this context. * 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 deleted file mode 100755 index d5112be95..000000000 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java +++ /dev/null @@ -1,201 +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.antcore.execution; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import org.apache.ant.antcore.config.AntConfig; -import org.apache.ant.common.event.BuildListener; -import org.apache.ant.common.model.Project; -import org.apache.ant.common.util.AntException; -import org.apache.ant.common.util.ExecutionException; -import org.apache.ant.common.util.DemuxOutputReceiver; -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. - * - * @author Conor MacNeill - * @created 12 January 2002 - */ -public class ExecutionManager implements DemuxOutputReceiver { - /** BuildEvent support used to fire events and manage listeners */ - private BuildEventSupport eventSupport = new BuildEventSupport(); - - /** The Execution Frame for the top level project being executed */ - private Frame mainFrame; - - /** - * The configuration to be used in this execution of Ant. It is formed - * from the system, user and any runtime configs. - */ - private AntConfig config; - - /** - * Ant's initialization configuration with information on the location - * of Ant and its libraries. - */ - private InitConfig initConfig; - - /** - * Create an ExecutionManager. When an ExecutionManager is created, it - * loads the ant libraries which are installed in the Ant lib/task - * directory. - * - * @param initConfig Ant's configuration - classloaders etc - * @param config The user config to use - may be null - * @exception ExecutionException if there is a problem with one of Ant's - * tasks - */ - public ExecutionManager(InitConfig initConfig, AntConfig config) - throws ExecutionException { - this.config = config; - this.initConfig = initConfig; - init(); - } - - /** - * Initialise the execution manager - * - * @exception ExecutionException if the standard ant libraries cannot be - * loaded - */ - public void init() throws ExecutionException { - } - - /** - * Run a build, executing each of the targets on the given project - * - * @param project the project model to be used for the build - * @param targets a list of target names to be executed. - * @param commandProperties the properties defined by the front end to - * control the build - * @exception AntException if there is a problem in the build - */ - public void runBuild(Project project, List targets, Map commandProperties) - throws AntException { - Throwable buildFailureCause = null; - try { - - // start by validating the project we have been given. - project.validate(); - - mainFrame = new Frame(initConfig, config); - for (Iterator j = eventSupport.getListeners(); j.hasNext();) { - BuildListener listener = (BuildListener) j.next(); - mainFrame.addBuildListener(listener); - } - - mainFrame.setProject(project); - mainFrame.setInitialProperties(commandProperties); - - eventSupport.fireBuildStarted(project); - mainFrame.runBuild(targets); - } catch (RuntimeException e) { - buildFailureCause = e; - throw e; - } catch (ExecutionException e) { - ExecutionException ee = e instanceof ExecutionException - ? e : new ExecutionException(e); - buildFailureCause = e; - throw ee; - } finally { - eventSupport.fireBuildFinished(project, buildFailureCause); - } - } - - /** - * Add a build listener to the build - * - * @param listener the listener to be added to the build - */ - public void addBuildListener(BuildListener listener) { - eventSupport.addBuildListener(listener); - if (mainFrame != null) { - mainFrame.addBuildListener(listener); - } - } - - /** - * Remove a build listener from the execution - * - * @param listener the listener to be removed - */ - public void removeBuildListener(BuildListener listener) { - eventSupport.removeBuildListener(listener); - if (mainFrame != null) { - mainFrame.removeBuildListener(listener); - } - } - - /** - * Handle the content from a single thread. This method will be called - * by the thread producing the content. The content is broken up into - * separate lines - * - * @param line the content produce by the current thread. - * @param isErr true if this content is from the thread's error stream. - */ - public void threadOutput(String line, boolean isErr) { - if (mainFrame == null) { - eventSupport.threadOutput(line, isErr); - } else { - mainFrame.threadOutput(line, isErr); - } - } -} - 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 6c9a3802c..27d25c962 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,11 +63,13 @@ import java.util.List; import java.util.ArrayList; import java.util.Set; import org.apache.ant.antcore.config.AntConfig; +import org.apache.ant.antcore.antlib.AntLibManager; import org.apache.ant.common.antlib.Task; import org.apache.ant.common.antlib.Aspect; 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.ModelException; import org.apache.ant.common.model.Project; import org.apache.ant.common.model.Target; import org.apache.ant.common.model.AspectValueCollection; @@ -79,8 +81,9 @@ import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.InputService; import org.apache.ant.common.service.MagicProperties; import org.apache.ant.common.util.DemuxOutputReceiver; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.FileUtils; +import org.apache.ant.common.util.Location; +import org.apache.ant.common.util.AntException; import org.apache.ant.init.InitConfig; import org.apache.ant.init.LoaderUtils; @@ -102,20 +105,20 @@ public class Frame implements DemuxOutputReceiver { /** The referenced frames corresponding to the referenced projects */ private Map referencedFrames = new HashMap(); - /** + /** * This is a Map of Maps. This map is keyed on an executing task. * Each entry is itself a Map of Aspects to their context for the * particular task. */ private Map aspectContextsMap = new HashMap(); - - /** - * The property overrides for the referenced frames. This map is indexed - * by the reference names of the frame. Each entry is another Map of + + /** + * The property overrides for the referenced frames. This map is indexed + * by the reference names of the frame. Each entry is another Map of * property values indexed by their relative name. */ private Map overrides = new HashMap(); - + /** * The context of this execution. This contains all data object's created * by tasks that have been executed @@ -146,10 +149,10 @@ public class Frame implements DemuxOutputReceiver { /** * The Data Service instance used by the frame for data management */ - private DataService dataService; + private CoreDataService dataService; /** The execution file service instance */ - private FileService fileService; + private CoreFileService fileService; /** * the Component Manager used to manage the importing of library @@ -160,19 +163,41 @@ public class Frame implements DemuxOutputReceiver { /** The core's execution Service */ private CoreExecService execService; + /** The parent frame of this frame - may be null. */ + private Frame parent = null; + + /** The currently executing target in this frame */ + private String currentTarget = null; + + /** The global library manager */ + private AntLibManager libManager; + + /** + * Create the main or root Execution Frame. + * + * @param config the user config to use for this execution of Ant + * @param initConfig Ant's initialisation config + */ + public Frame(InitConfig initConfig, AntConfig config) { + this.config = config; + this.initConfig = initConfig; + this.parent = null; + this.libManager + = new AntLibManager(initConfig, config.isRemoteLibAllowed()); + } /** - * Create an Execution Frame for the given project + * Create an Execution Frame. * * @param config the user config to use for this execution of Ant * @param initConfig Ant's initialisation config - * @exception ExecutionException if a component of the library cannot be - * imported + * @param parent the frame creating this frame. */ - protected Frame(InitConfig initConfig, - AntConfig config) throws ExecutionException { + private Frame(InitConfig initConfig, AntConfig config, Frame parent) { this.config = config; this.initConfig = initConfig; + this.parent = parent; + this.libManager = parent.libManager; } @@ -182,10 +207,10 @@ public class Frame implements DemuxOutputReceiver { * * @param value the string to be scanned for property references. * @return the string with all property references replaced - * @exception ExecutionException if any of the properties do not exist + * @exception AntException if any of the properties do not exist */ - protected String replacePropertyRefs(String value) - throws ExecutionException { + protected String replacePropertyRefs(String value) + throws AntException { return dataService.replacePropertyRefs(value); } @@ -194,12 +219,12 @@ public class Frame implements DemuxOutputReceiver { * Sets the Project of the Frame * * @param project The new Project value - * @exception ExecutionException if any required sub-frames cannot be - * created and configured + * @exception ModelException if the project is not valid. */ - protected void setProject(Project project) throws ExecutionException { + public void setProject(Project project) throws ModelException { this.project = project; referencedFrames.clear(); + project.validate(); } @@ -235,7 +260,7 @@ public class Frame implements DemuxOutputReceiver { if (frame == this) { if (dataValues.containsKey(name) && !mutable) { - log("Ignoring oveeride for data value " + name, + log("Ignoring override for data value " + name, MessageLevel.MSG_VERBOSE); } else { dataValues.put(name, value); @@ -252,22 +277,22 @@ public class Frame implements DemuxOutputReceiver { * @param name the name of the value * @param value the actual value * @param mutable if true, existing values can be changed - * @exception ExecutionException if attempting to override a property in - * the current frame. + * @exception ExecutionException if attempting to override a property in + * the current frame. */ - private void setOverrideProperty(String name, Object value, - boolean mutable) + private void setOverrideProperty(String name, Object value, + boolean mutable) throws ExecutionException { int refIndex = name.indexOf(Project.REF_DELIMITER); if (refIndex == -1) { - throw new ExecutionException("Property overrides can only be set" - + " for properties in referenced projects - not " + throw new ExecutionException("Property overrides can only be set" + + " for properties in referenced projects - not " + name); } - + String firstFrameName = name.substring(0, refIndex); - - String relativeName + + String relativeName = name.substring(refIndex + Project.REF_DELIMITER.length()); Map frameOverrides = (Map) overrides.get(firstFrameName); @@ -278,30 +303,30 @@ public class Frame implements DemuxOutputReceiver { if (mutable || !frameOverrides.containsKey(relativeName)) { frameOverrides.put(relativeName, value); - } + } } - + /** - * Get a value which exists in the frame property overrides awaiting + * Get a value which exists in the frame property overrides awaiting * the frame to be introduced. * * @param name the name of the value - * @return the value of the property or null if the property does not + * @return the value of the property or null if the property does not * exist. - * @exception ExecutionException if attempting to get an override in - * the current frame. + * @exception ExecutionException if attempting to get an override in + * the current frame. */ private Object getOverrideProperty(String name) throws ExecutionException { int refIndex = name.indexOf(Project.REF_DELIMITER); if (refIndex == -1) { - throw new ExecutionException("Property overrides can only be" - + " returned for properties in referenced projects - not " + throw new ExecutionException("Property overrides can only be" + + " returned for properties in referenced projects - not " + name); } - + String firstFrameName = name.substring(0, refIndex); - - String relativeName + + String relativeName = name.substring(refIndex + Project.REF_DELIMITER.length()); Map frameOverrides = (Map) overrides.get(firstFrameName); @@ -311,28 +336,28 @@ public class Frame implements DemuxOutputReceiver { return frameOverrides.get(relativeName); } - + /** - * Get a value which exists in the frame property overrides awaiting + * Get a value which exists in the frame property overrides awaiting * the frame to be introduced. * * @param name the name of the value - * @return the value of the property or null if the property does not + * @return the value of the property or null if the property does not * exist. - * @exception ExecutionException if attempting to check an override in - * the current frame. + * @exception ExecutionException if attempting to check an override in + * the current frame. */ private boolean isOverrideSet(String name) throws ExecutionException { int refIndex = name.indexOf(Project.REF_DELIMITER); if (refIndex == -1) { - throw new ExecutionException("Property overrides can only be" - + " returned for properties in referenced projects - not " + throw new ExecutionException("Property overrides can only be" + + " returned for properties in referenced projects - not " + name); } - + String firstFrameName = name.substring(0, refIndex); - - String relativeName + + String relativeName = name.substring(refIndex + Project.REF_DELIMITER.length()); Map frameOverrides = (Map) overrides.get(firstFrameName); @@ -342,32 +367,35 @@ public class Frame implements DemuxOutputReceiver { return frameOverrides.containsKey(relativeName); } - + /** - * Set the initial properties to be used when the frame starts execution + * Initialize the frame setting any initial properties. * * @param properties a Map of named properties which may in fact be any * object - * @exception ExecutionException if the properties cannot be set + * @exception AntException if the properties cannot be set */ - protected void setInitialProperties(Map properties) - throws ExecutionException { + public void initialize(Map properties) + throws AntException { + configureServices(); if (properties != null) { addProperties(properties); } // add in system properties addProperties(System.getProperties()); + setMagicProperties(); } /** * Set the values of various magic properties * - * @exception ExecutionException if the properties cannot be set + * @exception AntException if the properties cannot be set */ - protected void setMagicProperties() throws ExecutionException { + protected void setMagicProperties() throws AntException { + // ant.home URL antHomeURL = initConfig.getAntHome(); String antHomeString = null; @@ -378,7 +406,25 @@ public class Frame implements DemuxOutputReceiver { } else { antHomeString = antHomeURL.toString(); } - setDataValue(MagicProperties.ANT_HOME, antHomeString, true); + setDataValue(MagicProperties.ANT_HOME, antHomeString, false); + + // ant.file + URL projectSource = project.getSourceURL(); + if (projectSource != null + && projectSource.getProtocol().equals("file")) { + setDataValue(MagicProperties.ANT_FILE, projectSource.getFile(), + true); + } + + // basedir + determineBaseDir(); + + // ant.project.name + String projectName = project.getName(); + if (projectName != null) { + setDataValue(MagicProperties.ANT_PROJECT_NAME, projectName, true); + } + } @@ -650,26 +696,24 @@ public class Frame implements DemuxOutputReceiver { * referenced. * @param project the project model. * @param initialData the project's initial data load. - * @exception ExecutionException if the project cannot be referenced. + * @exception AntException if the project cannot be referenced. */ protected void createProjectReference(String name, Project project, - Map initialData) - throws ExecutionException { + Map initialData) + throws AntException { Frame referencedFrame = createFrame(project); + addListeners(referencedFrame); + + referencedFrame.initialize(initialData); - if (initialData != null) { - referencedFrame.setInitialProperties(initialData); - } - // does the frame have any overrides? Map initialProperties = (Map) overrides.get(name); - if (initialProperties != null) { - referencedFrame.setInitialProperties(initialProperties); - overrides.remove(name); - } - + referencedFrame.initialize(initialProperties); + overrides.remove(name); + referencedFrames.put(name, referencedFrame); - referencedFrame.initialize(); + referencedFrame.importStandardComponents(); + referencedFrame.runGlobalTasks(); } /** @@ -677,21 +721,30 @@ public class Frame implements DemuxOutputReceiver { * * @param project the project model the frame will deal with * @return an Frame ready to build the project - * @exception ExecutionException if the frame cannot be created. + * @exception ModelException if the given project is not valid. */ protected Frame createFrame(Project project) - throws ExecutionException { + throws ModelException { Frame newFrame - = new Frame(initConfig, config); + = new Frame(initConfig, config, this); newFrame.setProject(project); + + return newFrame; + } + + /** + * Add all build listeners from this frame to the given sub frame. + * + * @param subFrame the subFrame to which all the listeners of this frame + * will be added. + */ + protected void addListeners(Frame subFrame) { for (Iterator j = eventSupport.getListeners(); j.hasNext();) { BuildListener listener = (BuildListener) j.next(); - newFrame.addBuildListener(listener); + subFrame.addBuildListener(listener); } - - return newFrame; } @@ -711,7 +764,7 @@ public class Frame implements DemuxOutputReceiver { * * @param listener the listener to be added to the frame */ - protected void addBuildListener(BuildListener listener) { + public void addBuildListener(BuildListener listener) { for (Iterator i = getReferencedFrames(); i.hasNext();) { Frame referencedFrame = (Frame) i.next(); @@ -735,15 +788,26 @@ public class Frame implements DemuxOutputReceiver { eventSupport.removeBuildListener(listener); } + /** + * Import any standard components from the libraries which have been loaded. + * A standard component is a component provided by a library in the ant + * namespace. + * + * @exception AntException if the standard components cannot be imported. + */ + private void importStandardComponents() throws AntException { + componentManager.importStandardComponents(); + } /** * Run the given list of targets * * @param targets a list of target names which are to be evaluated - * @exception ExecutionException if there is a problem in the build + * @exception AntException if there is a problem in the build */ - protected void runBuild(List targets) throws ExecutionException { - initialize(); + protected void runBuild(List targets) throws AntException { + importStandardComponents(); + runGlobalTasks(); if (targets.isEmpty()) { // we just execute the default target if any String defaultTarget = project.getDefaultTarget(); @@ -787,10 +851,12 @@ public class Frame implements DemuxOutputReceiver { * @param flattenedList the List of targets that must be executed before * the given target * @param fullTargetName the fully qualified name of the target + * @param targetRefLocation the location requesting this dependency. * @exception ExecutionException if the given target does not exist in the * project hierarchy */ - private void flattenDependency(List flattenedList, String fullTargetName) + private void flattenDependency(List flattenedList, String fullTargetName, + Location targetRefLocation) throws ExecutionException { if (flattenedList.contains(fullTargetName)) { return; @@ -800,17 +866,18 @@ public class Frame implements DemuxOutputReceiver { String localTargetName = getNameInFrame(fullTargetName); Target target = frame.getProject().getTarget(localTargetName); if (target == null) { - throw new ExecutionException("Target " + fullTargetName - + " does not exist"); + throw new ExecutionException("Target \"" + fullTargetName + + "\" does not exist", targetRefLocation); } for (Iterator i = target.getDependencies(); i.hasNext();) { String localDependencyName = (String) i.next(); String fullDependencyName = localDependencyName; if (fullProjectName != null) { - fullDependencyName = fullProjectName + Project.REF_DELIMITER + fullDependencyName = fullProjectName + Project.REF_DELIMITER + localDependencyName; } - flattenDependency(flattenedList, fullDependencyName); + flattenDependency(flattenedList, fullDependencyName, + target.getLocation()); if (!flattenedList.contains(fullDependencyName)) { flattenedList.add(fullDependencyName); } @@ -829,7 +896,7 @@ public class Frame implements DemuxOutputReceiver { protected List getTargetDependencies(String fullTargetName) throws ExecutionException { List flattenedList = new ArrayList(); - flattenDependency(flattenedList, fullTargetName); + flattenDependency(flattenedList, fullTargetName, null); flattenedList.add(fullTargetName); return flattenedList; } @@ -839,10 +906,10 @@ public class Frame implements DemuxOutputReceiver { * Execute the tasks of a target in this frame with the given name * * @param targetName the name of the target whose tasks will be evaluated - * @exception ExecutionException if there is a problem executing the tasks + * @exception AntException if there is a problem executing the tasks * of the target */ - protected void executeTarget(String targetName) throws ExecutionException { + protected void executeTarget(String targetName) throws AntException { // to execute a target we must determine its dependencies and // execute them in order. @@ -864,10 +931,10 @@ public class Frame implements DemuxOutputReceiver { * * @param task the task to be executed. * @param aspectValues the collection of aspect attribute values. - * @exception ExecutionException if the task has a problem. + * @exception AntException if the task has a problem. */ - protected void executeTask(Task task, AspectValueCollection aspectValues) - throws ExecutionException { + protected void executeTask(Task task, AspectValueCollection aspectValues) + throws AntException { List aspects = componentManager.getAspects(); Map aspectContexts = new HashMap(); @@ -881,7 +948,7 @@ public class Frame implements DemuxOutputReceiver { if (aspectContexts.size() != 0) { aspectContextsMap.put(task, aspectContexts); } - + eventSupport.fireTaskStarted(task); Throwable failureCause = null; @@ -903,14 +970,14 @@ public class Frame implements DemuxOutputReceiver { for (Iterator i = activeAspects.iterator(); i.hasNext();) { Aspect aspect = (Aspect) i.next(); Object aspectContext = aspectContexts.get(aspect); - failureCause + failureCause = aspect.postExecuteTask(aspectContext, failureCause); } eventSupport.fireTaskFinished(task, failureCause); if (aspectContexts.size() != 0) { aspectContextsMap.remove(task); } - + if (failureCause != null) { if (failureCause instanceof ExecutionException) { throw (ExecutionException) failureCause; @@ -918,18 +985,22 @@ public class Frame implements DemuxOutputReceiver { throw new ExecutionException(failureCause); } } - + /** * Run the tasks returned by the given iterator * * @param taskIterator the iterator giving the tasks to execute - * @exception ExecutionException if there is execution problem while + * @exception AntException if there is execution problem while * executing tasks */ protected void executeTasks(Iterator taskIterator) - throws ExecutionException { - + throws AntException { + + if (taskIterator == null) { + return; + } + while (taskIterator.hasNext()) { BuildElement model = (BuildElement) taskIterator.next(); @@ -938,7 +1009,7 @@ public class Frame implements DemuxOutputReceiver { Object component = componentManager.createComponent(model); if (component instanceof Task) { execService.executeTask((Task) component); - } + } } catch (ExecutionException e) { e.setLocation(model.getLocation(), false); throw e; @@ -952,6 +1023,63 @@ public class Frame implements DemuxOutputReceiver { } + /** + * Get the parent frame of this frame. + * + * @return the parent frame - may be null if this frame has no parent. + */ + private Frame getParent() { + return parent; + } + + /** + * Get the currently executing target of this frame + * + * @return the name of the current target. + */ + private String getCurrentTarget() { + return currentTarget; + } + + /** + * Check for recursion - executing the same target in the same buildfile + * with the same base directory + * + * @param targetName the target to check + * + * @exception ExecutionException if the target is already being evaluated + * in a parent frame. + */ + private void checkRecursion(String targetName) throws ExecutionException { + Frame checkFrame = getParent(); + while (checkFrame != null) { + File checkDir = checkFrame.getBaseDir(); + String checkTarget = checkFrame.getCurrentTarget(); + URL checkURL = checkFrame.getProject().getSourceURL(); + if (targetName.equals(checkTarget) + && checkDir.equals(getBaseDir()) + && checkURL != null + && checkURL.equals(getProject().getSourceURL())) { + throw new ExecutionException("Recursive execution of " + + "target \"" + targetName + "\" in " + + "project \"" + checkURL + "\""); + } + checkFrame = checkFrame.getParent(); + } + } + + /** + * Initialize a library in this frame. + * + * @param libraryId the library's global identifier. + * + * @exception AntException if the library cannot be initialized. + */ + protected void initializeLibrary(String libraryId) + throws AntException { + componentManager.initializeLibrary(libraryId); + } + /** * Execute the given target's tasks. The target must be local to this @@ -959,10 +1087,13 @@ public class Frame implements DemuxOutputReceiver { * * @param targetName the name of the target within this frame that is to * be executed. - * @exception ExecutionException if there is a problem executing tasks + * @exception AntException if there is a problem executing tasks */ protected void executeTargetTasks(String targetName) - throws ExecutionException { + throws AntException { + checkRecursion(targetName); + currentTarget = targetName; + Throwable failureCause = null; Target target = project.getTarget(targetName); String ifCondition = target.getIfCondition(); @@ -1000,51 +1131,104 @@ public class Frame implements DemuxOutputReceiver { throw ee; } finally { eventSupport.fireTargetFinished(target, failureCause); + currentTarget = null; } - } + } /** - * Initialize the frame by executing the project level tasks if any + * Start the build. This is only called on the + * main frame of the build. All subordinate frames use runBuild to + * process sub builds. * - * @exception ExecutionException if the top level tasks of the frame - * failed + * This method performs all global config tasks and then starts the + * build + * + * @param targets the targets to be evaluated in this build + * + * @exception AntException if there is a problem running the build. */ - protected void initialize() throws ExecutionException { - configureServices(); - setMagicProperties(); - determineBaseDir(); + public void startBuild(List targets) throws AntException { + eventSupport.fireBuildStarted(project); - try { + Throwable buildFailureCause = null; + try { // load system ant lib - URL systemLibs + URL systemLibs = new URL(initConfig.getLibraryURL(), "syslibs/"); - componentManager.loadLib(systemLibs.toString(), true, true); - - // execute any config tasks - executeTasks(config.getTasks()); - + componentManager.loadLib(systemLibs, true); + + executeTasks(config.getGlobalTasks()); + // now load other system libraries URL antLibs = new URL(initConfig.getLibraryURL(), "antlibs/"); - componentManager.loadLib(antLibs.toString(), false, true); - - executeTasks(project.getTasks()); + componentManager.loadLib(antLibs, false); + } catch (MalformedURLException e) { throw new ExecutionException("Unable to initialize antlibs", e); } + + try { + runBuild(targets); + } catch (RuntimeException e) { + buildFailureCause = e; + throw e; + } catch (AntException e) { + buildFailureCause = e; + throw e; + } finally { + eventSupport.fireBuildFinished(project, buildFailureCause); + } + } + + /** + * Execute any config and project level tasks + * + * @exception AntException if the top level tasks of the frame + * failed + */ + private void runGlobalTasks() throws AntException { + executeTasks(config.getFrameTasks()); + executeTasks(project.getTasks()); + } + + /** + * Set the base director for this frame's execution. + * + * @param baseDir the new base directory + * + * @exception AntException if the base directory cannot be set. + */ + protected void setBaseDir(File baseDir) throws AntException { + FileUtils fileUtils = FileUtils.newFileUtils(); + + baseDir = fileUtils.normalize(baseDir.getAbsolutePath()); + if (!baseDir.exists()) { + throw new ExecutionException("Basedir " + baseDir.getAbsolutePath() + + " does not exist"); + } + if (!baseDir.isDirectory()) { + throw new ExecutionException("Basedir " + baseDir.getAbsolutePath() + + " is not a directory"); + } + this.baseDir = baseDir; + setDataValue(MagicProperties.BASEDIR, baseDir.getPath(), false); + log("Project base dir set to: " + this.baseDir, + MessageLevel.MSG_VERBOSE); } /** - * Determine the base directory for each frame in the frame hierarchy + * Determine the base directory. * - * @exception ExecutionException if the base directories cannot be + * @exception AntException if the base directories cannot be * determined */ - private void determineBaseDir() throws ExecutionException { + private void determineBaseDir() throws AntException { if (isDataValueSet(MagicProperties.BASEDIR)) { - baseDir - = new File(getDataValue(MagicProperties.BASEDIR).toString()); + String baseDirString + = getDataValue(MagicProperties.BASEDIR).toString(); + setBaseDir(new File(baseDirString)); } else { URL projectURL = project.getSourceURL(); @@ -1054,17 +1238,16 @@ public class Frame implements DemuxOutputReceiver { String base = project.getBase(); if (base == null) { - baseDir = projectFileParent; + setBaseDir(projectFileParent); } else { FileUtils fileUtils = FileUtils.newFileUtils(); - baseDir = fileUtils.resolveFile(projectFileParent, base); + setBaseDir(fileUtils.resolveFile(projectFileParent, base)); } } else { - baseDir = new File("."); + setBaseDir(new File(".")); } } - setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(), true); } @@ -1072,13 +1255,13 @@ public class Frame implements DemuxOutputReceiver { * Configure the services that the frame makes available to its library * components * - * @exception ExecutionException if the services required by the core + * @exception ExecutionException if the services required by the core * could not be configured. */ private void configureServices() throws ExecutionException { // create services and make them available in our services map fileService = new CoreFileService(this); - componentManager = new ComponentManager(this); + componentManager = new ComponentManager(this, libManager); dataService = new CoreDataService(this, config.isUnsetPropertiesAllowed()); execService = new CoreExecService(this); 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 06c030deb..583ab9edd 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 @@ -59,7 +59,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.ant.common.antlib.Converter; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * A reflector is used to set attributes and add nested elements to an @@ -145,12 +145,12 @@ public class Reflector implements Setter { * @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 + * @exception AntException 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 { + throws AntException { String name = attributeName.toLowerCase(); AttributeSetter as = (AttributeSetter) attributeSetters.get(name); @@ -338,14 +338,14 @@ public class Reflector implements Setter { * Add an attribute setter for the given property. The setter will only * be added if it does not override a higher priorty setter * - * @param attributeName the name of the attribute that the setter operates + * @param attributeName the name of the attribute that the setter operates * upon. * @param setter the AttribnuteSetter instance to use. */ - private void addAttributeSetter(String attributeName, + private void addAttributeSetter(String attributeName, AttributeSetter setter) { String name = attributeName.toLowerCase(); - AttributeSetter currentSetter + AttributeSetter currentSetter = (AttributeSetter) attributeSetters.get(name); if (currentSetter != null) { // there is a setter, is it lower down in the class hierarchy @@ -359,11 +359,11 @@ public class Reflector implements Setter { return; } } - } + } attributeSetters.put(name, setter); } - - + + /** * Determine if the class associated with this reflector supports a * particular nested element @@ -380,13 +380,13 @@ public class Reflector implements Setter { * Add a method to the reflector for setting an attribute value * * @param m the method, obtained by introspection. - * @param depth the depth of this method's declaration in the class + * @param depth the depth of this method's declaration in the class * hierarchy * @param propertyName the property name the method will set. * @param converters A map of converter classes used to convert strings * to different types. */ - public void addAttributeMethod(Method m, int depth, + public void addAttributeMethod(Method m, int depth, String propertyName, Map converters) { Class type = m.getParameterTypes()[0]; @@ -471,7 +471,7 @@ public class Reflector implements Setter { * Add an attribute setter with an associated converter * * @param m the attribute setter method - * @param depth the depth of this method's declaration in the class + * @param depth the depth of this method's declaration in the class * hierarchy * @param propertyName the name of the attribute this method supports * @param converter the converter to be used to construct the value @@ -479,7 +479,7 @@ public class Reflector implements Setter { */ private void addConvertingSetter(Method m, int depth, String propertyName, Converter converter) { - addAttributeSetter(propertyName, + addAttributeSetter(propertyName, new AttributeSetter(m, depth, converter)); } } 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 index 50b9083ab..cc3b8b0a8 100644 --- 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 @@ -52,7 +52,7 @@ * . */ package org.apache.ant.antcore.execution; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * The Setter interface is used by the Ant core to set values and nested @@ -68,12 +68,12 @@ public interface Setter { * @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 + * @exception AntException 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; + throws AntException; /** * Get the type of the given nested element diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java index 54d250a13..6b8d6b0c1 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskAdapter.java @@ -53,9 +53,9 @@ */ package org.apache.ant.antcore.execution; import java.lang.reflect.Method; - +import java.lang.reflect.InvocationTargetException; import org.apache.ant.common.antlib.AbstractTask; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.event.MessageLevel; /** * Use introspection to "adapt" an arbitrary Bean (not extending Task, but @@ -105,7 +105,16 @@ public class TaskAdapter extends AbstractTask { public void execute() throws ExecutionException { try { executeMethod.invoke(worker, null); + } catch (InvocationTargetException e) { + log("Error in " + worker.getClass(), MessageLevel.MSG_ERR); + Throwable t = e.getTargetException(); + if (t instanceof ExecutionException) { + throw (ExecutionException) t; + } else { + throw new ExecutionException(t); + } } catch (Throwable t) { + log("Error in " + worker.getClass(), MessageLevel.MSG_ERR); throw new ExecutionException(t); } } diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1CompatException.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1CompatException.java new file mode 100644 index 000000000..be4f99e90 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1CompatException.java @@ -0,0 +1,129 @@ +/* + * 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.tools.ant; + +import org.apache.ant.common.util.Location; +import org.apache.ant.common.util.AntException; + +/** + * An exception in the Ant1 compatability layer. + * + * @author Conor MacNeill + */ +public class Ant1CompatException extends AntException { + /** + * Constructs an exception with the given descriptive message. + * + * @param msg Description of or information about the exception. + */ + public Ant1CompatException(String msg) { + super(msg); + } + + /** + * Constructs an exception with the given descriptive message and a + * location in a file. + * + * @param msg Description of or information about the exception. + * @param location Location in the project file where the error occured. + */ + public Ant1CompatException(String msg, Location location) { + super(msg, location); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause. + * + * @param msg Description of or information about the exception. + * @param cause Throwable that might have cause this one. + */ + public Ant1CompatException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause and a location in a file. + * + * @param msg Description of or information about the exception. + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public Ant1CompatException(String msg, Throwable cause, + Location location) { + super(msg, cause, location); + } + + /** + * Constructs an exception with the given exception as a root cause. + * + * @param cause Exception that might have caused this one. + */ + public Ant1CompatException(Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the given exception as a root cause and + * a location in a file. + * + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public Ant1CompatException(Throwable cause, Location location) { + super(cause, location); + } +} + diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Converter.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Converter.java index 20b77d37f..cd5bb847d 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Converter.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Converter.java @@ -54,7 +54,7 @@ package org.apache.tools.ant; import org.apache.ant.common.antlib.AbstractConverter; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.antlib.ConverterException; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Path; @@ -96,9 +96,9 @@ public class Ant1Converter extends AbstractConverter { * @param value The value to be converted * @param type the desired type of the converted object * @return the value of the converted object - * @exception ExecutionException if the conversion cannot be made + * @exception ConverterException if the conversion cannot be made */ - public Object convert(String value, Class type) throws ExecutionException { + public Object convert(String value, Class type) throws ConverterException { if (type.equals(Path.class)) { return new Path(project, value); } else if (EnumeratedAttribute.class.isAssignableFrom(type)) { @@ -108,13 +108,13 @@ public class Ant1Converter extends AbstractConverter { ea.setValue(value); return ea; } catch (InstantiationException e) { - throw new ExecutionException(e); + throw new ConverterException(e); } catch (IllegalAccessException e) { - throw new ExecutionException(e); + throw new ConverterException(e); } } else { - throw new ExecutionException("This converter does not handle " + throw new ConverterException("This converter does not handle " + type.getName()); } } diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java index 56def0204..195d15a19 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java @@ -55,7 +55,7 @@ package org.apache.tools.ant; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.StandardLibFactory; import org.apache.ant.common.service.EventService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.init.LoaderUtils; /** @@ -78,9 +78,9 @@ public class Ant1Factory extends StandardLibFactory { * * @param context the context for this factory to use to access core * services. - * @exception ExecutionException if the factory cannot be initialised. + * @exception AntException if the factory cannot be initialised. */ - public void init(AntContext context) throws ExecutionException { + public void init(AntContext context) throws AntException { if (project != null) { return; } @@ -109,11 +109,11 @@ public class Ant1Factory extends StandardLibFactory { * @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 + * @exception Ant1CompatException if there is a problem creating the task */ public Object createComponent(Class componentClass, String localName) throws InstantiationException, IllegalAccessException, - ExecutionException { + Ant1CompatException { try { java.lang.reflect.Constructor constructor = null; // DataType can have a "no arg" constructor or take a single @@ -123,7 +123,7 @@ public class Ant1Factory extends StandardLibFactory { constructor = componentClass.getConstructor(new Class[0]); component = constructor.newInstance(new Object[0]); } catch (NoSuchMethodException nse) { - constructor + constructor = componentClass.getConstructor(new Class[]{Project.class}); component = constructor.newInstance(new Object[]{project}); } @@ -136,9 +136,9 @@ public class Ant1Factory extends StandardLibFactory { Throwable t = ite.getTargetException(); String msg = "Could not create component of type: " + componentClass.getName() + " due to " + t; - throw new ExecutionException(msg, t); + throw new Ant1CompatException(msg, t); } catch (NoSuchMethodException e) { - throw new ExecutionException("Unable to find an appropriate " + throw new Ant1CompatException("Unable to find an appropriate " + "constructor for component " + componentClass.getName(), e); } } @@ -151,12 +151,12 @@ public class Ant1Factory extends StandardLibFactory { * @return a instance of the required class * @exception InstantiationException if the class cannot be instantiated * @exception IllegalAccessException if the instance cannot be accessed - * @exception ExecutionException if there is a problem creating the + * @exception Ant1CompatException if there is a problem creating the * converter */ public Object createInstance(Class requiredClass) throws InstantiationException, IllegalAccessException, - ExecutionException { + Ant1CompatException { java.lang.reflect.Constructor c = null; @@ -175,9 +175,9 @@ public class Ant1Factory extends StandardLibFactory { Throwable t = ite.getTargetException(); String msg = "Could not create instance of type: " + requiredClass.getName() + " due to " + t; - throw new ExecutionException(msg, t); + throw new Ant1CompatException(msg, t); } catch (NoSuchMethodException e) { - throw new ExecutionException("Unable to find an appropriate " + throw new Ant1CompatException("Unable to find an appropriate " + "constructor for class " + requiredClass.getName(), e); } } @@ -187,11 +187,11 @@ public class Ant1Factory extends StandardLibFactory { * create method. * * @param createdElement the element that the component created - * @exception ExecutionException if there is a problem registering the + * @exception AntException if there is a problem registering the * element */ public void registerCreatedElement(Object createdElement) - throws ExecutionException { + throws AntException { if (createdElement instanceof ProjectComponent) { ProjectComponent component = (ProjectComponent) createdElement; component.setProject(project); diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1InputHandler.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1InputHandler.java index 7a352c4c2..4461bc681 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1InputHandler.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1InputHandler.java @@ -54,7 +54,7 @@ package org.apache.tools.ant; import org.apache.ant.common.service.InputService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.tools.ant.input.InputHandler; import org.apache.tools.ant.input.InputRequest; @@ -87,7 +87,7 @@ public class Ant1InputHandler implements InputHandler { public void handleInput(InputRequest request) throws BuildException { try { inputService.handleInput(request); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } 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 31f33d5a6..d2bcd0bfd 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 @@ -55,22 +55,26 @@ package org.apache.tools.ant; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.Properties; import java.util.Stack; import java.util.Vector; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.AntLibFactory; import org.apache.ant.common.event.MessageLevel; +import org.apache.ant.common.service.BuildKey; import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.ExecService; import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.InputService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.PropertyUtils; import org.apache.tools.ant.input.InputHandler; import org.apache.tools.ant.types.FilterSet; @@ -84,6 +88,11 @@ import org.apache.tools.ant.util.FileUtils; * @created 30 January 2002 */ public class Project implements org.apache.ant.common.event.BuildListener { + /** + * A Property key which identifies the Project actiong as proxy for a + * a project. + */ + private static final String PROXY_KEY = "_ant.proxy"; /** String which indicates Java version 1.0 */ public static final String JAVA_1_0 = "1.0"; @@ -155,6 +164,12 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** The core's Component Service instance */ private ComponentService componentService; + /** + * A static copy of a context used fro Projects which have been created on + * the fly. It is used to access the required core services + */ + private static AntContext sharedContext = null; + /** Ant1 FileUtils instance for manipulating files */ private FileUtils fileUtils; /** The collection of global filters */ @@ -167,6 +182,33 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** the target's we have seen */ private Stack targetStack = new Stack(); + /** + * Flag which indicates if this project object is proxing for a subordinate + * project which has not yet been created. + */ + private boolean proxying; + + /** + * The properties which will be passed to the project instance for which we + * are proxing. + */ + private Map proxyProperties = new HashMap(); + + /** + * The build key used to control the proxied build. + */ + private BuildKey proxyBuildKey; + + /** + * The subordinate project if proxying + */ + private Project subordinate; + + /** + * The requested base dir + */ + private File baseDir = null; + static { // Determine the Java version by looking at available classes @@ -197,18 +239,44 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param factory the factory object creating this project */ public Project(AntLibFactory factory) { + proxying = false; this.factory = factory; fileUtils = FileUtils.newFileUtils(); } /** - * The old constructor fopr Project instances - not used now. + * The old constructor for Project instances - legacy support. * * @deprecated */ public Project() { - throw new BuildException("Projects can not be constructed to " - + "invoke Ant"); + if (sharedContext == null) { + throw new BuildException("Project object can no longer be " + + "constructed outside Ant execution"); + } + proxying = true; + } + + /** + * Configure a new project + * + * @param buildFile the file containing the XML build definition. + */ + protected void configure(File buildFile) { + try { + // we create an execution frame and link ourselves to the Project + // object created in that frame + ExecService sharedExec + = (ExecService) sharedContext.getCoreService(ExecService.class); + org.apache.ant.common.model.Project subProject + = sharedExec.parseXMLBuildFile(buildFile); + proxyProperties.put(PROXY_KEY, this); + proxyBuildKey + = sharedExec.setupBuild(subProject, proxyProperties, false); + sharedExec.initializeBuildLibrary(proxyBuildKey, "ant.ant1compat"); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); + } } /** @@ -270,8 +338,65 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @deprecated */ public void init() throws BuildException { - throw new BuildException("Projects can not be initialized in this " - + "manner any longer."); + String defs = "/org/apache/tools/ant/taskdefs/defaults.properties"; + + try { + Properties props = new Properties(); + InputStream in = this.getClass().getResourceAsStream(defs); + if (in == null) { + throw new BuildException("Can't load default task list"); + } + props.load(in); + in.close(); + + Enumeration enum = props.propertyNames(); + while (enum.hasMoreElements()) { + String key = (String) enum.nextElement(); + String value = props.getProperty(key); + try { + Class taskClass = Class.forName(value); + taskClassDefinitions.put(key, taskClass); + } catch (NoClassDefFoundError ncdfe) { + log("Could not load a dependent class (" + + ncdfe.getMessage() + ") for task " + key, MSG_DEBUG); + } catch (ClassNotFoundException cnfe) { + log("Could not load class (" + value + + ") for task " + key, MSG_DEBUG); + } + } + } catch (IOException ioe) { + throw new BuildException("Can't load default task list"); + } + + String dataDefs = "/org/apache/tools/ant/types/defaults.properties"; + + try { + Properties props = new Properties(); + InputStream in = this.getClass().getResourceAsStream(dataDefs); + if (in == null) { + throw new BuildException("Can't load default datatype list"); + } + props.load(in); + in.close(); + + Enumeration enum = props.propertyNames(); + while (enum.hasMoreElements()) { + String key = (String) enum.nextElement(); + String value = props.getProperty(key); + try { + Class dataClass = Class.forName(value); + dataClassDefinitions.put(key, dataClass); + } catch (NoClassDefFoundError ncdfe) { + log("Could not load a dependent class (" + + ncdfe.getMessage() + ") for type " + key, MSG_DEBUG); + } catch (ClassNotFoundException cnfe) { + log("Could not load class (" + value + + ") for type " + key, MSG_DEBUG); + } + } + } catch (IOException ioe) { + throw new BuildException("Can't load default datatype list"); + } } @@ -284,8 +409,56 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @deprecated */ public void executeTargets(Vector targetNames) throws BuildException { - throw new BuildException("Targets within the project cannot be " - + "executed with this method."); + if (!proxying) { + throw new BuildException("This interface is no longer available."); + } + + try { + List targets = new ArrayList(); + for (Iterator i = targetNames.iterator(); i.hasNext();) { + targets.add(i.next()); + } + + ExecService execService + = (ExecService) sharedContext.getCoreService(ExecService.class); + execService.runBuild(proxyBuildKey, targets); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); + } + } + + /** + * Executes the specified target and any targets it depends on. + * + * @param targetName The name of the target to execute. + * Must not be null. + * + * @exception BuildException if the build failed + */ + public void executeTarget(String targetName) throws BuildException { + + // sanity check ourselves, if we've been asked to build nothing + // then we should complain + + if (targetName == null) { + String msg = "No target specified"; + throw new BuildException(msg); + } + + if (!proxying) { + throw new BuildException("This interface is no longer available."); + } + + try { + List targets = new ArrayList(); + targets.add(targetName); + + ExecService execService + = (ExecService) sharedContext.getCoreService(ExecService.class); + execService.runBuild(proxyBuildKey, targets); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); + } } /** @@ -306,8 +479,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { public void setProperty(String name, String value) { try { dataService.setMutableDataValue(name, value); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -318,10 +491,16 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param value the property value */ public void setNewProperty(String name, String value) { + if (dataService == null) { + if (!proxyProperties.containsKey(name)) { + proxyProperties.put(name, value); + } + return; + } try { dataService.setDataValue(name, value); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -333,10 +512,15 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param value the property value */ public void setUserProperty(String name, String value) { + if (dataService == null) { + proxyProperties.put(name, value); + return; + } + try { dataService.setMutableDataValue(name, value); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -345,10 +529,10 @@ public class Project implements org.apache.ant.common.event.BuildListener { * special handling for instances of tasks and data types. *

* This is useful for logging purposes. - * + * * @param element The element to describe. * Must not be null. - * + * * @return a description of the element type * * @since 1.95, Ant 1.5 @@ -467,8 +651,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { try { Object value = dataService.getDataValue(name); return value == null ? null : value.toString(); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -482,8 +666,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { public String getUserProperty(String name) { try { return dataService.getDataValue(name).toString(); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -497,8 +681,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { public Object getReference(String refId) { try { return dataService.getDataValue(refId); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -585,6 +769,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @since 1.102, Ant 1.5 */ public void registerThreadTask(Thread thread, Task task) { +// XXX // if (task != null) { // threadTasks.put(thread, task); // } else { @@ -601,7 +786,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { */ public Task getThreadTask(Thread thread) { return null; - // return (Task)threadTasks.get(thread); + // return (Task)threadTasks.get(thread); XXX } /** @@ -655,6 +840,10 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param event task started event */ public void taskStarted(org.apache.ant.common.event.BuildEvent event) { + Object source = event.getSource(); + if (source instanceof Task) { + fireTaskStarted((Task) source); + } } /** @@ -663,6 +852,10 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param event task finished event */ public void taskFinished(org.apache.ant.common.event.BuildEvent event) { + Object source = event.getSource(); + if (source instanceof Task) { + fireTaskFinished((Task) source, event.getCause()); + } } /** @@ -671,6 +864,14 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param event message logged event */ public void messageLogged(org.apache.ant.common.event.BuildEvent event) { + Object source = event.getSource(); + if (source instanceof Task) { + fireMessageLogged((Task) source, event.getMessage(), + event.getPriority()); + } else { + fireMessageLogged(this, event.getMessage(), + event.getPriority()); + } } /** @@ -679,7 +880,11 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param listener the listener to be added to the project */ public void addBuildListener(BuildListener listener) { - listeners.addElement(listener); + if (subordinate != null) { + subordinate.addBuildListener(listener); + } else { + listeners.addElement(listener); + } } /** @@ -701,8 +906,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { public void addReference(String name, Object value) { try { dataService.setDataValue(name, value); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -758,8 +963,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** * Convienence method to copy a file from a source to a destination * specifying if token filtering must be used, if source files may - * overwrite newer destination files and the last modified time - * of destFile file should be made equal to the last + * overwrite newer destination files and the last modified time + * of destFile file should be made equal to the last * modified time of sourceFile. * * @param sourceFile the source file to be copied @@ -829,8 +1034,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** * Convienence method to copy a file from a source to a destination * specifying if token filtering must be used, if source files may - * overwrite newer destination files and the last modified time of - * destFile file should be made equal to the last + * overwrite newer destination files and the last modified time of + * destFile file should be made equal to the last * modified time of sourceFile. * * @param sourceFile the source file to be copied @@ -849,83 +1054,104 @@ public class Project implements org.apache.ant.common.event.BuildListener { filtering ? globalFilters : null, overwrite, preserveLastModified); } + + + /** + * Initialise this project + * + * @param context the context the project uses to access core services + * @exception AntException if the project cannot be initialised. + */ + public void init(AntContext context) throws AntException { + initContext(context); + Object proxy = dataService.getDataValue(PROXY_KEY); + if (proxy != null) { + Project proxyProject = (Project) proxy; + proxyProject.setSubordinate(this); + } + init(); + } + + /** + * Connect this project to its subordinate. + * + * When the subordinate project is created it will call this method to + * inform this project. The core services are then initialised using the + * context of the subordinate project + * + * @param subordinate the subordinate project + * + * @exception AntException if there is a problem configuring this project to + * use the subordinate's context. + */ + private void setSubordinate(Project subordinate) throws AntException { + initContext(subordinate.getContext()); + // add our listeners to the subordinate + for (Iterator i = listeners.iterator(); i.hasNext();) { + BuildListener listener = (BuildListener) i.next(); + subordinate.addBuildListener(listener); + } + if (baseDir != null) { + execService.setBaseDir(baseDir); + } + this.subordinate = subordinate; + } + + /** + * Sets the base directory for the project, checking that + * the given filename exists and is a directory. + * + * @param baseDir The project base directory. + * Must not be null. + * + * @exception BuildException if the directory if invalid + */ + public void setBasedir(String baseDir) throws BuildException { + setBaseDir(new File(baseDir)); + } + /** - * Initialise this porject + * Sets the base directory for the project, checking that + * the given file exists and is a directory. + * + * @param baseDir The project base directory. + * Must not be null. + * @exception BuildException if the specified file doesn't exist or + * isn't a directory + */ + public void setBaseDir(File baseDir) throws BuildException { + try { + if (execService != null) { + execService.setBaseDir(baseDir); + } + this.baseDir = baseDir; + proxyProperties.put("basedir", baseDir.getPath()); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); + } + } + + /** + * Initialise the context related parts of this project * * @param context the context the project uses to access core services - * @exception ExecutionException if the project cannot be initialised. + * @exception AntException if the project cannot be initialised. */ - public void init(AntContext context) throws ExecutionException { + public void initContext(AntContext context) throws AntException { this.context = context; + if (sharedContext == null) { + sharedContext = context; + } + fileService = (FileService) context.getCoreService(FileService.class); dataService = (DataService) context.getCoreService(DataService.class); execService = (ExecService) context.getCoreService(ExecService.class); - componentService = (ComponentService) + componentService = (ComponentService) context.getCoreService(ComponentService.class); InputService inputService = (InputService) context.getCoreService(InputService.class); setInputHandler(new Ant1InputHandler(inputService)); - - String defs = "/org/apache/tools/ant/taskdefs/defaults.properties"; - - try { - Properties props = new Properties(); - InputStream in = this.getClass().getResourceAsStream(defs); - if (in == null) { - throw new BuildException("Can't load default task list"); - } - props.load(in); - in.close(); - - Enumeration enum = props.propertyNames(); - while (enum.hasMoreElements()) { - String key = (String) enum.nextElement(); - String value = props.getProperty(key); - try { - Class taskClass = Class.forName(value); - taskClassDefinitions.put(key, taskClass); - } catch (NoClassDefFoundError ncdfe) { - log("Could not load a dependent class (" - + ncdfe.getMessage() + ") for task " + key, MSG_DEBUG); - } catch (ClassNotFoundException cnfe) { - log("Could not load class (" + value - + ") for task " + key, MSG_DEBUG); - } - } - } catch (IOException ioe) { - throw new BuildException("Can't load default task list"); - } - - String dataDefs = "/org/apache/tools/ant/types/defaults.properties"; - - try { - Properties props = new Properties(); - InputStream in = this.getClass().getResourceAsStream(dataDefs); - if (in == null) { - throw new BuildException("Can't load default datatype list"); - } - props.load(in); - in.close(); - - Enumeration enum = props.propertyNames(); - while (enum.hasMoreElements()) { - String key = (String) enum.nextElement(); - String value = props.getProperty(key); - try { - Class dataClass = Class.forName(value); - dataClassDefinitions.put(key, dataClass); - } catch (NoClassDefFoundError ncdfe) { - log("Could not load a dependent class (" - + ncdfe.getMessage() + ") for type " + key, MSG_DEBUG); - } catch (ClassNotFoundException cnfe) { - log("Could not load class (" + value - + ") for type " + key, MSG_DEBUG); - } - } - } catch (IOException ioe) { - throw new BuildException("Can't load default datatype list"); - } } /** @@ -946,7 +1172,11 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param msgLevel level to log at */ public void log(String msg, int msgLevel) { - context.log(msg, msgLevel); + if (context != null) { + context.log(msg, msgLevel); + } else { + sharedContext.log(msg, msgLevel); + } } /** @@ -976,7 +1206,33 @@ public class Project implements org.apache.ant.common.event.BuildListener { * @param msgLevel level to log at */ public void log(Task task, String msg, int msgLevel) { - context.log(msg, msgLevel); + if (context != null) { + context.log(msg, msgLevel); + } else { + sharedContext.log(msg, msgLevel); + } + } + + + /** + * Returns the canonical form of a filename. + *

+ * If the specified file name is relative it is resolved + * with respect to the given root directory. + * + * @param fileName The name of the file to resolve. + * Must not be null. + * + * @param rootDir The directory to resolve relative file names with + * respect to. May be null, in which case + * the current directory is used. + * + * @return the resolved File. + * + * @deprecated + */ + public File resolveFile(String fileName, File rootDir) { + return fileUtils.resolveFile(rootDir, fileName); } /** @@ -988,8 +1244,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { public File resolveFile(String fileName) { try { return fileService.resolveFile(fileName); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -1002,8 +1258,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { public String replaceProperties(String value) { try { return dataService.replacePropertyRefs(value); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -1020,8 +1276,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { componentService.taskdef(factory, taskClass.getClassLoader(), taskName, taskClass.getName()); taskClassDefinitions.put(taskName, taskClass); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -1036,8 +1292,8 @@ public class Project implements org.apache.ant.common.event.BuildListener { componentService.typedef(factory, typeClass.getClassLoader(), typeName, typeClass.getName()); dataClassDefinitions.put(typeName, typeClass); - } catch (ExecutionException e) { - throw new BuildException(e); + } catch (AntException e) { + throw new BuildException(e.getMessage(), e); } } @@ -1070,7 +1326,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { task.setTaskName(taskType); return task; } catch (Throwable e) { - throw new BuildException(e); + throw new BuildException(e.getMessage(), e); } } @@ -1094,7 +1350,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { try { return componentService.createComponent(typeName); } catch (Throwable e) { - throw new BuildException(e); + throw new BuildException(e.getMessage(), e); } } diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java index 964c1e0cc..cbb99da79 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java @@ -54,7 +54,7 @@ package org.apache.tools.ant; import org.apache.ant.common.antlib.AntContext; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * ProjectComponent facade @@ -113,10 +113,10 @@ public abstract class ProjectComponent { * * @param context the core context for this component * @param componentType the component type of this component - * @exception ExecutionException if the component cannot be initialized + * @exception AntException if the component cannot be initialized */ - public void init(AntContext context, String componentType) - throws ExecutionException { + public void init(AntContext context, String componentType) + throws AntException { this.context = context; this.componentType = componentType; diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectHelper.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectHelper.java index 739847a61..ea86edecb 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectHelper.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectHelper.java @@ -58,7 +58,6 @@ import java.io.File; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.service.DataService; import org.apache.ant.common.util.AntException; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.PropertyUtils; /** @@ -106,7 +105,7 @@ public class ProjectHelper { DataService dataService = (DataService) context.getCoreService(DataService.class); return dataService.replacePropertyRefs(value); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -128,25 +127,24 @@ public class ProjectHelper { DataService dataService = (DataService) context.getCoreService(DataService.class); return dataService.replacePropertyRefs(value, keys); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } /** * Old method to build a project. - * + * * @param project The project to configure. Must not be null. * @param buildFile An XML file giving the project's configuration. * Must not be null. - * + * * @exception BuildException always * @deprecated */ - public static void configureProject(Project project, File buildFile) - throws BuildException { - throw new BuildException("Project are not built by ProjectHelper " - + "any longer."); + public static void configureProject(Project project, File buildFile) + throws BuildException { + project.configure(buildFile); } } diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java index 15536841f..e4039a421 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java @@ -55,7 +55,7 @@ package org.apache.tools.ant; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.service.ExecService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Ant1 Task facade @@ -77,10 +77,10 @@ public abstract class Task extends ProjectComponent protected Location location; /** - * Called by the project to let the task do its work. This method may be - * called more than once, if the task is invoked more than once. - * For example, - * if target1 and target2 both depend on target3, then running + * Called by the project to let the task do its work. This method may be + * called more than once, if the task is invoked more than once. + * For example, + * if target1 and target2 both depend on target3, then running * "ant target1 target2" will run all tasks in target3 twice. * * @exception BuildException if something goes wrong with the build @@ -159,10 +159,10 @@ public abstract class Task extends ProjectComponent * Add a nested task to this Ant1 task. * * @param task The task to be added - * @exception ExecutionException if the task cannot be added. + * @exception AntException if the task cannot be added. */ public void addNestedTask(org.apache.ant.common.antlib.Task task) - throws ExecutionException { + throws AntException { if (!(this instanceof TaskContainer)) { throw new BuildException("Can't add tasks to this task"); @@ -185,15 +185,15 @@ public abstract class Task extends ProjectComponent * * @param context the core context for this component * @param componentType the component type of this component - * @exception ExecutionException if the component cannot be initialized + * @exception AntException if the component cannot be initialized */ public void init(AntContext context, String componentType) - throws ExecutionException { + throws AntException { super.init(context, componentType); taskType = componentType; taskName = componentType; - + org.apache.ant.common.util.Location contextLocation = context.getLocation(); @@ -225,7 +225,7 @@ public abstract class Task extends ProjectComponent ExecService execService = (ExecService) context.getCoreService(ExecService.class); execService.executeTask(this); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -281,7 +281,7 @@ public abstract class Task extends ProjectComponent void setTaskType(String type) { this.taskType = type; } - + /** * Sets the file location where this task was defined. * diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/Ant.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/Ant.java index 00016ef14..31120bf9e 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/Ant.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/Ant.java @@ -60,7 +60,7 @@ import org.apache.ant.antlib.system.AntBase; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.AntLibFactory; import org.apache.ant.common.service.ComponentService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; @@ -147,7 +147,7 @@ public class Ant extends Task { AntLibFactory factory = getProject().getFactory(); realAnt = (org.apache.ant.antlib.system.Ant) componentService.createComponent("ant.system", "ant"); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -156,7 +156,7 @@ public class Ant extends Task { /** * Do the execution. * - * @exception BuildException if the execution of the sub-build has a + * @exception BuildException if the execution of the sub-build has a * problem */ public void execute() throws BuildException { @@ -169,7 +169,7 @@ public class Ant extends Task { } try { realAnt.execute(); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -194,7 +194,7 @@ public class Ant extends Task { public void addReference(AntBase.Reference r) { try { realAnt.addReference(r); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -203,11 +203,11 @@ public class Ant extends Task { * Gets the componentService * * @return the componentService instance provided by the core - * @exception ExecutionException if the service is not available. + * @exception AntException if the service is not available. */ - private ComponentService getComponentService() throws ExecutionException { + private ComponentService getComponentService() throws AntException { AntContext context = getAntContext(); - return (ComponentService) + return (ComponentService) context.getCoreService(ComponentService.class); } diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/CallTarget.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/CallTarget.java index e09156e07..aae5dfd2e 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/CallTarget.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/taskdefs/CallTarget.java @@ -60,7 +60,7 @@ import org.apache.ant.antlib.system.AntCall; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.AntLibFactory; import org.apache.ant.common.service.ComponentService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; @@ -104,7 +104,7 @@ public class CallTarget extends Task { AntLibFactory factory = getProject().getFactory(); antCall = (AntCall) componentService.createComponent("ant.system", "antcall"); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -120,7 +120,7 @@ public class CallTarget extends Task { } try { antCall.execute(); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -145,7 +145,7 @@ public class CallTarget extends Task { public void addReference(AntBase.Reference r) { try { antCall.addReference(r); - } catch (ExecutionException e) { + } catch (AntException e) { throw new BuildException(e); } } @@ -154,11 +154,11 @@ public class CallTarget extends Task { * Gets the componentService * * @return the componentService instance provided by the core - * @exception ExecutionException if the service is not available. + * @exception AntException if the service is not available. */ - private ComponentService getComponentService() throws ExecutionException { + private ComponentService getComponentService() throws AntException { AntContext context = getAntContext(); - return + return (ComponentService) context.getCoreService(ComponentService.class); } } diff --git a/proposal/mutant/src/java/antlibs/monitor/antlib.xml b/proposal/mutant/src/java/antlibs/monitor/antlib.xml new file mode 100644 index 000000000..a83a6e1a1 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/monitor/antlib.xml @@ -0,0 +1,4 @@ + + + diff --git a/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java new file mode 100644 index 000000000..c01c2783f --- /dev/null +++ b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java @@ -0,0 +1,176 @@ +/* + * 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.monitor; + +import org.apache.ant.common.antlib.AbstractAspect; +import org.apache.ant.common.antlib.Task; +import org.apache.ant.common.model.BuildElement; +import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.util.AntException; +import org.apache.ant.common.event.MessageLevel; +import java.util.Date; +import java.io.PrintStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * A monitoring aspect to help understand memory and performance + * characteristics. + * + * @author Conor MacNeill + */ +public class MonitorAspect extends AbstractAspect { + private static PrintStream monitorLog; + private static long lastMessageTime; + public MonitorAspect() { + if (monitorLog == null) { + try { + monitorLog + = new PrintStream(new FileOutputStream("monitor.log")); + monitorLog.println("Logging started at " + new Date()); + lastMessageTime = System.currentTimeMillis(); + } catch (IOException e) { + log("Unable to open monitor log", MessageLevel.MSG_WARN); + } + } + } + + private void monitor(String message) { + Runtime rt = Runtime.getRuntime(); + synchronized (monitorLog) { + long now = System.currentTimeMillis(); + long diff = now - lastMessageTime; + lastMessageTime = now; + long freeMem = rt.freeMemory(); + long usedMem = rt.totalMemory() - freeMem; + monitorLog.println("+" + diff + " (" + usedMem + "/" + + freeMem + "): " + message); + } + } + + /** + * This join point is activated before a component is to be created. + * The aspect can return an object to be used rather than the core creating + * the object. + * + * @param component the component that has been created. This will be null + * unless another aspect has created the component + * @param model the Build model that applies to the component + * + * @return a component to use. + * @exception AntException if the aspect cannot process the component. + */ + public Object preCreateComponent(Object component, BuildElement model) + throws AntException { + monitor("Creating component " + "from <" + model.getType() + ">"); + return component; + } + + /** + * This join point is activated after a component has been created and + * configured. If the aspect wishes, an object can be returned in place + * of the one created by Ant. + * + * @param component the component that has been created. + * @param model the Build model used to create the component. + * + * @return a replacement for the component if desired. If null is returned + * the current component is used. + * @exception AntException if the aspect cannot process the component. + */ + public Object postCreateComponent(Object component, BuildElement model) + throws AntException { + monitor("Created component " + + component.getClass().getName() + + " from <" + model.getType() + ">"); + return component; + } + + /** + * This join point is activated just prior to task execution. + * + * @param task the task being executed. + * @param aspectValues a collection of aspect attribute values for use + * during the task execution - may be null if no aspect values are + * provided. + * @return an object which indicates that this aspect wishes to + * be notified after execution has been completed, in which case the obkect + * is returned to provide the aspect its context. If this returns null + * the aspect's postExecuteTask method will not be invoked. + * @exception AntException if the aspect cannot process the task. + */ + public Object preExecuteTask(Task task, AspectValueCollection aspectValues) + throws AntException { + String taskName = task.getClass().getName(); + MonitorRecord record = new MonitorRecord(taskName); + return record; + } + + /** + * This join point is activated after a task has executed. The aspect + * may override the task's failure cause by returning a new failure. + * + * @param context the context the aspect provided in preExecuteTask. + * @param failureCause the current failure reason for the task. + * + * @return a new failure reason or null if the task is not to fail. + */ + public Throwable postExecuteTask(Object context, Throwable failureCause) { + MonitorRecord record = (MonitorRecord)context; + record.print(monitorLog); + System.gc(); + return failureCause; + } + +} diff --git a/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorRecord.java b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorRecord.java new file mode 100644 index 000000000..0b30d0740 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorRecord.java @@ -0,0 +1,94 @@ +/* + * 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.monitor; + +import org.apache.ant.common.antlib.AbstractAspect; +import org.apache.ant.common.antlib.Task; +import org.apache.ant.common.model.BuildElement; +import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.util.AntException; +import org.apache.ant.common.event.MessageLevel; +import java.util.Date; +import java.io.PrintStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * A record of some performance values at a particular time + * + * @author Conor MacNeill + */ +public class MonitorRecord { + private String recordName; + private long startMillis; + private long startMemory; + + private long getMemoryUsage() { + Runtime rt = Runtime.getRuntime(); + return rt.totalMemory() - rt.freeMemory(); + } + + public MonitorRecord(String recordName) { + this.recordName = recordName; + startMillis = System.currentTimeMillis(); + startMemory = getMemoryUsage(); + } + + public void print(PrintStream stream) { + long timeDiff = System.currentTimeMillis() - startMillis; + long memDiff = getMemoryUsage() - startMemory; + stream.println(recordName + " took " + timeDiff + + " milliseconds and memory used changed by " + memDiff); + } +} 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 index 957abb946..724afc3d2 100644 --- 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 @@ -62,7 +62,6 @@ 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; import org.apache.ant.common.antlib.AntContext; /** @@ -113,9 +112,9 @@ public class ScriptBase extends AbstractTask implements DeferredTask { /** * Execute the script * - * @exception ExecutionException if tghe script execution fails + * @exception ScriptException if tghe script execution fails */ - public void execute() throws ExecutionException { + public void execute() throws ScriptException { String language = factory.getScriptLanguage(scriptName); String script = factory.getScript(scriptName); @@ -123,10 +122,10 @@ public class ScriptBase extends AbstractTask implements DeferredTask { BSFManager manager = new BSFManager(); manager.declareBean("self", this, getClass()); manager.declareBean("context", getAntContext(), AntContext.class); - + // 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(); @@ -135,7 +134,7 @@ public class ScriptBase extends AbstractTask implements DeferredTask { setter.setCharAt(0, Character.toUpperCase(setter.charAt(0))); engine.call(null, "set" + setter, new Object[]{value}); } - + Iterator i = nestedElementNames.iterator(); Iterator j = nestedElements.iterator(); while (i.hasNext()) { @@ -145,19 +144,19 @@ public class ScriptBase extends AbstractTask implements DeferredTask { adder.setCharAt(0, Character.toUpperCase(adder.charAt(0))); engine.call(null, "add" + adder, new Object[]{nestedElement}); } - + 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; + if (te instanceof ScriptException) { + throw (ScriptException) te; } else { t = te; } } - throw new ExecutionException(t); + throw new ScriptException(t); } } 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 index d41ae98ca..702e1469d 100644 --- 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 @@ -54,7 +54,7 @@ package org.apache.ant.antlib.script; import org.apache.ant.common.antlib.AbstractTask; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Define a task using a script @@ -98,9 +98,9 @@ public class ScriptDef extends AbstractTask { * 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 + * @exception AntException if the script cannot be defined */ - public void execute() throws ExecutionException { + public void execute() throws AntException { // tell the factory about this script, under this name. factory.defineScript(name, language, script); } diff --git a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptException.java b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptException.java new file mode 100644 index 000000000..0b5c5dd31 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptException.java @@ -0,0 +1,129 @@ +/* + * 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.util.Location; +import org.apache.ant.common.util.AntException; + +/** + * A Script related exception + * + * @author Conor MacNeill + */ +public class ScriptException extends AntException { + /** + * Constructs an exception with the given descriptive message. + * + * @param msg Description of or information about the exception. + */ + public ScriptException(String msg) { + super(msg); + } + + /** + * Constructs an exception with the given descriptive message and a + * location in a file. + * + * @param msg Description of or information about the exception. + * @param location Location in the project file where the error occured. + */ + public ScriptException(String msg, Location location) { + super(msg, location); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause. + * + * @param msg Description of or information about the exception. + * @param cause Throwable that might have cause this one. + */ + public ScriptException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause and a location in a file. + * + * @param msg Description of or information about the exception. + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public ScriptException(String msg, Throwable cause, + Location location) { + super(msg, cause, location); + } + + /** + * Constructs an exception with the given exception as a root cause. + * + * @param cause Exception that might have caused this one. + */ + public ScriptException(Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the given exception as a root cause and + * a location in a file. + * + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public ScriptException(Throwable cause, Location location) { + super(cause, location); + } +} + 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 index af62a21ed..a0cc25a40 100644 --- 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 @@ -58,7 +58,7 @@ 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; +import org.apache.ant.common.util.AntException; /** * The ScriptFactory class is a factory for the Scripting tasks. It stores @@ -120,19 +120,19 @@ public class ScriptFactory extends StandardLibFactory { * Initialise the factory * * @param context the factory's context - * @exception ExecutionException if the factory cannot be initialized + * @exception AntException if the factory cannot be initialized */ - public void init(AntContext context) throws ExecutionException { + public void init(AntContext context) throws AntException { super.init(context); - componentService = (ComponentService) + componentService = (ComponentService) context.getCoreService(ComponentService.class); try { Class.forName("com.ibm.bsf.BSFManager"); } catch (ClassNotFoundException e) { - throw new ExecutionException("The script Ant library requires " + throw new ScriptException("The script Ant library requires " + "bsf.jar to be available"); } catch (NoClassDefFoundError e) { - throw new ExecutionException("The script Ant library requires " + throw new ScriptException("The script Ant library requires " + "bsf.jar to be available. The class " + e.getMessage() + "appears to be missing"); } @@ -147,11 +147,10 @@ public class ScriptFactory extends StandardLibFactory { * @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 + * @exception AntException if there is a problem creating the task */ public Object createComponent(Class componentClass, String localName) - throws InstantiationException, IllegalAccessException, - ExecutionException { + throws InstantiationException, IllegalAccessException, AntException { Object component = super.createComponent(componentClass, localName); if (component instanceof ScriptDef) { @@ -193,10 +192,10 @@ public class ScriptFactory extends StandardLibFactory { * @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 + * @exception AntException if the script cannot be defined */ protected void defineScript(String name, String language, String script) - throws ExecutionException { + throws AntException { ScriptInfo scriptDefinition = new ScriptInfo(language, script); scripts.put(name, scriptDefinition); componentService.taskdef(this, ScriptBase.class.getClassLoader(), diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java index 09ee90db6..404ab1725 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java @@ -53,11 +53,18 @@ */ package org.apache.ant.antlib.system; import java.io.File; +import java.io.PrintStream; +import java.io.FileOutputStream; +import java.io.IOException; import org.apache.ant.common.model.Project; +import org.apache.ant.common.service.BuildKey; 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.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.FileUtils; +import org.apache.ant.common.logger.DefaultLogger; +import org.apache.ant.common.event.MessageLevel; /** * The Ant task - used to execute a different build file @@ -71,7 +78,7 @@ public class Ant extends AntBase { /** the base directory to use for the run */ private File baseDir; /** File to capture any output */ - private File outputFile; + private String output; /** @@ -97,19 +104,19 @@ public class Ant extends AntBase { /** * The output file for capturing the build output * - * @param outputFile the output file for capturing the build output + * @param output the output file for capturing the build output */ - public void setOutput(File outputFile) { - this.outputFile = outputFile; + public void setOutput(String output) { + this.output = output; } /** * Run the sub-build * - * @exception ExecutionException if the build can't be run + * @exception AntException if the build can't be run */ - public void execute() throws ExecutionException { + public void execute() throws AntException { if (baseDir == null) { baseDir = getExecService().getBaseDir(); } @@ -130,10 +137,36 @@ public class Ant extends AntBase { ExecService execService = getExecService(); Project model = execService.parseXMLBuildFile(antFile); - Object key = execService.setupBuild(model, getProperties()); + BuildKey key = execService.setupBuild(model, getProperties(), true); setSubBuildKey(key); + + if (output != null) { + FileService fileService + = (FileService) getCoreService(FileService.class); + + File outfile = null; + if (baseDir != null) { + outfile = FileUtils.newFileUtils().resolveFile(baseDir, output); + } else { + outfile = fileService.resolveFile(output); + } + try { + PrintStream out + = new PrintStream(new FileOutputStream(outfile)); + DefaultLogger logger = new DefaultLogger(); + logger.setMessageOutputLevel(MessageLevel.MSG_INFO); + logger.setOutputPrintStream(out); + logger.setErrorPrintStream(out); + execService.addBuildListener(key, logger); + } catch (IOException ex) { + log("Ant: Can't set output to " + output, + MessageLevel.MSG_INFO); + } + } + execService.runBuild(key, getTargets()); + execService.releaseBuild(key); } } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java index 53dc57b73..a2458d114 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java @@ -57,9 +57,10 @@ import java.util.Map; import org.apache.ant.common.antlib.AbstractAspect; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.Task; +import org.apache.ant.common.antlib.AspectException; import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.ComponentService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.model.AspectValueCollection; @@ -71,7 +72,7 @@ import org.apache.ant.common.model.AspectValueCollection; public class AntAspect extends AbstractAspect { /** The Ant aspect used to identify Ant metadata */ public static final String ANT_ASPECT = "ant"; - + /** The core's data service implementation */ private DataService dataService = null; @@ -79,73 +80,73 @@ public class AntAspect extends AbstractAspect { private ComponentService componentService = null; /** - * Initialise the aspect with a context. + * Initialise the aspect with a context. * * @param context the aspect's context - * @exception ExecutionException if the aspect cannot be initialised + * @exception AntException if the aspect cannot be initialised */ - public void init(AntContext context) throws ExecutionException { + public void init(AntContext context) throws AntException { super.init(context); dataService = (DataService) context.getCoreService(DataService.class); - componentService + componentService = (ComponentService) context.getCoreService(ComponentService.class); } - + /** * This join point is activated before a component has been created. - * The aspect can return an object to be used rather than the core creating - * the object. + * The aspect can return an object to be used rather than the core creating + * the object. * * @param component the component that has been created. This will be null * unless another aspect has created the component * @param model the Build model that applies to the component * * @return a component to use. - * @exception ExecutionException if the aspect cannot process the component. - */ + * @exception AntException if the aspect cannot process the component. + */ public Object preCreateComponent(Object component, BuildElement model) - throws ExecutionException { + throws AntException { String refId = model.getAspectAttributeValue(ANT_ASPECT, "refid"); if (refId != null) { if (model.getAttributeNames().hasNext() || model.getNestedElements().hasNext() || model.getText().length() != 0) { - throw new ExecutionException("Element <" + model.getType() + throw new AspectException("Element <" + model.getType() + "> is defined by reference and hence may not specify " + "any attributes, nested elements or content", model.getLocation()); } Object referredComponent = dataService.getDataValue(refId); if (referredComponent == null) { - throw new ExecutionException("The given ant:refid value '" + throw new AspectException("The given ant:refid value '" + refId + "' is not defined", model.getLocation()); } return referredComponent; - } + } return component; } - + /** * This join point is activated after a component has been created and * configured. If the aspect wishes, an object can be returned in place - * of the one created by Ant. + * of the one created by Ant. * * @param component the component that has been created. * @param model the Build model used to create the component. * * @return a replacement for the component if desired. If null is returned * the current component is used. - * @exception ExecutionException if the component cannot be processed. - */ - public Object postCreateComponent(Object component, BuildElement model) - throws ExecutionException { + * @exception AntException if the component cannot be processed. + */ + public Object postCreateComponent(Object component, BuildElement model) + throws AntException { String typeId = model.getAspectAttributeValue(ANT_ASPECT, "id"); - + if (typeId != null) { dataService.setMutableDataValue(typeId, component); } - + return super.postCreateComponent(component, model); } @@ -153,31 +154,31 @@ public class AntAspect extends AbstractAspect { * This join point is activated just prior to task execution. * * @param task the task being executed. - * @param aspectValues a collection of aspect attribute values for use + * @param aspectValues a collection of aspect attribute values for use * during the task execution. * - * @return an objectwhich indicates that this aspect wishes to + * @return an objectwhich indicates that this aspect wishes to * be notified after execution has been completed, in which case the obkect * is returned to provide the aspect its context. If this returns null * the aspect's postExecuteTask method will not be invoked. - * @exception ExecutionException if the aspect cannot process the task. + * @exception AntException if the aspect cannot process the task. */ - public Object preExecuteTask(Task task, AspectValueCollection aspectValues) - throws ExecutionException { + public Object preExecuteTask(Task task, AspectValueCollection aspectValues) + throws AntException { AntAspectContext aspectContext = new AntAspectContext(); Map antAspectValues = aspectValues.getAttributes(ANT_ASPECT); if (antAspectValues == null) { return null; } - - componentService.configureAttributes(aspectContext, antAspectValues, + + componentService.configureAttributes(aspectContext, antAspectValues, true); if (aspectContext.isRequired()) { return aspectContext; } - return null; + return null; } - + /** * This join point is activated after a task has executed. The aspect * may override the task's failure cause by returning a new failure. diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java index 760bc3595..b67be9791 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java @@ -55,7 +55,8 @@ package org.apache.ant.antlib.system; import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; +import org.apache.ant.common.service.BuildKey; /** * Common Base class for the Ant and AntCall tasks @@ -80,7 +81,7 @@ public abstract class AntBase extends SubBuild { /** * The key to the subbuild with which the Ant task can manage the subbuild */ - private Object subbuildKey; + private BuildKey subbuildKey; /** The name of the target to be evaluated in the sub-build */ private String targetName; @@ -125,9 +126,9 @@ public abstract class AntBase extends SubBuild { * System.err, directly or indirectly. * * @param line The line of error info produce by the task - * @exception ExecutionException if the output cannot be handled. + * @exception AntException if the output cannot be handled. */ - public void handleSystemErr(String line) throws ExecutionException { + public void handleSystemErr(String line) throws AntException { if (subbuildKey == null) { super.handleSystemErr(line); } else { @@ -143,9 +144,9 @@ public abstract class AntBase extends SubBuild { * or indirectly. * * @param line The line of content produce by the task - * @exception ExecutionException if the output cannot be handled. + * @exception AntException if the output cannot be handled. */ - public void handleSystemOut(String line) throws ExecutionException { + public void handleSystemOut(String line) throws AntException { if (subbuildKey == null) { super.handleSystemOut(line); } else { @@ -180,7 +181,7 @@ public abstract class AntBase extends SubBuild { * * @param key the key returned by the Ant core for managing the subbuild */ - protected void setSubBuildKey(Object key) { + protected void setSubBuildKey(BuildKey key) { this.subbuildKey = key; } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java index d5e62110b..b93d1b149 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java @@ -52,8 +52,9 @@ * . */ package org.apache.ant.antlib.system; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.service.MagicProperties; +import org.apache.ant.common.service.BuildKey; /** * The Ant task - used to execute a different build file @@ -65,15 +66,16 @@ public class AntCall extends AntBase { /** * Execute the sub-build * - * @exception ExecutionException if the build fails + * @exception AntException if the build fails */ - public void execute() throws ExecutionException { - setProperty(MagicProperties.BASEDIR, + public void execute() throws AntException { + setProperty(MagicProperties.BASEDIR, getExecService().getBaseDir().getAbsolutePath()); - Object key = getExecService().setupBuild(getProperties()); + BuildKey key = getExecService().setupBuild(getProperties(), true); setSubBuildKey(key); getExecService().runBuild(key, getTargets()); + getExecService().releaseBuild(key); } /** diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/FileConverter.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/FileConverter.java index e2558991f..a0ad496e0 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/FileConverter.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/FileConverter.java @@ -55,7 +55,7 @@ package org.apache.ant.antlib.system; import java.io.File; import org.apache.ant.common.antlib.AbstractConverter; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.antlib.ConverterException; import org.apache.ant.common.util.AntException; import org.apache.ant.common.service.FileService; @@ -85,15 +85,15 @@ public class FileConverter extends AbstractConverter { * @param value The value to be converted * @param type the desired type of the converted object * @return the value of the converted object - * @exception ExecutionException if the conversion cannot be made + * @exception ConverterException if the conversion cannot be made */ - public Object convert(String value, Class type) throws ExecutionException { + public Object convert(String value, Class type) throws ConverterException { try { - FileService fileService + FileService fileService = (FileService) getContext().getCoreService(FileService.class); return fileService.resolveFile(value); } catch (AntException e) { - throw new ExecutionException("Unable to resolve file: " + throw new ConverterException("Unable to resolve file: " + value, e); } } 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 index 481f312bf..a5145ab33 100644 --- 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 @@ -55,8 +55,9 @@ 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.antlib.ValidationException; import org.apache.ant.common.service.ComponentService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Task to import a component or components from a library @@ -116,22 +117,22 @@ public class Import extends AbstractTask { /** * Validate this task is properly configured * - * @exception ExecutionException if the task is not configured correctly + * @exception ValidationException if the task is not configured correctly */ - public void validateComponent() throws ExecutionException { + public void validateComponent() throws ValidationException { if (ref != null) { if (libraryId != null || name != null) { - throw new ExecutionException("The \"ref\" attribute can only " + throw new ValidationException("The \"ref\" attribute can only " + "be used when \"libraryId\" and \"name\" attributes are " + "not present"); } } else { if (libraryId == null) { - throw new ExecutionException("You must specify a library " + throw new ValidationException("You must specify a library " + "identifier with the \"libraryid\" attribute"); } if (alias != null && name == null) { - throw new ExecutionException("You may only specify an alias" + throw new ValidationException("You may only specify an alias" + " when you specify the \"name\" or \"ref\" attributes"); } } @@ -140,9 +141,9 @@ public class Import extends AbstractTask { /** * Do the work and import the component or components * - * @exception ExecutionException if the components cannot be imported + * @exception AntException if the components cannot be imported */ - public void execute() throws ExecutionException { + public void execute() throws AntException { AntContext context = getAntContext(); ComponentService componentService = (ComponentService) context.getCoreService(ComponentService.class); 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 index bbd54737f..97ac0858e 100644 --- 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 @@ -58,8 +58,9 @@ import java.net.URL; import org.apache.ant.common.antlib.AbstractTask; import org.apache.ant.common.antlib.AntContext; +import org.apache.ant.common.antlib.ValidationException; import org.apache.ant.common.service.ComponentService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.event.MessageLevel; import org.apache.ant.init.InitUtils; @@ -91,9 +92,9 @@ public class LibPath extends AbstractTask { * 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 + * @exception ValidationException if the URL cannot be set */ - public void setURL(URL url) throws ExecutionException { + public void setURL(URL url) throws ValidationException { checkNullURL(); this.url = url; } @@ -102,14 +103,14 @@ public class LibPath extends AbstractTask { * 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 + * @exception ValidationException if the file attribute cannot be set */ - public void setFile(File file) throws ExecutionException { + public void setFile(File file) throws ValidationException { checkNullURL(); try { this.url = InitUtils.getFileURL(file); } catch (MalformedURLException e) { - throw new ExecutionException(e); + throw new ValidationException(e); } } @@ -117,29 +118,29 @@ public class LibPath extends AbstractTask { * 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 + * @exception ValidationException if the dir attribute cannot be set */ - public void setDir(File dir) throws ExecutionException { + public void setDir(File dir) throws ValidationException { checkNullURL(); try { this.url = InitUtils.getFileURL(dir); } catch (MalformedURLException e) { - throw new ExecutionException(e); + throw new ValidationException(e); } } /** * Validate this task is configured correctly * - * @exception ExecutionException if the task is not configured correctly + * @exception ValidationException if the task is not configured correctly */ - public void validateComponent() throws ExecutionException { + public void validateComponent() throws ValidationException { if (libraryId == null) { - throw new ExecutionException("You must specify the id of the" + throw new ValidationException("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 " + throw new ValidationException("You must provide an additional " + "classpath using one of the file, dir or url attributes"); } } @@ -147,15 +148,15 @@ public class LibPath extends AbstractTask { /** * Add the libpath to the set of paths associated with the library * - * @exception ExecutionException if the library path cannot be addded to + * @exception AntException if the library path cannot be addded to * the library */ - public void execute() throws ExecutionException { + public void execute() throws AntException { AntContext context = getAntContext(); ComponentService componentService = (ComponentService) context.getCoreService(ComponentService.class); - log("Adding lib path " + url + " for " + libraryId, - MessageLevel.MSG_DEBUG); + log("Adding lib path " + url + " for " + libraryId, + MessageLevel.MSG_DEBUG); componentService.addLibPath(libraryId, url); } @@ -163,12 +164,13 @@ public class LibPath extends AbstractTask { * Check if any of the location specifying attributes have already been * set. * - * @exception ExecutionException if the search URL has already been set + * @exception ValidationException if the search URL has already been set */ - private void checkNullURL() throws ExecutionException { + private void checkNullURL() throws ValidationException { if (url != null) { - throw new ExecutionException("Location of library has already been " - + "set. Please use only one of file, dir or url attributes"); + throw new ValidationException("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/org/apache/ant/antlib/system/LoadLib.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java index 11cf85197..1461483d6 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java @@ -58,7 +58,8 @@ 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.common.antlib.ValidationException; +import org.apache.ant.common.util.AntException; import org.apache.ant.init.InitUtils; /** @@ -81,9 +82,9 @@ public class LoadLib extends AbstractTask { * 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 + * @exception ValidationException if the URL cannot be set */ - public void setURL(URL url) throws ExecutionException { + public void setURL(URL url) throws ValidationException { checkNullURL(); this.url = url; } @@ -92,14 +93,14 @@ public class LoadLib extends AbstractTask { * 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 + * @exception ValidationException if the file attribute cannot be set */ - public void setFile(File file) throws ExecutionException { + public void setFile(File file) throws ValidationException { checkNullURL(); try { this.url = InitUtils.getFileURL(file); } catch (MalformedURLException e) { - throw new ExecutionException(e); + throw new ValidationException(e); } } @@ -107,14 +108,14 @@ public class LoadLib extends AbstractTask { * 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 + * @exception ValidationException if the dir attribute cannot be set */ - public void setDir(File dir) throws ExecutionException { + public void setDir(File dir) throws ValidationException { checkNullURL(); try { this.url = InitUtils.getFileURL(dir); } catch (MalformedURLException e) { - throw new ExecutionException(e); + throw new ValidationException(e); } } @@ -131,11 +132,11 @@ public class LoadLib extends AbstractTask { /** * Validate this task is configured correctly * - * @exception ExecutionException if the task is not configured correctly + * @exception ValidationException if the task is not configured correctly */ - public void validateComponent() throws ExecutionException { + public void validateComponent() throws ValidationException { if (url == null) { - throw new ExecutionException("A location from which to load " + throw new ValidationException("A location from which to load " + "libraries must be provided"); } } @@ -144,26 +145,27 @@ public class LoadLib extends AbstractTask { /** * Load the library or libraries and optiinally import their components * - * @exception ExecutionException if the library or libraries cannot be + * @exception AntException if the library or libraries cannot be * loaded. */ - public void execute() throws ExecutionException { + public void execute() throws AntException { AntContext context = getAntContext(); ComponentService componentService = (ComponentService) context.getCoreService(ComponentService.class); - componentService.loadLib(url.toString(), importAll, false); + componentService.loadLib(url, importAll); } /** * Check if any of the location specifying attributes have already been * set. * - * @exception ExecutionException if the search URL has already been set + * @exception ValidationException if the search URL has already been set */ - private void checkNullURL() throws ExecutionException { + private void checkNullURL() throws ValidationException { if (url != null) { - throw new ExecutionException("Location of library has already been " - + "set. Please use only one of file, dir or url attributes"); + throw new ValidationException("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/org/apache/ant/antlib/system/Parallel.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Parallel.java index 298be76da..bb21b773c 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Parallel.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Parallel.java @@ -61,7 +61,7 @@ import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.Task; import org.apache.ant.common.antlib.TaskContainer; import org.apache.ant.common.service.ExecService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.Location; /** @@ -143,10 +143,10 @@ public class Parallel extends AbstractTask * Block execution until the specified time or for a specified amount of * milliseconds and if defined, execute the wait status. * - * @exception ExecutionException if any of the nested tasks throws an + * @exception AntException if any of the nested tasks throws an * exception */ - public void execute() throws ExecutionException { + public void execute() throws AntException { TaskThread[] threads = new TaskThread[nestedTasks.size()]; int threadNumber = 0; for (Iterator i = nestedTasks.iterator(); i.hasNext(); threadNumber++) { @@ -181,9 +181,9 @@ public class Parallel extends AbstractTask if (firstException == null) { firstException = t; } - if (t instanceof ExecutionException && + if (t instanceof AntException && firstLocation == Location.UNKNOWN_LOCATION) { - firstLocation = ((ExecutionException) t).getLocation(); + firstLocation = ((AntException) t).getLocation(); } exceptionMessage.append(lSep); exceptionMessage.append(t.getMessage()); @@ -191,13 +191,13 @@ public class Parallel extends AbstractTask } if (numExceptions == 1) { - if (firstException instanceof ExecutionException) { - throw (ExecutionException) firstException; + if (firstException instanceof AntException) { + throw (AntException) firstException; } else { - throw new ExecutionException(firstException); + throw new SystemException(firstException); } } else if (numExceptions > 1) { - throw new ExecutionException(exceptionMessage.toString(), + throw new SystemException(exceptionMessage.toString(), firstLocation); } } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/PrimitiveConverter.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/PrimitiveConverter.java index 1d3fac05d..ca52e3d58 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/PrimitiveConverter.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/PrimitiveConverter.java @@ -54,8 +54,8 @@ package org.apache.ant.antlib.system; import org.apache.ant.common.antlib.AbstractConverter; -import org.apache.ant.common.util.ExecutionException; import org.apache.ant.common.util.PropertyUtils; +import org.apache.ant.common.antlib.ConverterException; /** * A converter to convert to Java's primitie types @@ -72,8 +72,8 @@ public class PrimitiveConverter extends AbstractConverter { */ public Class[] getTypes() { return new Class[] { - Character.class, Character.TYPE, Byte.TYPE, Short.TYPE, - Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, + Character.class, Character.TYPE, Byte.TYPE, Short.TYPE, + Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Boolean.class, Boolean.TYPE}; } @@ -84,10 +84,10 @@ public class PrimitiveConverter extends AbstractConverter { * @param value The value to be converted * @param type the desired type of the converted object * @return the value of the converted object - * @exception ExecutionException if the conversion cannot be made + * @exception ConverterException if the conversion cannot be made */ - public Object convert(String value, Class type) throws ExecutionException { - if (type.equals(Character.class) + public Object convert(String value, Class type) throws ConverterException { + if (type.equals(Character.class) || type.equals(Character.TYPE)) { return new Character(value.charAt(0)); } else if (type.equals(Byte.TYPE)) { @@ -102,12 +102,12 @@ public class PrimitiveConverter extends AbstractConverter { return new Float(value); } else if (type.equals(Double.TYPE)) { return new Double(value); - } else if (type.equals(Boolean.class) + } else if (type.equals(Boolean.class) || type.equals(Boolean.TYPE)) { return new Boolean(PropertyUtils.toBoolean(value)); } - throw new ExecutionException("This converter does not handle " - + type.getName()); + throw new ConverterException("This converter does not handle " + + type.getName()); } } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java index 7a689ea32..2f7e865f0 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ref.java @@ -55,7 +55,7 @@ package org.apache.ant.antlib.system; import java.io.File; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.model.Project; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * A Task to create a project reference. @@ -77,10 +77,10 @@ public class Ref extends SubBuild { * @param context core's context * @param componentType the component type of this component (i.e its * defined name in the build file) - * @exception ExecutionException if we can't access the data service + * @exception AntException if we can't access the data service */ public void init(AntContext context, String componentType) - throws ExecutionException { + throws AntException { super.init(context, componentType); } @@ -109,9 +109,9 @@ public class Ref extends SubBuild { /** * Create the project reference * - * @exception ExecutionException if the project cannot be referenced. + * @exception AntException if the project cannot be referenced. */ - public void execute() throws ExecutionException { + public void execute() throws AntException { Project model = getExecService().parseXMLBuildFile(projectFile); getExecService().createProjectReference(name, model, getProperties()); diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Sequential.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Sequential.java index e2e253813..22458f38a 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Sequential.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Sequential.java @@ -61,7 +61,7 @@ import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.Task; import org.apache.ant.common.antlib.TaskContainer; import org.apache.ant.common.service.ExecService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Implements a single threaded task execution.

@@ -94,10 +94,10 @@ public class Sequential extends AbstractTask /** * Execute all nestedTasks. * - * @exception ExecutionException if any of the nested tasks throws an + * @exception AntException if any of the nested tasks throws an * exception */ - public void execute() throws ExecutionException { + public void execute() throws AntException { AntContext context = getAntContext(); ExecService execService = (ExecService) context.getCoreService(ExecService.class); diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java index a446f808e..5a58d5885 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SubBuild.java @@ -57,9 +57,10 @@ import java.util.Map; import org.apache.ant.common.antlib.AbstractComponent; import org.apache.ant.common.antlib.AbstractTask; import org.apache.ant.common.antlib.AntContext; +import org.apache.ant.common.antlib.ValidationException; import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.ExecService; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Common Base class all tasks that can pass references and property overrides @@ -127,15 +128,15 @@ public abstract class SubBuild extends AbstractTask { /** * Validate this data type instance * - * @exception ExecutionException if either attribute has not been set + * @exception ValidationException if either attribute has not been set */ - public void validateComponent() throws ExecutionException { + public void validateComponent() throws ValidationException { if (name == null) { - throw new ExecutionException("\"name\" attribute of " + throw new ValidationException("\"name\" attribute of " + " must be supplied"); } if (value == null) { - throw new ExecutionException("\"value\" attribute of " + throw new ValidationException("\"value\" attribute of " + " must be supplied"); } } @@ -152,7 +153,7 @@ public abstract class SubBuild extends AbstractTask { /** The id of the reference to be passed */ private String refId; /** The id to be used in the sub-build for this reference */ - private String toId; + private String toRefId; /** @@ -170,8 +171,8 @@ public abstract class SubBuild extends AbstractTask { * * @return the toId value */ - public String getToId() { - return toId; + public String getToRefId() { + return toRefId; } @@ -188,22 +189,22 @@ public abstract class SubBuild extends AbstractTask { /** * Sets the toId of the Reference * - * @param toId the new toId value + * @param toRefId the new toId value */ - public void setToId(String toId) { - this.toId = toId; + public void setToRefId(String toRefId) { + this.toRefId = toRefId; } /** * Validate this data type instance * - * @exception ExecutionException if the refid attribute has not been + * @exception ValidationException if the refid attribute has not been * set */ - public void validateComponent() throws ExecutionException { + public void validateComponent() throws ValidationException { if (refId == null) { - throw new ExecutionException("\"refid\" attribute of " + throw new ValidationException("\"refid\" attribute of " + " must be supplied"); } } @@ -234,17 +235,17 @@ public abstract class SubBuild extends AbstractTask { * Add a reference to be passed * * @param reference the descriptor of the reference to be passed - * @exception ExecutionException if the reference does not reference a + * @exception AntException if the reference does not reference a * valid object */ - public void addReference(Reference reference) throws ExecutionException { + public void addReference(Reference reference) throws AntException { String refId = reference.getRefId(); if (!dataService.isDataValueSet(refId)) { - throw new ExecutionException("RefId \"" + refId + "\" is not set"); + throw new ValidationException("RefId \"" + refId + "\" is not set"); } Object value = dataService.getDataValue(refId); - String toId = reference.getToId(); + String toId = reference.getToRefId(); if (toId == null) { toId = refId; @@ -290,10 +291,10 @@ public abstract class SubBuild extends AbstractTask { * @param context core's context * @param componentType the component type of this component (i.e its * defined name in the build file) - * @exception ExecutionException if we can't access the data service + * @exception AntException if we can't access the data service */ public void init(AntContext context, String componentType) - throws ExecutionException { + throws AntException { super.init(context, componentType); dataService = (DataService) getCoreService(DataService.class); execService = (ExecService) getCoreService(ExecService.class); diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SystemException.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SystemException.java new file mode 100644 index 000000000..c1f5131c8 --- /dev/null +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/SystemException.java @@ -0,0 +1,129 @@ +/* + * 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.util.Location; +import org.apache.ant.common.util.AntException; + +/** + * A System task related exception + * + * @author Conor MacNeill + */ +public class SystemException extends AntException { + /** + * Constructs an exception with the given descriptive message. + * + * @param msg Description of or information about the exception. + */ + public SystemException(String msg) { + super(msg); + } + + /** + * Constructs an exception with the given descriptive message and a + * location in a file. + * + * @param msg Description of or information about the exception. + * @param location Location in the project file where the error occured. + */ + public SystemException(String msg, Location location) { + super(msg, location); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause. + * + * @param msg Description of or information about the exception. + * @param cause Throwable that might have cause this one. + */ + public SystemException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause and a location in a file. + * + * @param msg Description of or information about the exception. + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public SystemException(String msg, Throwable cause, + Location location) { + super(msg, cause, location); + } + + /** + * Constructs an exception with the given exception as a root cause. + * + * @param cause Exception that might have caused this one. + */ + public SystemException(Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the given exception as a root cause and + * a location in a file. + * + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public SystemException(Throwable cause, Location location) { + super(cause, location); + } +} + diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/URLConverter.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/URLConverter.java index b115b253a..3348b7caa 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/URLConverter.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/URLConverter.java @@ -56,10 +56,10 @@ package org.apache.ant.antlib.system; import java.net.URL; import java.net.MalformedURLException; import org.apache.ant.common.antlib.AbstractConverter; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.antlib.ConverterException; /** - * A converter to convert to URLs relative to the project base dir + * A converter to convert to URLs relative to the project base dir * * @author Conor MacNeill */ @@ -82,13 +82,13 @@ public class URLConverter extends AbstractConverter { * @param value The value to be converted * @param type the desired type of the converted object * @return the value of the converted object - * @exception ExecutionException if the conversion cannot be made + * @exception ConverterException if the conversion cannot be made */ - public Object convert(String value, Class type) throws ExecutionException { + public Object convert(String value, Class type) throws ConverterException { try { return new URL(value); } catch (MalformedURLException e) { - throw new ExecutionException(e); + throw new ConverterException(e); } } } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java index c178aff3e..089dea59c 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java @@ -53,7 +53,7 @@ */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.model.AspectValueCollection; @@ -63,19 +63,19 @@ import org.apache.ant.common.model.AspectValueCollection; * @author Conor MacNeill */ public class AbstractAspect implements Aspect { - /** - * The Ant context for this aspect which can be used to access core + /** + * The Ant context for this aspect which can be used to access core * services. */ private AntContext context; - + /** - * Initialise the aspect with a context. + * Initialise the aspect with a context. * * @param context the aspect's context - * @exception ExecutionException if the aspect cannot be initialised + * @exception AntException if the aspect cannot be initialised */ - public void init(AntContext context) throws ExecutionException { + public void init(AntContext context) throws AntException { this.context = context; } @@ -90,35 +90,35 @@ public class AbstractAspect implements Aspect { /** * This join point is activated before a component is to be created. - * The aspect can return an object to be used rather than the core creating - * the object. + * The aspect can return an object to be used rather than the core creating + * the object. * * @param component the component that has been created. This will be null * unless another aspect has created the component * @param model the Build model that applies to the component * * @return a component to use. - * @exception ExecutionException if the aspect cannot process the component. - */ + * @exception AntException if the aspect cannot process the component. + */ public Object preCreateComponent(Object component, BuildElement model) - throws ExecutionException { + throws AntException { return component; } /** * This join point is activated after a component has been created and * configured. If the aspect wishes, an object can be returned in place - * of the one created by Ant. + * of the one created by Ant. * * @param component the component that has been created. * @param model the Build model used to create the component. * * @return a replacement for the component if desired. If null is returned * the current component is used. - * @exception ExecutionException if the aspect cannot process the component. - */ - public Object postCreateComponent(Object component, BuildElement model) - throws ExecutionException { + * @exception AntException if the aspect cannot process the component. + */ + public Object postCreateComponent(Object component, BuildElement model) + throws AntException { return component; } @@ -126,20 +126,20 @@ public class AbstractAspect implements Aspect { * This join point is activated just prior to task execution. * * @param task the task being executed. - * @param aspectValues a collection of aspect attribute values for use + * @param aspectValues a collection of aspect attribute values for use * during the task execution - may be null if no aspect values are * provided. - * @return an object which indicates that this aspect wishes to + * @return an object which indicates that this aspect wishes to * be notified after execution has been completed, in which case the obkect * is returned to provide the aspect its context. If this returns null * the aspect's postExecuteTask method will not be invoked. - * @exception ExecutionException if the aspect cannot process the task. + * @exception AntException if the aspect cannot process the task. */ - public Object preExecuteTask(Task task, AspectValueCollection aspectValues) - throws ExecutionException { + public Object preExecuteTask(Task task, AspectValueCollection aspectValues) + throws AntException { return null; } - + /** * This join point is activated after a task has executed. The aspect * may override the task's failure cause by returning a new failure. @@ -167,7 +167,7 @@ public class AbstractAspect implements Aspect { } /** - * This point is activated when the task is to receive error content that + * This point is activated when the task is to receive error content that * has been sent to error stream and redirected into the task. * * @param context the context the aspect provided in preExecuteTask. @@ -178,5 +178,15 @@ public class AbstractAspect implements Aspect { public String taskError(Object context, String line) { return line; } + + /** + * Log a message as a build event + * + * @param message the message to be logged + * @param level the priority level of the message + */ + protected void log(String message, int level) { + context.log(message, level); + } } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java index 1afc96009..23184905c 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java @@ -53,7 +53,7 @@ */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Abstract implementation of the ExecutionComponent @@ -96,10 +96,10 @@ public abstract class AbstractComponent implements ExecutionComponent { * * @param context the component's context * @param componentType the type of the component - * @exception ExecutionException if initialisation fails + * @exception AntException if initialisation fails */ public void init(AntContext context, String componentType) - throws ExecutionException { + throws AntException { this.context = context; this.componentType = componentType; } @@ -109,9 +109,9 @@ public abstract class AbstractComponent implements ExecutionComponent { * configured from its build model. The element may perform validation * of its configuration * - * @exception ExecutionException if validation fails + * @exception ValidationException if validation fails */ - public void validateComponent() throws ExecutionException { + public void validateComponent() throws ValidationException { // no validation by default } @@ -121,11 +121,11 @@ public abstract class AbstractComponent implements ExecutionComponent { * @param serviceClass the required interface of which an instance is * required * @return the core's instance of the requested service - * @exception ExecutionException if the core does not support the + * @exception AntException if the core does not support the * requested service */ protected Object getCoreService(Class serviceClass) - throws ExecutionException { + throws AntException { return context.getCoreService(serviceClass); } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java index 2703dab70..ea1c8e043 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java @@ -53,7 +53,7 @@ */ package org.apache.ant.common.antlib; import org.apache.ant.common.event.MessageLevel; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Abstract implementation of the Task interface @@ -90,9 +90,9 @@ public abstract class AbstractTask extends AbstractComponent implements Task { * directly or indirectly. * * @param line The line of content produce by the task - * @exception ExecutionException if the output cannot be handled. + * @exception AntException if the output cannot be handled. */ - public void handleSystemOut(String line) throws ExecutionException { + public void handleSystemOut(String line) throws AntException { // default behaviout is to log at INFO level log(line, MessageLevel.MSG_INFO); } @@ -104,9 +104,9 @@ public abstract class AbstractTask extends AbstractComponent implements Task { * System.err, directly or indirectly. * * @param line The line of error info produce by the task - * @exception ExecutionException if the output cannot be handled. + * @exception AntException if the output cannot be handled. */ - public void handleSystemErr(String line) throws ExecutionException { + public void handleSystemErr(String line) throws AntException { // default behaviout is to log at WARN level log(line, MessageLevel.MSG_WARN); } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java index 58946bcce..5f1c0ddd5 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java @@ -52,7 +52,7 @@ * . */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.Location; /** @@ -80,10 +80,10 @@ public interface AntContext { * @param serviceInterfaceClass the class object for the required * interface * @return an instance of the requested interface - * @exception ExecutionException if the core service is not supported + * @exception AntException if the core service is not supported */ Object getCoreService(Class serviceInterfaceClass) - throws ExecutionException; + throws AntException; /** * Gets the location associated with the AntContext 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 aa51713ad..697f7bb69 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 @@ -52,7 +52,7 @@ * . */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * An Ant Library Factory is a class is used to create instances of the @@ -68,9 +68,9 @@ public interface AntLibFactory { * Initialise the factory * * @param context the factory's context - * @exception ExecutionException if the factory cannot be initialized + * @exception AntException if the factory cannot be initialized */ - void init(AntContext context) throws ExecutionException; + void init(AntContext context) throws AntException; /** * Create an instance of the given component class @@ -81,11 +81,11 @@ public interface AntLibFactory { * @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 + * @exception AntException if there is a problem creating the task */ Object createComponent(Class componentClass, String localName) throws InstantiationException, IllegalAccessException, - ExecutionException; + AntException; /** * Create an instance of the given class @@ -95,12 +95,12 @@ public interface AntLibFactory { * @return a instance of the required class * @exception InstantiationException if the class cannot be instantiated * @exception IllegalAccessException if the instance cannot be accessed - * @exception ExecutionException if there is a problem creating the + * @exception AntException if there is a problem creating the * converter */ Object createInstance(Class requiredClass) throws InstantiationException, IllegalAccessException, - ExecutionException; + AntException; /** @@ -108,11 +108,11 @@ public interface AntLibFactory { * create method. * * @param createdElement the element that the component created - * @exception ExecutionException if there is a problem registering the + * @exception AntException if there is a problem registering the * element */ void registerCreatedElement(Object createdElement) - throws ExecutionException; + throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java index fe1a3bdf5..ced0d4562 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java @@ -53,73 +53,73 @@ */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.model.AspectValueCollection; /** - * An aspect is a component which is activated across all task and + * An aspect is a component which is activated across all task and * component operations. It allows a single implmentation to be applied - * to a number of tasks without requiring changes to the task implementations. + * to a number of tasks without requiring changes to the task implementations. * * @author Conor MacNeill */ public interface Aspect { /** - * Initialise the aspect with a context. + * Initialise the aspect with a context. * * @param context the aspect's context - * @exception ExecutionException if the aspect cannot be initialised + * @exception AntException if the aspect cannot be initialised */ void init(AntContext context) - throws ExecutionException; + throws AntException; + - /** * This join point is activated before a component has been created. - * The aspect can return an object to be used rather than the core creating - * the object. + * The aspect can return an object to be used rather than the core creating + * the object. * * @param component the component that has been created. This will be null * unless another aspect has created the component * @param model the Build model that applies to the component * * @return a component to use. - * @exception ExecutionException if the aspect cannot process the component. - */ + * @exception AntException if the aspect cannot process the component. + */ Object preCreateComponent(Object component, BuildElement model) - throws ExecutionException; + throws AntException; /** * This join point is activated after a component has been created and * configured. If the aspect wishes, an object can be returned in place - * of the one created by Ant. + * of the one created by Ant. * * @param component the component that has been created. * @param model the Build model used to create the component. * * @return a component to use - * @exception ExecutionException if the aspect cannot process the component. - */ + * @exception AntException if the aspect cannot process the component. + */ Object postCreateComponent(Object component, BuildElement model) - throws ExecutionException; + throws AntException; /** * This join point is activated just prior to task execution. * * @param task the task being executed. - * @param aspectValues a collection of aspect attribute values for use + * @param aspectValues a collection of aspect attribute values for use * during the task execution - may be null if no aspect values are * provided. - * @return an object which indicates that this aspect wishes to + * @return an object which indicates that this aspect wishes to * be notified after execution has been completed, in which case the obkect * is returned to provide the aspect its context. If this returns null * the aspect's postExecuteTask method will not be invoked. - * @exception ExecutionException if the aspect cannot process the task. + * @exception AntException if the aspect cannot process the task. */ - Object preExecuteTask(Task task, AspectValueCollection aspectValues) - throws ExecutionException; - + Object preExecuteTask(Task task, AspectValueCollection aspectValues) + throws AntException; + /** * This join point is activated after a task has executed. The aspect * may override the task's failure cause by returning a new failure. @@ -143,7 +143,7 @@ public interface Aspect { String taskOutput(Object context, String line); /** - * This point is activated when the task is to receive error content that + * This point is activated when the task is to receive error content that * has been sent to error stream and redirected into the task. * * @param context the context the aspect provided in preExecuteTask. diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AspectException.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AspectException.java new file mode 100644 index 000000000..4912ecb6b --- /dev/null +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AspectException.java @@ -0,0 +1,129 @@ +/* + * 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.common.antlib; + +import org.apache.ant.common.util.Location; +import org.apache.ant.common.util.AntException; + +/** + * An Aspect Exception is used by Aspects to indicate problems + * + * @author Conor MacNeill + */ +public class AspectException extends AntException { + /** + * Constructs an exception with the given descriptive message. + * + * @param msg Description of or information about the exception. + */ + public AspectException(String msg) { + super(msg); + } + + /** + * Constructs an exception with the given descriptive message and a + * location in a file. + * + * @param msg Description of or information about the exception. + * @param location Location in the project file where the error occured. + */ + public AspectException(String msg, Location location) { + super(msg, location); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause. + * + * @param msg Description of or information about the exception. + * @param cause Throwable that might have cause this one. + */ + public AspectException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause and a location in a file. + * + * @param msg Description of or information about the exception. + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public AspectException(String msg, Throwable cause, + Location location) { + super(msg, cause, location); + } + + /** + * Constructs an exception with the given exception as a root cause. + * + * @param cause Exception that might have caused this one. + */ + public AspectException(Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the given exception as a root cause and + * a location in a file. + * + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public AspectException(Throwable cause, Location location) { + super(cause, location); + } +} + diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Converter.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Converter.java index f87c9178e..5dbb794e1 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Converter.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Converter.java @@ -53,8 +53,6 @@ */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; - /** * Convert between a string and a data type * @@ -69,9 +67,9 @@ public interface Converter { * @param value The value to be converted * @param type the desired type of the converted object * @return the value of the converted object - * @exception ExecutionException if the conversion cannot be made + * @exception ConverterException if the conversion cannot be made */ - Object convert(String value, Class type) throws ExecutionException; + Object convert(String value, Class type) throws ConverterException; /** * Initialise the converter. The converter may use the AntContext to @@ -91,12 +89,12 @@ public interface Converter { /** - * This method allows a converter to indicate whether it can create + * This method allows a converter to indicate whether it can create * the given type which is a sub-type of one of the converter's main * types indicated in getTypes. Most converters can return false here. * * @param subType the sub-type - * @return true if this converter can convert a string representation to + * @return true if this converter can convert a string representation to * the given subclass of one of its main class */ boolean canConvertSubType(Class subType); diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ConverterException.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ConverterException.java new file mode 100644 index 000000000..e2775a366 --- /dev/null +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ConverterException.java @@ -0,0 +1,129 @@ +/* + * 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.common.antlib; + +import org.apache.ant.common.util.Location; +import org.apache.ant.common.util.AntException; + +/** + * A Converter Exception indicates a problem converting a value. + * + * @author Conor MacNeill + */ +public class ConverterException extends AntException { + /** + * Constructs an exception with the given descriptive message. + * + * @param msg Description of or information about the exception. + */ + public ConverterException(String msg) { + super(msg); + } + + /** + * Constructs an exception with the given descriptive message and a + * location in a file. + * + * @param msg Description of or information about the exception. + * @param location Location in the project file where the error occured. + */ + public ConverterException(String msg, Location location) { + super(msg, location); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause. + * + * @param msg Description of or information about the exception. + * @param cause Throwable that might have cause this one. + */ + public ConverterException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause and a location in a file. + * + * @param msg Description of or information about the exception. + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public ConverterException(String msg, Throwable cause, + Location location) { + super(msg, cause, location); + } + + /** + * Constructs an exception with the given exception as a root cause. + * + * @param cause Exception that might have caused this one. + */ + public ConverterException(Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the given exception as a root cause and + * a location in a file. + * + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public ConverterException(Throwable cause, Location location) { + super(cause, location); + } +} + diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java index 066c5bfee..1e33271be 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java @@ -52,7 +52,7 @@ * . */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * An execution component is a component from an AntLibrary which is used in @@ -68,20 +68,20 @@ public interface ExecutionComponent { * * @param context the Component's context * @param componentType the type of the component - * @exception ExecutionException if the component cannot be initialised + * @exception AntException if the component cannot be initialised */ void init(AntContext context, String componentType) - throws ExecutionException; + throws AntException; /** * Validate the component. This is called after the element has been * configured from its build model. The element may perform validation * of its configuration * - * @exception ExecutionException if the component is not validly + * @exception ValidationException if the component is not validly * configured */ - void validateComponent() throws ExecutionException; + void validateComponent() throws ValidationException; /** * Get the AntContext associated with this component 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 633091c87..6d54d650f 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 @@ -52,7 +52,7 @@ * . */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Standard Ant Library Factory @@ -74,11 +74,11 @@ public class StandardLibFactory implements AntLibFactory { * @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 + * @exception AntException if there is a problem creating the task */ public Object createComponent(Class componentClass, String localName) throws InstantiationException, IllegalAccessException, - ExecutionException { + AntException { return componentClass.newInstance(); } @@ -86,9 +86,9 @@ public class StandardLibFactory implements AntLibFactory { * Initilaise the factory * * @param context the factory's context - * @exception ExecutionException if the factory cannot be initialized + * @exception AntException if the factory cannot be initialized */ - public void init(AntContext context) throws ExecutionException { + public void init(AntContext context) throws AntException { this.context = context; } @@ -100,12 +100,12 @@ public class StandardLibFactory implements AntLibFactory { * @return a instance of the required class * @exception InstantiationException if the class cannot be instantiated * @exception IllegalAccessException if the instance cannot be accessed - * @exception ExecutionException if there is a problem creating the + * @exception AntException if there is a problem creating the * converter */ public Object createInstance(Class requiredClass) throws InstantiationException, IllegalAccessException, - ExecutionException { + AntException { return requiredClass.newInstance(); } @@ -114,11 +114,11 @@ public class StandardLibFactory implements AntLibFactory { * create method. * * @param createdElement the element that the component created - * @exception ExecutionException if there is a problem registering the + * @exception AntException if there is a problem registering the * element */ public void registerCreatedElement(Object createdElement) - throws ExecutionException { + throws AntException { // do nothing } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java index 67d3462a8..e77ac014e 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java @@ -52,7 +52,7 @@ * . */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * The Task interface defines the methods that a Task must implement. @@ -64,9 +64,9 @@ public interface Task extends ExecutionComponent { /** * Execute the task. * - * @exception ExecutionException if the task has a problem executing. + * @exception AntException if the task has a problem executing. */ - void execute() throws ExecutionException; + void execute() throws AntException; /** * Sets the taskName of the Task @@ -89,9 +89,9 @@ public interface Task extends ExecutionComponent { * directly or indirectly. * * @param line The line of content produce by the task - * @exception ExecutionException if the output cannot be handled. + * @exception AntException if the output cannot be handled. */ - void handleSystemOut(String line) throws ExecutionException; + void handleSystemOut(String line) throws AntException; /** * Handle error information produced by the task. When a task prints to @@ -100,8 +100,8 @@ public interface Task extends ExecutionComponent { * System.err, directly or indirectly. * * @param line The line of error info produce by the task - * @exception ExecutionException if the output cannot be handled. + * @exception AntException if the output cannot be handled. */ - void handleSystemErr(String line) throws ExecutionException; + void handleSystemErr(String line) throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java index 06cdaf641..914e0a44e 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java @@ -52,7 +52,7 @@ * . */ package org.apache.ant.common.antlib; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * A TaskContainer is an object which can contain and manage ExecutionTasks. @@ -65,8 +65,8 @@ public interface TaskContainer { * Add a task to the container. * * @param task the task tobe added - * @exception ExecutionException if the container cannot add the task + * @exception AntException if the container cannot add the task */ - void addNestedTask(Task task) throws ExecutionException; + void addNestedTask(Task task) throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ValidationException.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ValidationException.java new file mode 100644 index 000000000..ffbcc8324 --- /dev/null +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ValidationException.java @@ -0,0 +1,130 @@ +/* + * 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.common.antlib; + +import org.apache.ant.common.util.Location; +import org.apache.ant.common.util.AntException; + +/** + * A validation exception is thrown by tasks when they are not configured + * correctly + * + * @author Conor MacNeill + */ +public class ValidationException extends AntException { + /** + * Constructs an exception with the given descriptive message. + * + * @param msg Description of or information about the exception. + */ + public ValidationException(String msg) { + super(msg); + } + + /** + * Constructs an exception with the given descriptive message and a + * location in a file. + * + * @param msg Description of or information about the exception. + * @param location Location in the project file where the error occured. + */ + public ValidationException(String msg, Location location) { + super(msg, location); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause. + * + * @param msg Description of or information about the exception. + * @param cause Throwable that might have cause this one. + */ + public ValidationException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause and a location in a file. + * + * @param msg Description of or information about the exception. + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public ValidationException(String msg, Throwable cause, + Location location) { + super(msg, cause, location); + } + + /** + * Constructs an exception with the given exception as a root cause. + * + * @param cause Exception that might have caused this one. + */ + public ValidationException(Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the given exception as a root cause and + * a location in a file. + * + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public ValidationException(Throwable cause, Location location) { + super(cause, location); + } +} + diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/cli/BuildLogger.java b/proposal/mutant/src/java/common/org/apache/ant/common/logger/BuildLogger.java similarity index 98% rename from proposal/mutant/src/java/frontend/org/apache/ant/cli/BuildLogger.java rename to proposal/mutant/src/java/common/org/apache/ant/common/logger/BuildLogger.java index 020f2fed6..35fb658e3 100755 --- a/proposal/mutant/src/java/frontend/org/apache/ant/cli/BuildLogger.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/logger/BuildLogger.java @@ -51,7 +51,7 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.cli; +package org.apache.ant.common.logger; import java.io.PrintStream; import org.apache.ant.common.event.BuildListener; diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/cli/DefaultLogger.java b/proposal/mutant/src/java/common/org/apache/ant/common/logger/DefaultLogger.java similarity index 99% rename from proposal/mutant/src/java/frontend/org/apache/ant/cli/DefaultLogger.java rename to proposal/mutant/src/java/common/org/apache/ant/common/logger/DefaultLogger.java index b3a3345df..64283397d 100755 --- a/proposal/mutant/src/java/frontend/org/apache/ant/cli/DefaultLogger.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/logger/DefaultLogger.java @@ -51,7 +51,7 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.cli; +package org.apache.ant.common.logger; import java.io.PrintStream; import org.apache.ant.common.antlib.ExecutionComponent; diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/BuildKey.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/BuildKey.java new file mode 100644 index 000000000..678138ffb --- /dev/null +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/BuildKey.java @@ -0,0 +1,63 @@ +/* + * 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.common.service; + +/** + * Opaque key used to refer to builds setup in the core. + * + * @author Conor MacNeill + */ +public interface BuildKey { +} + 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 c14b5bfb2..556e34b1c 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 @@ -55,7 +55,7 @@ package org.apache.ant.common.service; import java.net.URL; import java.util.Map; import org.apache.ant.common.antlib.AntLibFactory; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** @@ -79,13 +79,11 @@ public interface ComponentService { * @param libLocation the location of the library or the libraries * @param importAll true if all components of the loaded libraries * should be imported - * @param autoImport true if libraries in the Ant namespace should be - * automatically imported. - * @exception ExecutionException if the library or libraries cannot be + * @exception AntException if the library or libraries cannot be * imported. */ - void loadLib(String libLocation, boolean importAll, boolean autoImport) - throws ExecutionException; + void loadLib(URL libLocation, boolean importAll) + throws AntException; /** * Add a library path to the given library. The library path is used in @@ -94,9 +92,9 @@ public interface ComponentService { * @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. + * @exception AntException if the path cannot be used. */ - void addLibPath(String libraryId, URL libPath) throws ExecutionException; + void addLibPath(String libraryId, URL libPath) throws AntException; /** * Define a new type @@ -106,11 +104,11 @@ public interface ComponentService { * 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 + * @exception AntException if the type cannot be defined */ void typedef(AntLibFactory factory, ClassLoader loader, String typeName, String className) - throws ExecutionException; + throws AntException; /** * Experimental - define a new task @@ -120,11 +118,11 @@ public interface ComponentService { * 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 + * @exception AntException if the task cannot be defined */ void taskdef(AntLibFactory factory, ClassLoader loader, String taskName, String className) - throws ExecutionException; + throws AntException; /** @@ -137,18 +135,18 @@ public interface ComponentService { * @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 + * @exception AntException if the component cannot be imported */ void importComponent(String libraryId, String defName, - String alias) throws ExecutionException; + String alias) throws AntException; /** * 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 + * @exception AntException if the library cannot be imported */ - void importLibrary(String libraryId) throws ExecutionException; + void importLibrary(String libraryId) throws AntException; /** * Imports a component defined in another frame. @@ -158,10 +156,10 @@ public interface ComponentService { * @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 + * @exception AntException if the component cannot be imported */ void importFrameComponent(String relativeName, String alias) - throws ExecutionException; + throws AntException; /** * Create a component. The component will have a context but will not be @@ -171,12 +169,12 @@ public interface ComponentService { * @param componentName the name of the component * @return the created component. The return type of this method depends * on the component type. - * @exception ExecutionException if the component cannot be created + * @exception AntException if the component cannot be created */ - Object createComponent(String componentName) throws ExecutionException; + Object createComponent(String componentName) throws AntException; /** - * Create a component given its libraryId and local name within the + * Create a component given its libraryId and local name within the * library. This method is unambiguous in the face of imports, aliases and * taskdefs performed in the build. * @@ -184,11 +182,11 @@ public interface ComponentService { * @param localName the name component within the library. * @return the created component. The return type of this method depends * on the component type. - * @exception ExecutionException if the component cannot be created + * @exception AntException if the component cannot be created */ Object createComponent(String libraryId, String localName) - throws ExecutionException; - + throws AntException; + /** * configure an object with attribtes from the given map * @@ -196,11 +194,11 @@ public interface ComponentService { * @param attributeValues a map containing named attribute values. * @param ignoreUnsupported if this is true, attribute names for which no * setter method exists are ignored. - * @exception ExecutionException if the object does not support an + * @exception AntException if the object does not support an * attribute in the map. */ void configureAttributes(Object object, Map attributeValues, boolean ignoreUnsupported) - throws ExecutionException; + throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java index 6e5cd29d4..e497cef21 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java @@ -54,7 +54,7 @@ package org.apache.ant.common.service; import java.util.Map; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Service interface for Data value manipulation operations provided by the @@ -70,9 +70,9 @@ public interface DataService { * @param valueName the name of the data value * @return the current object associated with the name or null if no * value is currently associated with the name - * @exception ExecutionException if the value cannot be retrieved. + * @exception AntException if the value cannot be retrieved. */ - Object getDataValue(String valueName) throws ExecutionException; + Object getDataValue(String valueName) throws AntException; /** * Indicate if a data value has been set @@ -80,10 +80,10 @@ public interface DataService { * @param name the name of the data value - may contain reference * delimiters * @return true if the value exists - * @exception ExecutionException if the containing frame for the value + * @exception AntException if the containing frame for the value * does not exist */ - boolean isDataValueSet(String name) throws ExecutionException; + boolean isDataValueSet(String name) throws AntException; /** * Set a data value. If an existing data value exists, associated with @@ -91,19 +91,19 @@ public interface DataService { * * @param valueName the name of the data value * @param value the value to be associated with the name - * @exception ExecutionException if the value cannot be set + * @exception AntException if the value cannot be set */ - void setDataValue(String valueName, Object value) throws ExecutionException; + void setDataValue(String valueName, Object value) throws AntException; /** * Set a data value which can be overwritten * * @param valueName the name of the data value * @param value the value to be associated with the name - * @exception ExecutionException if the value cannot be set + * @exception AntException if the value cannot be set */ void setMutableDataValue(String valueName, Object value) - throws ExecutionException; + throws AntException; /** * Replace ${} style constructions in the given value with the string @@ -111,9 +111,9 @@ public interface DataService { * * @param value the string to be scanned for property references. * @return the string with all property references replaced - * @exception ExecutionException if any of the properties do not exist + * @exception AntException if any of the properties do not exist */ - String replacePropertyRefs(String value) throws ExecutionException; + String replacePropertyRefs(String value) throws AntException; /** * Replace ${} style constructions in the given value with the string @@ -123,10 +123,10 @@ public interface DataService { * @param value the string to be scanned for property references. * @param replacementValues the collection of replacement values * @return the string with all property references replaced - * @exception ExecutionException if any of the properties do not exist + * @exception AntException if any of the properties do not exist */ String replacePropertyRefs(String value, Map replacementValues) - throws ExecutionException; + throws AntException; /** * Get all the properties from the frame and any references frames. This diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/EventService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/EventService.java index 1986ff32b..ebb25f9cb 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/EventService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/EventService.java @@ -53,7 +53,7 @@ */ package org.apache.ant.common.service; import org.apache.ant.common.event.BuildListener; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Core service to manage receiving of events by components within Ant. @@ -66,16 +66,16 @@ public interface EventService { * Add a build listener to the current frame * * @param listener the lister which will receive build events - * @exception ExecutionException if the listener cannot be added + * @exception AntException if the listener cannot be added */ - void addBuildListener(BuildListener listener) throws ExecutionException; + void addBuildListener(BuildListener listener) throws AntException; /** * Remove a listener from the current frame * * @param listener the listener to be removed - * @exception ExecutionException if the listener could not be removed + * @exception AntException if the listener could not be removed */ - void removeBuildListener(BuildListener listener) throws ExecutionException; + void removeBuildListener(BuildListener listener) throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java index 35f6bf99c..83beb0ba0 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java @@ -57,8 +57,9 @@ import java.util.List; import java.util.Map; import org.apache.ant.common.antlib.Task; import org.apache.ant.common.model.Project; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.event.BuildListener; /** * The ExecService provides executiuon services to tasks @@ -72,9 +73,9 @@ public interface ExecService { * * @param xmlBuildFile The file containing the XML build description. * @return A Project model for the build. - * @exception ExecutionException if the build cannot be parsed + * @exception AntException if the build cannot be parsed */ - Project parseXMLBuildFile(File xmlBuildFile) throws ExecutionException; + Project parseXMLBuildFile(File xmlBuildFile) throws AntException; /** @@ -84,10 +85,10 @@ public interface ExecService { * referenced. * @param model the project model. * @param initialData the project's initial data load. - * @exception ExecutionException if the project cannot be referenced. + * @exception AntException if the project cannot be referenced. */ - void createProjectReference(String referenceName, Project model, - Map initialData) throws ExecutionException; + void createProjectReference(String referenceName, Project model, + Map initialData) throws AntException; /** @@ -95,22 +96,49 @@ public interface ExecService { * * @param model the project model to be used for the build * @param properties the initiali properties to be used in the build + * @param addListeners true if the current frame's listeners should be + * added to the created Frame * @return a key to the build allowing it to be executed and managed - * @exception ExecutionException if the subbuild cannot be setup + * @exception AntException if the subbuild cannot be setup */ - Object setupBuild(Project model, Map properties) - throws ExecutionException; + BuildKey setupBuild(Project model, Map properties, boolean addListeners) + throws AntException; /** * Setup a sub-build using the current frame's project model * * @param properties the initiali properties to be used in the build + * @param addListeners true if the current frame's listeners should be + * added to the created Frame * @return a key to the build allowing it to be executed and managed - * @exception ExecutionException if the subbuild cannot be setup + * @exception AntException if the subbuild cannot be setup */ - Object setupBuild(Map properties) - throws ExecutionException; + BuildKey setupBuild(Map properties, boolean addListeners) + throws AntException; + + + /** + * Force initialisation of a particular ant library in the context of the + * given subbuild. + * + * @param key the build key. + * @param libraryId the id of the library to be initialized. + * @exception AntException if the build cannot be run + */ + void initializeBuildLibrary(BuildKey key, String libraryId) + throws AntException; + + /** + * Add a listener to a subbuild + * + * @param key the key identifying the build previously setup + * @param listener the listener to add to the build. + * + * @exception AntException if the build cannot be found. + */ + public void addBuildListener(BuildKey key, BuildListener listener) + throws AntException; /** @@ -119,36 +147,46 @@ public interface ExecService { * @param buildKey the buildKey returned previously when the build was * setup * @param targets A list of targets to be run - * @exception ExecutionException if the build cannot be run + * @exception AntException if the build cannot be run */ - void runBuild(Object buildKey, List targets) throws ExecutionException; + void runBuild(BuildKey buildKey, List targets) + throws AntException; + /** + * Release a subbuild that is no longer in use. + * + * @param key the BuildKey identifiying the subbuild. + * + * @exception AntException if the build was not registered. + */ + void releaseBuild(BuildKey key) throws AntException; + /** * execute a task. The task should have already been initialised by the * core * * @param task the task to be executed. - * @exception ExecutionException if there is a problem in execution. + * @exception AntException if there is a problem in execution. */ - void executeTask(Task task) throws ExecutionException; + void executeTask(Task task) throws AntException; /** - * Execute a task with a set of aspect values. Normally aspect values come + * Execute a task with a set of aspect values. Normally aspect values come * from a build model but not all tasks will be created from a build model. - * Some may be created dynamically and configured programatically. This + * Some may be created dynamically and configured programatically. This * method allows aspect values to provided for execution of such tasks since * by their nature, aspect values are not part of the task configuration. * * @param task the task to be executed * @param aspectValues the aspect attribute values. - * @exception ExecutionException if there is an execution problem + * @exception AntException if there is an execution problem */ - void executeTask(Task task, AspectValueCollection aspectValues) - throws ExecutionException; - - + void executeTask(Task task, AspectValueCollection aspectValues) + throws AntException; + + /** * get the name of the project associated with this execution. * @@ -164,6 +202,15 @@ public interface ExecService { */ File getBaseDir(); + /** + * Set the basedir for the current execution + * + * @param baseDir the new base directory for this execution of Ant + * @exception AntException if the base directory cannot be set to the given + * value. + */ + void setBaseDir(File baseDir) throws AntException ; + /** * Handle subbuild output. @@ -171,9 +218,9 @@ public interface ExecService { * @param subbuildKey the core's key for managing the subbuild. * @param line the content produce by the current thread. * @param isErr true if this content is from the thread's error stream. - * @exception ExecutionException if the subbuild cannot be found. + * @exception AntException if the subbuild cannot be found. */ void handleBuildOutput(Object subbuildKey, String line, boolean isErr) - throws ExecutionException; + throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/FileService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/FileService.java index 512bf6917..897a9419e 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/FileService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/FileService.java @@ -54,7 +54,7 @@ package org.apache.ant.common.service; import java.io.File; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Service interface for File manipulation operations provided by the Ant @@ -70,8 +70,8 @@ public interface FileService { * * @param fileName the file name to be resolved. * @return the file resolved to the project's base dir - * @exception ExecutionException if the file cannot be resolved + * @exception AntException if the file cannot be resolved */ - File resolveFile(String fileName) throws ExecutionException; + File resolveFile(String fileName) throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/InputService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/InputService.java index d83b09b09..5bd7d6302 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/InputService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/InputService.java @@ -54,7 +54,7 @@ package org.apache.ant.common.service; import org.apache.ant.common.input.InputRequest; -import org.apache.ant.common.util.ExecutionException; +import org.apache.ant.common.util.AntException; /** * Service interface for input management @@ -67,8 +67,8 @@ public interface InputService { * Handle an input request * * @param request an input request - * @exception ExecutionException if the request cannot be handled + * @exception AntException if the request cannot be handled */ - void handleInput(InputRequest request) throws ExecutionException; + void handleInput(InputRequest request) throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/MagicProperties.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/MagicProperties.java index a026b1e1c..7125f76ef 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/MagicProperties.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/MagicProperties.java @@ -68,5 +68,17 @@ public class MagicProperties { /** This property provides the location of Ant's home directory */ public static final String ANT_HOME = "ant.home"; + + /** The file containing the current project model, if any */ + public static final String ANT_FILE = "ant.file"; + + /** The name of the project */ + public static final String ANT_PROJECT_NAME = "ant.project.name"; + + /** The version of Ant */ + public static final String ANT_VERSION = "ant.version"; + + /** The version of java detected by Ant. */ + public static final String ANT_JAVA_VERSION = "ant.java.version"; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/FileUtils.java b/proposal/mutant/src/java/common/org/apache/ant/common/util/FileUtils.java index 1a79e550d..1d59d6951 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/util/FileUtils.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/FileUtils.java @@ -90,16 +90,16 @@ public class FileUtils { * @param file the "reference" file for relative paths. This instance * must be an absolute file and must not contain "./" or * "../" sequences (same for \ instead of /). If it is - * null, this call is equivalent to + * null, this call is equivalent to * new java.io.File(filename). * @param filename the filename to be resolved * @return an absolute file that doesn't contain "./" or * "../" sequences and uses the correct separator for the * current platform. - * @exception ExecutionException if the file cannot be resolved + * @exception GeneralException if the file cannot be resolved */ public File resolveFile(File file, String filename) - throws ExecutionException { + throws GeneralException { String platformFilename = filename.replace('/', File.separatorChar) .replace('\\', File.separatorChar); @@ -126,7 +126,7 @@ public class FileUtils { String msg = "The file or path you specified (" + filename + ") is invalid relative to " + file.getPath(); - throw new ExecutionException(msg); + throw new GeneralException(msg); } } else if (part.equals(".")) { // Do nothing here @@ -153,11 +153,11 @@ public class FileUtils { * * @param path the path to be normalized * @return the normalized path - * @exception ExecutionException if there is a problem with the path + * @exception GeneralException if there is a problem with the path * @throws NullPointerException if the file path is equal to null. */ public File normalize(String path) - throws NullPointerException, ExecutionException { + throws NullPointerException, GeneralException { String platformPath = path.replace('/', File.separatorChar) .replace('\\', File.separatorChar); @@ -168,7 +168,7 @@ public class FileUtils { Character.isLetter(platformPath.charAt(0)) && platformPath.charAt(1) == ':')) { String msg = path + " is not an absolute path"; - throw new ExecutionException(msg); + throw new GeneralException(msg); } boolean dosWithDrive = false; @@ -223,7 +223,7 @@ public class FileUtils { continue; } else if ("..".equals(thisToken)) { if (s.size() < 2) { - throw new ExecutionException("Cannot resolve path " + throw new GeneralException("Cannot resolve path " + path); } else { s.pop(); diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/ExecutionException.java b/proposal/mutant/src/java/common/org/apache/ant/common/util/GeneralException.java similarity index 88% rename from proposal/mutant/src/java/common/org/apache/ant/common/util/ExecutionException.java rename to proposal/mutant/src/java/common/org/apache/ant/common/util/GeneralException.java index 24d26893d..3cfd4edec 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/util/ExecutionException.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/GeneralException.java @@ -54,23 +54,20 @@ package org.apache.ant.common.util; /** - * An ExecutionException indicates a problem while executing tasks in a - * build + * A General Ant exception. This exception is usually thrown by utility classes. * * @author Conor MacNeill - * @created 20 January 2002 */ -public class ExecutionException extends AntException { +public class GeneralException extends AntException { /** * Constructs an exception with the given descriptive message. * * @param msg Description of or information about the exception. */ - public ExecutionException(String msg) { + public GeneralException(String msg) { super(msg); } - /** * Constructs an exception with the given descriptive message and a * location in a file. @@ -78,11 +75,10 @@ public class ExecutionException extends AntException { * @param msg Description of or information about the exception. * @param location Location in the project file where the error occured. */ - public ExecutionException(String msg, Location location) { + public GeneralException(String msg, Location location) { super(msg, location); } - /** * Constructs an exception with the given message and exception as a * root cause. @@ -90,11 +86,10 @@ public class ExecutionException extends AntException { * @param msg Description of or information about the exception. * @param cause Throwable that might have cause this one. */ - public ExecutionException(String msg, Throwable cause) { + public GeneralException(String msg, Throwable cause) { super(msg, cause); } - /** * Constructs an exception with the given message and exception as a * root cause and a location in a file. @@ -103,21 +98,20 @@ public class ExecutionException extends AntException { * @param cause Exception that might have cause this one. * @param location Location in the project file where the error occured. */ - public ExecutionException(String msg, Throwable cause, Location location) { + public GeneralException(String msg, Throwable cause, + Location location) { super(msg, cause, location); } - /** * Constructs an exception with the given exception as a root cause. * * @param cause Exception that might have caused this one. */ - public ExecutionException(Throwable cause) { + public GeneralException(Throwable cause) { super(cause); } - /** * Constructs an exception with the given exception as a root cause and * a location in a file. @@ -125,9 +119,8 @@ public class ExecutionException extends AntException { * @param cause Exception that might have cause this one. * @param location Location in the project file where the error occured. */ - public ExecutionException(Throwable cause, Location location) { + public GeneralException(Throwable cause, Location location) { super(cause, location); } - } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/PropertyUtils.java b/proposal/mutant/src/java/common/org/apache/ant/common/util/PropertyUtils.java index ec2f8557e..cedc5e060 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/util/PropertyUtils.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/PropertyUtils.java @@ -72,12 +72,12 @@ public class PropertyUtils { * @param value the string to be parsed * @param fragments the fragments parsed out of the string * @param propertyRefs the property refs to be replaced - * @exception ExecutionException if there is a problem parsing out the + * @exception GeneralException if there is a problem parsing out the * values */ public static void parsePropertyString(String value, List fragments, List propertyRefs) - throws ExecutionException { + throws GeneralException { int prev = 0; int pos; while ((pos = value.indexOf("$", prev)) >= 0) { @@ -94,7 +94,7 @@ public class PropertyUtils { } else { int endName = value.indexOf('}', pos); if (endName < 0) { - throw new ExecutionException("Syntax error in property: " + throw new GeneralException("Syntax error in property: " + value); } String propertyName = value.substring(pos + 2, endName); diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java index ca11830f7..55b25e5b6 100755 --- a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java +++ b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java @@ -65,18 +65,20 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.ant.antcore.config.AntConfig; -import org.apache.ant.antcore.execution.ExecutionManager; +import org.apache.ant.antcore.execution.Frame; import org.apache.ant.antcore.modelparser.XMLProjectParser; import org.apache.ant.antcore.xml.XMLParseException; import org.apache.ant.common.event.BuildEvent; import org.apache.ant.common.event.BuildListener; import org.apache.ant.common.event.MessageLevel; import org.apache.ant.common.model.Project; -import org.apache.ant.common.util.ConfigException; import org.apache.ant.common.util.DemuxOutputStream; +import org.apache.ant.common.logger.DefaultLogger; +import org.apache.ant.common.logger.BuildLogger; import org.apache.ant.init.InitConfig; import org.apache.ant.init.InitUtils; import org.apache.ant.frontend.FrontendUtils; +import org.apache.ant.frontend.FrontendException; /** * This is the command line front end. It drives the core. @@ -141,34 +143,34 @@ public class Commandline { * Adds a feature to the BuildListeners attribute of the Commandline * object * - * @param execManager The feature to be added to the BuildListeners - * attribute - * @exception ConfigException if the necessary listener instances could + * @param eventSource the build event source to which listeners + * will be added. + * @exception FrontendException if the necessary listener instances could * not be created */ - protected void addBuildListeners(ExecutionManager execManager) - throws ConfigException { + protected void addBuildListeners(Frame eventSource) + throws FrontendException { // Add the default listener - execManager.addBuildListener(logger); + eventSource.addBuildListener(logger); for (Iterator i = listeners.iterator(); i.hasNext();) { String className = (String) i.next(); try { BuildListener listener = (BuildListener) Class.forName(className).newInstance(); - execManager.addBuildListener(listener); + eventSource.addBuildListener(listener); } catch (ClassCastException e) { System.err.println("The specified listener class " + className + " does not implement the Listener interface"); - throw new ConfigException("Unable to instantiate listener " + throw new FrontendException("Unable to instantiate listener " + className, e); } catch (Exception e) { System.err.println("Unable to instantiate specified listener " + "class " + className + " : " + e.getClass().getName()); - throw new ConfigException("Unable to instantiate listener " + throw new FrontendException("Unable to instantiate listener " + className, e); } } @@ -182,15 +184,15 @@ public class Commandline { * be * @param argType the option type * @return the value of the option - * @exception ConfigException if the option cannot be read + * @exception FrontendException if the option cannot be read */ private String getOption(String[] args, int position, String argType) - throws ConfigException { + throws FrontendException { String value = null; try { value = args[position]; } catch (IndexOutOfBoundsException e) { - throw new ConfigException("You must specify a value for the " + throw new FrontendException("You must specify a value for the " + argType + " argument"); } return value; @@ -205,7 +207,7 @@ public class Commandline { */ private void process(String[] args, InitConfig initConfig) { this.initConfig = initConfig; - ExecutionManager executionManager = null; + Frame mainFrame = null; Project project = null; try { parseArguments(args); @@ -213,7 +215,7 @@ public class Commandline { determineBuildFile(); AntConfig config = new AntConfig(); - AntConfig userConfig = + AntConfig userConfig = FrontendUtils.getAntConfig(initConfig.getUserConfigArea()); AntConfig systemConfig = FrontendUtils.getAntConfig(initConfig.getSystemConfigArea()); @@ -227,28 +229,28 @@ public class Commandline { for (Iterator i = configFiles.iterator(); i.hasNext();) { File configFile = (File) i.next(); - AntConfig runConfig + AntConfig runConfig = FrontendUtils.getAntConfigFile(configFile); config.merge(runConfig); } if (!buildFileURL.getProtocol().equals("file") && !config.isRemoteProjectAllowed()) { - throw new ConfigException("Remote Projects are not allowed: " + throw new FrontendException("Remote Projects are not allowed: " + buildFileURL); } project = parseProject(); // create the execution manager to execute the build - executionManager = new ExecutionManager(initConfig, config); + mainFrame = new Frame(initConfig, config); OutputStream demuxOut - = new DemuxOutputStream(executionManager, false); + = new DemuxOutputStream(mainFrame, false); OutputStream demuxErr - = new DemuxOutputStream(executionManager, true); + = new DemuxOutputStream(mainFrame, true); System.setOut(new PrintStream(demuxOut)); System.setErr(new PrintStream(demuxErr)); - addBuildListeners(executionManager); + addBuildListeners(mainFrame); } catch (Throwable e) { if (logger != null) { BuildEvent finishedEvent @@ -261,7 +263,10 @@ public class Commandline { } try { - executionManager.runBuild(project, targets, definedProperties); + mainFrame.setProject(project); + mainFrame.initialize(definedProperties); + + mainFrame.startBuild(targets); System.exit(0); } catch (Throwable t) { System.exit(1); @@ -285,9 +290,9 @@ public class Commandline { * Handle build file argument * * @param url the build file's URL - * @exception ConfigException if the build file location is not valid + * @exception FrontendException if the build file location is not valid */ - private void argBuildFile(String url) throws ConfigException { + private void argBuildFile(String url) throws FrontendException { try { if (url.indexOf(":") == -1) { // We convert any hash characters to their URL escape. @@ -296,7 +301,7 @@ public class Commandline { buildFileURL = new URL(url); } } catch (MalformedURLException e) { - throw new ConfigException("Build file is not valid", e); + throw new FrontendException("Build file is not valid", e); } } @@ -304,15 +309,15 @@ public class Commandline { * Handle the log file option * * @param arg the value of the log file option - * @exception ConfigException if the log file is not writeable + * @exception FrontendException if the log file is not writeable */ - private void argLogFile(String arg) throws ConfigException { + private void argLogFile(String arg) throws FrontendException { 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 " + + throw new FrontendException("Cannot write on the specified log " + "file. Make sure the path exists and " + "you have write permissions.", ioe); } @@ -322,11 +327,11 @@ public class Commandline { * Handle the logger attribute * * @param arg the logger classname - * @exception ConfigException if a logger has already been defined + * @exception FrontendException if a logger has already been defined */ - private void argLogger(String arg) throws ConfigException { + private void argLogger(String arg) throws FrontendException { if (loggerClassname != null) { - throw new ConfigException("Only one logger class may be " + + throw new FrontendException("Only one logger class may be " + "specified."); } loggerClassname = arg; @@ -336,14 +341,14 @@ public class Commandline { /** * Determine the build file to use * - * @exception ConfigException if the build file cannot be found + * @exception FrontendException if the build file cannot be found */ - private void determineBuildFile() throws ConfigException { + private void determineBuildFile() throws FrontendException { if (buildFileURL == null) { - File defaultBuildFile + File defaultBuildFile = new File(FrontendUtils.DEFAULT_BUILD_FILENAME); if (!defaultBuildFile.exists()) { - File ant1BuildFile + File ant1BuildFile = new File(FrontendUtils.DEFAULT_ANT1_FILENAME); if (ant1BuildFile.exists()) { defaultBuildFile = ant1BuildFile; @@ -352,7 +357,7 @@ public class Commandline { try { buildFileURL = InitUtils.getFileURL(defaultBuildFile); } catch (MalformedURLException e) { - throw new ConfigException("Build file is not valid", e); + throw new FrontendException("Build file is not valid", e); } } } @@ -361,11 +366,11 @@ public class Commandline { * Parse the command line arguments. * * @param args the command line arguments - * @exception ConfigException thrown when the command line contains some + * @exception FrontendException thrown when the command line contains some * sort of error. */ private void parseArguments(String[] args) - throws ConfigException { + throws FrontendException { int i = 0; while (i < args.length) { @@ -417,9 +422,9 @@ public class Commandline { * Creates the default build logger for sending build events to the ant * log. * - * @exception ConfigException if the logger cannot be instantiatd + * @exception FrontendException if the logger cannot be instantiatd */ - private void createLogger() throws ConfigException { + private void createLogger() throws FrontendException { if (loggerClassname != null) { try { Class loggerClass = Class.forName(loggerClassname); @@ -428,13 +433,13 @@ public class Commandline { System.err.println("The specified logger class " + loggerClassname + " does not implement the BuildLogger interface"); - throw new ConfigException("Unable to instantiate logger " + throw new FrontendException("Unable to instantiate logger " + loggerClassname, e); } catch (Exception e) { System.err.println("Unable to instantiate specified logger " + "class " + loggerClassname + " : " + e.getClass().getName()); - throw new ConfigException("Unable to instantiate logger " + throw new FrontendException("Unable to instantiate logger " + loggerClassname, e); } } else { diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendException.java b/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendException.java new file mode 100644 index 000000000..54a17024f --- /dev/null +++ b/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendException.java @@ -0,0 +1,129 @@ +/* + * 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.frontend; + +import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.Location; + +/** + * An exception in the frontend set up of an Ant run + * + * @author Conor MacNeill + */ +public class FrontendException extends AntException { + /** + * Constructs an exception with the given descriptive message. + * + * @param msg Description of or information about the exception. + */ + public FrontendException(String msg) { + super(msg); + } + + /** + * Constructs an exception with the given descriptive message and a + * location in a file. + * + * @param msg Description of or information about the exception. + * @param location Location in the project file where the error occured. + */ + public FrontendException(String msg, Location location) { + super(msg, location); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause. + * + * @param msg Description of or information about the exception. + * @param cause Throwable that might have cause this one. + */ + public FrontendException(String msg, Throwable cause) { + super(msg, cause); + } + + /** + * Constructs an exception with the given message and exception as a + * root cause and a location in a file. + * + * @param msg Description of or information about the exception. + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public FrontendException(String msg, Throwable cause, + Location location) { + super(msg, cause, location); + } + + /** + * Constructs an exception with the given exception as a root cause. + * + * @param cause Exception that might have caused this one. + */ + public FrontendException(Throwable cause) { + super(cause); + } + + /** + * Constructs an exception with the given exception as a root cause and + * a location in a file. + * + * @param cause Exception that might have cause this one. + * @param location Location in the project file where the error occured. + */ + public FrontendException(Throwable cause, Location location) { + super(cause, location); + } +} + diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java b/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java index 004eefb83..29c485300 100644 --- a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java +++ b/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java @@ -61,7 +61,6 @@ import org.apache.ant.antcore.config.AntConfig; import org.apache.ant.antcore.config.AntConfigHandler; import org.apache.ant.antcore.xml.ParseContext; import org.apache.ant.antcore.xml.XMLParseException; -import org.apache.ant.common.util.ConfigException; import org.apache.ant.init.InitUtils; /** @@ -84,11 +83,11 @@ public class FrontendUtils { * @param configArea the config area from which the config may be read * @return the AntConfig instance representing the config info read in * from the config area. May be null if the AntConfig is not present - * @exception ConfigException if the URL for the config file cannotbe + * @exception FrontendException if the URL for the config file cannotbe * formed. */ public static AntConfig getAntConfig(File configArea) - throws ConfigException { + throws FrontendException { File configFile = new File(configArea, "antconfig.xml"); try { @@ -105,11 +104,11 @@ public class FrontendUtils { * * @param configFile the file containing the XML config * @return the parsed config object - * @exception ConfigException if the config cannot be parsed + * @exception FrontendException if the config cannot be parsed * @exception FileNotFoundException if the file cannot be found. */ public static AntConfig getAntConfigFile(File configFile) - throws ConfigException, FileNotFoundException { + throws FrontendException, FileNotFoundException { try { URL configFileURL = InitUtils.getFileURL(configFile); @@ -120,15 +119,15 @@ public class FrontendUtils { return configHandler.getAntConfig(); } catch (MalformedURLException e) { - throw new ConfigException("Unable to form URL to read config from " - + configFile, e); + throw new FrontendException("Unable to form URL to read " + + "config from " + configFile, e); } catch (XMLParseException e) { if (e.getCause() instanceof FileNotFoundException) { throw (FileNotFoundException) e.getCause(); } - throw new ConfigException("Unable to parse config file from " - + configFile, e); + throw new FrontendException("Unable to parse config file from " + + configFile, e, e.getLocation()); } }