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 c83b64a66..82570ba2e 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
@@ -81,6 +81,7 @@ public class AntLibHandler extends ElementHandler {
/** The extends attribute name */
public final static String ISOLATED_ATTR = "isolated";
+
/** The list of allowed Attributes */
public final static String[] ALLOWED_ATTRIBUTES
= {LIBID_ATTR, HOME_ATTR, REQXML_ATTR, REQTOOLS_ATTR,
@@ -144,12 +145,20 @@ public class AntLibHandler extends ElementHandler {
antLibrarySpec.addDefinition(defnHandler.getDefinitionType(),
defnHandler.getName(), defnHandler.getClassName());
} else if (qualifiedName.equals("converter")) {
- ConverterHandler converterHandler
- = new ConverterHandler();
+ ClassNameHandler converterHandler
+ = new ClassNameHandler();
converterHandler.start(getParseContext(), getXMLReader(),
this, getLocator(), attributes, getElementSource(),
qualifiedName);
antLibrarySpec.addConverter(converterHandler.getClassName());
+ } else if (qualifiedName.equals("factory")) {
+ ClassNameHandler factoryHandler
+ = new ClassNameHandler();
+ factoryHandler.start(getParseContext(), getXMLReader(),
+ this, getLocator(), attributes, getElementSource(),
+ qualifiedName);
+ String factoryClass = factoryHandler.getClassName();
+ antLibrarySpec.setFactory(factoryClass);
}
else {
super.startElement(uri, localName, qualifiedName, attributes);
@@ -179,17 +188,6 @@ public class AntLibHandler extends ElementHandler {
}
- /**
- * Get an attribute as a boolean value
- *
- * @param attributeName the name of the attribute
- * @return the attribute value as a boolean
- */
- private boolean getBooleanAttribute(String attributeName) {
- String value = getAttribute(attributeName);
- return value != null && (value.equalsIgnoreCase("true")
- || value.equalsIgnoreCase("yes"));
- }
}
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
new file mode 100644
index 000000000..0304f2935
--- /dev/null
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java
@@ -0,0 +1,310 @@
+/*
+ * 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.antlib;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.ant.antcore.util.CircularDependencyChecker;
+import org.apache.ant.antcore.util.CircularDependencyException;
+import org.apache.ant.antcore.util.ConfigException;
+import org.apache.ant.antcore.xml.ParseContext;
+import org.apache.ant.antcore.xml.XMLParseException;
+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
+ *
+ * @author Conor MacNeill
+ * @created 29 January 2002
+ */
+public class AntLibManager {
+
+ /** The list of extensions which are examined for ant libraries */
+ public final static String[] ANTLIB_EXTENSIONS
+ = new String[]{".tsk", ".jar", ".zip"};
+
+ /** Flag which indicates whether non-file URLS are used */
+ private boolean remoteAllowed;
+
+ /**
+ * Constructor for the AntLibManager object
+ *
+ * @param remoteAllowed true if remote libraries can be used and
+ * configured
+ */
+ public AntLibManager(boolean remoteAllowed) {
+ this.remoteAllowed = remoteAllowed;
+ }
+
+ /**
+ * Add all the Ant libraries that can be found at the given URL
+ *
+ * @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 ConfigException if the library specs cannot be parsed
+ */
+ public void addAntLibraries(Map librarySpecs, URL libURL)
+ throws MalformedURLException, ConfigException {
+ URL[] libURLs = LoaderUtils.getLocationURLs(libURL, libURL.toString(),
+ ANTLIB_EXTENSIONS);
+
+ 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)) {
+ throw new ConfigException("Found more than one "
+ + "copy of library with id = " + libraryId +
+ " (" + libURLs[i] + ")");
+ }
+ 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 ConfigException("Unable to parse Ant library "
+ + libURLs[i], e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Configures the Ant Libraries. Configuration of an Ant Library
+ * involves resolving any dependencies between libraries and then
+ * 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
+ * @exception ConfigException if a library cannot be configured from the
+ * given specification
+ */
+ public void configLibraries(InitConfig initConfig, Map librarySpecs,
+ Map libraries)
+ throws ConfigException {
+
+ // 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);
+ throw new ConfigException("Ant Library \"" + libraryId
+ + "\" is already loaded from "
+ + currentVersion.getDefinitionURL());
+ }
+ }
+
+ CircularDependencyChecker configuring
+ = new CircularDependencyChecker("configuring Ant libraries");
+ for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext(); ) {
+ String libraryId = (String)i.next();
+ if (!libraries.containsKey(libraryId)) {
+ configLibrary(initConfig, librarySpecs, libraryId,
+ configuring, libraries);
+ }
+ }
+ }
+
+ /**
+ * 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 ConfigException if the libraries cannot be loaded
+ * @exception MalformedURLException if the library's location cannot be
+ * formed
+ */
+ public void loadLib(Map librarySpecs, String libLocationString)
+ throws ConfigException, MalformedURLException {
+
+ File libLocation = new File(libLocationString);
+ if (!libLocation.exists()) {
+ try {
+ URL libLocationURL = new URL(libLocationString);
+ if (!libLocationURL.getProtocol().equals("file")
+ && !remoteAllowed) {
+ throw new ConfigException("The config library "
+ + "location \"" + libLocationString
+ + "\" cannot be used because config does "
+ + "not allow remote libraries");
+ }
+ addAntLibraries(librarySpecs, libLocationURL);
+ } catch (MalformedURLException e) {
+ // XXX
+ }
+ } else {
+ addAntLibraries(librarySpecs, InitUtils.getFileURL(libLocation));
+ }
+ }
+
+ /**
+ * 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
+ * @exception ConfigException if the library cannot be configured.
+ */
+ private void configLibrary(InitConfig initConfig, Map librarySpecs,
+ String libraryId,
+ CircularDependencyChecker configuring,
+ Map libraries)
+ throws ConfigException {
+
+ try {
+ configuring.visitNode(libraryId);
+
+ AntLibrarySpec librarySpec
+ = (AntLibrarySpec)librarySpecs.get(libraryId);
+ String extendsId = librarySpec.getExtendsLibraryId();
+ if (extendsId != null) {
+ if (!libraries.containsKey(extendsId)) {
+ if (!librarySpecs.containsKey(extendsId)) {
+ throw new ConfigException("Could not find library, "
+ + extendsId + ", upon which library "
+ + libraryId + " depends");
+ }
+ configLibrary(initConfig, librarySpecs, extendsId,
+ configuring, libraries);
+ }
+ }
+
+ // now create the library for the specification
+ AntLibrary antLibrary = new AntLibrary(librarySpec);
+
+ // determine the URLs required for this task. These are the
+ // task URL itself, the XML parser URLs if required, the
+ // tools jar URL if required
+ List urlsList = new ArrayList();
+
+ if (librarySpec.getLibraryURL() != null) {
+ urlsList.add(librarySpec.getLibraryURL());
+ }
+ if (librarySpec.isToolsJarRequired()
+ && initConfig.getToolsJarURL() != null) {
+ urlsList.add(initConfig.getToolsJarURL());
+ }
+
+ URL[] parserURLs = initConfig.getParserURLs();
+ if (librarySpec.usesAntXML()) {
+ for (int i = 0; i < parserURLs.length; ++i) {
+ urlsList.add(parserURLs[i]);
+ }
+ }
+
+ for (Iterator i = urlsList.iterator(); i.hasNext(); ) {
+ antLibrary.addLibraryURL((URL)i.next());
+ }
+ if (extendsId != null) {
+ AntLibrary extendsLibrary
+ = (AntLibrary)libraries.get(extendsId);
+ antLibrary.setExtendsLibrary(extendsLibrary);
+ }
+ antLibrary.setParentLoader(initConfig.getCommonLoader());
+ libraries.put(libraryId, antLibrary);
+ configuring.leaveNode(libraryId);
+ } catch (CircularDependencyException e) {
+ throw new ConfigException(e);
+ }
+ }
+
+ /**
+ * Read an Ant library definition from a URL
+ *
+ * @param antlibURL the URL of the library definition
+ * @return the AntLibrary specification read from the library XML
+ * definition
+ * @exception XMLParseException if the library cannot be parsed
+ */
+ private AntLibrarySpec parseLibraryDef(URL antlibURL)
+ throws XMLParseException {
+ ParseContext context = new ParseContext();
+ AntLibHandler libHandler = new AntLibHandler();
+
+ context.parse(antlibURL, "antlib", libHandler);
+
+ return libHandler.getAntLibrarySpec();
+ }
+
+}
+
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 1c742a905..bee388aff 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
@@ -58,6 +58,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.apache.ant.common.antlib.AntLibFactory;
+import org.apache.ant.common.util.ExecutionException;
/**
* This class represents the Ant library.
@@ -77,6 +79,10 @@ public class AntLibrary {
* This name is used when importing tasks from this library
*/
private String libraryId;
+
+ /** THe URL of the antlib.xml library spec which defines this library */
+ private URL definitionURL;
+
/**
* The URLs to use when contructing a classloader for the components in
* this library.
@@ -86,6 +92,9 @@ public class AntLibrary {
/** The list of converter classnames defined in this library */
private List converterClassNames = new ArrayList();
+ /** The class name of this library's factory class, if any */
+ private String factoryClassName;
+
/** The parent classloader to use when contructing classloaders */
private ClassLoader parentLoader;
@@ -110,7 +119,9 @@ public class AntLibrary {
this.libraryId = spec.getLibraryId();
this.definitions = spec.getDefinitions();
this.isolated = spec.isIsolated();
- this.converterClassNames.addAll(spec.getConverterClassNames());
+ this.converterClassNames.addAll(spec.getConverters());
+ this.factoryClassName = spec.getFactory();
+ this.definitionURL = spec.getLibraryURL();
}
/**
@@ -172,6 +183,54 @@ public class AntLibrary {
return converterClassNames.iterator();
}
+ /**
+ * Get the URL to where the library was loaded from
+ *
+ * @return the library's URL
+ */
+ public URL getDefinitionURL() {
+ return definitionURL;
+ }
+
+
+ /**
+ * Gat an instance of a factory object for creating objects in this
+ * library.
+ *
+ * @return an instance of the factory, or null if this library does not
+ * support a factory
+ * @exception ExecutionException if the factory cannot be created
+ */
+ public AntLibFactory getFactory() throws ExecutionException {
+ try {
+ AntLibFactory libFactory = null;
+ if (factoryClassName != null) {
+ Class factoryClass = Class.forName(factoryClassName,
+ true, getClassLoader());
+ libFactory
+ = (AntLibFactory)factoryClass.newInstance();
+ }
+ return libFactory;
+ } catch (ClassNotFoundException e) {
+ throw new ExecutionException("Unable to create factory "
+ + factoryClassName + " for the \"" + libraryId
+ + "\" Ant library", e);
+ } catch (NoClassDefFoundError e) {
+ throw new ExecutionException("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 "
+ + factoryClassName + " for the \"" + libraryId
+ + "\" Ant library", e);
+ } catch (IllegalAccessException e) {
+ throw new ExecutionException("Unable to access factory "
+ + factoryClassName + " for the \"" + libraryId
+ + "\" Ant library", e);
+ }
+ }
+
/**
* Indicate whether this library has any converters defined
*
@@ -190,6 +249,7 @@ public class AntLibrary {
libraryURLs.add(libraryURL);
}
+
/**
* Create classloader which can be used to load the classes of this ant
* library
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 da8afdb5b..f5e8acc4c 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
@@ -53,10 +53,10 @@
*/
package org.apache.ant.antcore.antlib;
import java.net.URL;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Map;
import java.util.List;
-import java.util.ArrayList;
+import java.util.Map;
import org.apache.ant.antcore.util.ConfigException;
/**
@@ -85,6 +85,9 @@ public class AntLibrarySpec {
/** The list of converter classnames defined in this library */
private List converterClassNames = new ArrayList();
+ /** The name of the factory class for this library */
+ private String factoryClassName;
+
/**
* This is the optional id of another Ant library upon which this
* library depends.
@@ -103,6 +106,9 @@ public class AntLibrarySpec {
/** Flag which indicates if tools.jar is required */
private boolean toolsJarRequired = false;
+ /** Flag which indicates that this library is a system library */
+ private boolean systemLibrary = false;
+
/**
* This flag indicates that this task processes XML and wishes to use
* the XML parser packaged with Ant
@@ -118,6 +124,15 @@ public class AntLibrarySpec {
this.extendsLibraryId = extendsLibraryId;
}
+ /**
+ * Sets the name of the factory class of the AntLibrarySpec
+ *
+ * @param className the new factory classname
+ */
+ public void setFactory(String className) {
+ this.factoryClassName = className;
+ }
+
/**
* Indicate that this library requires a separate classloader per task
* instance
@@ -156,7 +171,6 @@ public class AntLibrarySpec {
this.toolsJarRequired = toolsJarRequired;
}
-
/**
* Sets the libraryURL of the AntLibrary
*
@@ -181,10 +195,19 @@ public class AntLibrarySpec {
*
* @return the converter classnames list
*/
- public List getConverterClassNames() {
+ public List getConverters() {
return converterClassNames;
}
+ /**
+ * Gets the factory classname of the AntLibrarySpec
+ *
+ * @return the factory classname
+ */
+ public String getFactory() {
+ return factoryClassName;
+ }
+
/**
* Indicate whether this AntLibrary requires the Sun tools.jar
*
@@ -288,5 +311,6 @@ public class AntLibrarySpec {
definitions.put(name,
new AntLibDefinition(definitionType, name, classname));
}
+
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ConverterHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ClassNameHandler.java
old mode 100755
new mode 100644
similarity index 97%
rename from proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ConverterHandler.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ClassNameHandler.java
index 5b4e5abb9..868b96964
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ConverterHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ClassNameHandler.java
@@ -57,11 +57,11 @@ import org.apache.ant.antcore.xml.ElementHandler;
import org.xml.sax.SAXParseException;
/**
- * Handler for converter definition within an Ant Library
+ * Handler for elements which specify a class
*
* @author Conor MacNeill
*/
-public class ConverterHandler extends ElementHandler {
+public class ClassNameHandler extends ElementHandler {
/** The classname attribute name */
public final static String CLASSNAME_ATTR = "classname";
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 5e877fc21..4c6aa4613 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
@@ -60,8 +60,8 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import org.apache.ant.common.util.PathTokenizer;
import org.apache.ant.antcore.util.ConfigException;
+import org.apache.ant.common.util.PathTokenizer;
import org.apache.ant.init.InitUtils;
/**
@@ -73,7 +73,7 @@ import org.apache.ant.init.InitUtils;
*/
public class AntConfig {
/** The list of additional directories to be searched for Ant libraries */
- private List taskDirLocations = new ArrayList();
+ private List libraryLocations = new ArrayList();
/**
* A list of additional paths for each ant library, indexed on the
@@ -81,13 +81,37 @@ public class AntConfig {
*/
private Map libPaths = new HashMap();
+ /** Indicates if remote libraries may be used */
+ private boolean allowRemoteLibs = false;
+
+ /** Indicates if remote projects may be used */
+ private boolean allowRemoteProjects = false;
+
+ /**
+ * Indicate if the use of remote library's is allowe dby this config.
+ *
+ * @return true if this config allows the use of remote libraries,
+ */
+ public boolean isRemoteLibAllowed() {
+ return allowRemoteLibs;
+ }
+
+ /**
+ * Indicate if this config allows the execution of a remote project
+ *
+ * @return true if remote projects are allowed
+ */
+ public boolean isRemoteProjectAllowed() {
+ return allowRemoteProjects;
+ }
+
/**
- * Get the task dir locations.
+ * Get the additional locations in which to search for Ant Libraries
*
- * @return an iterator over the task dir locations
+ * @return an iterator over the library locations
*/
- public Iterator getTaskDirLocations() {
- return taskDirLocations.iterator();
+ public Iterator getLibraryLocations() {
+ return libraryLocations.iterator();
}
/**
@@ -169,10 +193,10 @@ public class AntConfig {
*/
public void merge(AntConfig otherConfig) {
// merge by
- List currentTaskDirs = taskDirLocations;
- taskDirLocations = new ArrayList();
- taskDirLocations.addAll(otherConfig.taskDirLocations);
- taskDirLocations.addAll(currentTaskDirs);
+ List currentLibraryLocations = libraryLocations;
+ libraryLocations = new ArrayList();
+ libraryLocations.addAll(otherConfig.libraryLocations);
+ libraryLocations.addAll(currentLibraryLocations);
Iterator i = otherConfig.libPaths.keySet().iterator();
while (i.hasNext()) {
@@ -188,11 +212,11 @@ public class AntConfig {
/**
* Add a new task directory to be searched for additional Ant libraries
*
- * @param taskDirLocation the location (can be a file or a URL) where
+ * @param libraryLocation the location (can be a file or a URL) where
* the libraries may be loaded from.
*/
- public void addTaskDir(String taskDirLocation) {
- taskDirLocations.add(taskDirLocation);
+ public void addAntLibraryLocation(String libraryLocation) {
+ libraryLocations.add(libraryLocation);
}
}
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 6b8c12afe..f1b7e2545 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
@@ -105,13 +105,13 @@ public class AntConfigHandler extends ElementHandler {
throws SAXParseException {
try {
- if (qualifiedName.equals("taskdir")) {
- TaskDirHandler taskDirHandler
- = new TaskDirHandler();
- taskDirHandler.start(getParseContext(), getXMLReader(),
+ if (qualifiedName.equals("loadlib")) {
+ LoadLibHandler loadlibHandler
+ = new LoadLibHandler();
+ loadlibHandler.start(getParseContext(), getXMLReader(),
this, getLocator(), attributes, getElementSource(),
qualifiedName);
- config.addTaskDir(taskDirHandler.getTaskDirLocation());
+ config.addAntLibraryLocation(loadlibHandler.getLibLocation());
} else if (qualifiedName.equals("libpath")) {
LibPathHandler libPathHandler
= new LibPathHandler();
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/TaskDirHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/LoadLibHandler.java
old mode 100755
new mode 100644
similarity index 95%
rename from proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/TaskDirHandler.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/LoadLibHandler.java
index 827a88513..3d3f5ff13
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/TaskDirHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/LoadLibHandler.java
@@ -57,12 +57,12 @@ import org.apache.ant.antcore.xml.ElementHandler;
import org.xml.sax.SAXParseException;
/**
- * An XML handler to handle the taskdir element of an AntConfig file.
+ * An XML handler to handle the loadlib element of an AntConfig file.
*
* @author Conor MacNeill
* @created 20 January 2002
*/
-public class TaskDirHandler extends ElementHandler {
+public class LoadLibHandler extends ElementHandler {
/** The location attribute name */
public final static String LOCATION_ATTR = "location";
@@ -71,12 +71,12 @@ public class TaskDirHandler extends ElementHandler {
*
* @return the additional directory to be searched for Ant libraries.
*/
- public String getTaskDirLocation() {
+ public String getLibLocation() {
return getAttribute(LOCATION_ATTR);
}
/**
- * Process the taskdir element
+ * Process the loadlibs element
*
* @param elementName the name of the element
* @exception SAXParseException if there is a problem parsing the
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildEventSupport.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
old mode 100755
new mode 100644
similarity index 97%
rename from proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildEventSupport.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
index a5d6d55c2..4e0a02ee6
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildEventSupport.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
@@ -51,12 +51,14 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.antcore.event;
+package org.apache.ant.antcore.execution;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.ant.antcore.model.ModelElement;
+import org.apache.ant.common.event.BuildListener;
+import org.apache.ant.common.event.BuildEvent;
/**
* BuildEventSupport is used by classes which which to send build events to
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java
index 2a402225c..9b1ad68a9 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ClassIntrospector.java
@@ -103,6 +103,12 @@ public class ClassIntrospector {
&& !args[0].isArray()
&& !args[0].isPrimitive()) {
reflector.addElementMethod(m, getPropertyName(name, "add"));
+ } else if (name.startsWith("create")
+ && name.length() > 6
+ && !returnType.isArray()
+ && !returnType.isPrimitive()
+ && args.length == 0) {
+ reflector.addCreateMethod(m, getPropertyName(name, "create"));
}
}
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionComponentService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionComponentService.java
new file mode 100644
index 000000000..14b0d9db8
--- /dev/null
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionComponentService.java
@@ -0,0 +1,123 @@
+/*
+ * 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.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.ant.antcore.antlib.AntLibManager;
+import org.apache.ant.antcore.util.ConfigException;
+import org.apache.ant.common.service.ComponentService;
+import org.apache.ant.common.util.ExecutionException;
+
+/**
+ * The instance of the ComponentServices made available by the core to the
+ * ant libraries.
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public class ExecutionComponentService implements ComponentService {
+ /** The ExecutionFrame this service instance is working for */
+ private ExecutionFrame frame;
+
+ /** The library manager instance used to configure libraries. */
+ private AntLibManager libManager;
+
+ /**
+ * Constructor
+ *
+ * @param executionFrame the frame containing this context
+ * @param allowRemoteLibs true if remote libraries can be loaded though
+ * this service.
+ */
+ public ExecutionComponentService(ExecutionFrame executionFrame,
+ boolean allowRemoteLibs) {
+ this.frame = executionFrame;
+ libManager = new AntLibManager(allowRemoteLibs);
+ }
+
+ /**
+ * Load a library or set of libraries from a location making them
+ * available for use
+ *
+ * @param libLocation the file or URL of the library location
+ * @param importAll if true all tasks are imported as the library is
+ * loaded
+ * @exception ExecutionException if the library cannot be loaded
+ */
+ public void loadLib(String libLocation, boolean importAll)
+ throws ExecutionException {
+ try {
+ Map librarySpecs = new HashMap();
+ libManager.loadLib(librarySpecs, libLocation);
+ libManager.configLibraries(frame.getInitConfig(), librarySpecs,
+ frame.getAntLibraries());
+
+ if (importAll) {
+ Iterator i = librarySpecs.keySet().iterator();
+ while (i.hasNext()) {
+ String libraryId = (String)i.next();
+ frame.importLibrary(libraryId);
+ }
+ }
+ } catch (MalformedURLException e) {
+ throw new ExecutionException("Unable to load libraries from "
+ + libLocation, e);
+ } catch (ConfigException e) {
+ throw new ExecutionException(e);
+ }
+ }
+}
+
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 9ac6b29bf..6e4c75573 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
@@ -53,12 +53,11 @@
*/
package org.apache.ant.antcore.execution;
import java.io.File;
-import java.net.URL;
-import org.apache.ant.common.context.AntContext;
-import org.apache.ant.common.util.AntException;
-import org.apache.ant.common.util.FileUtils;
-import org.apache.ant.antcore.event.BuildEventSupport;
import org.apache.ant.antcore.model.ModelElement;
+import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.FileUtils;
+import org.apache.ant.common.util.Location;
/**
* This is the core's implementation of the AntContext for all core objects.
@@ -67,9 +66,10 @@ import org.apache.ant.antcore.model.ModelElement;
* @author Conor MacNeill
* @created 20 January 2002
*/
-public class ExecutionContext extends AntContext {
+public class ExecutionContext implements AntContext {
/** The ExecutionFrame containing this context */
- private ExecutionFrame executionFrame;
+ private ExecutionFrame frame;
+
/** the event support instance used to manage build events */
private BuildEventSupport eventSupport;
@@ -79,6 +79,19 @@ public class ExecutionContext extends AntContext {
/** General file utilities */
private FileUtils fileUtils = new FileUtils();
+ /**
+ * Initilaise this context's environment
+ *
+ * @param frame the frame containing this context
+ * @param eventSupport the event support instance used to send build
+ * events
+ */
+ public ExecutionContext(ExecutionFrame frame,
+ BuildEventSupport eventSupport) {
+ this.frame = frame;
+ this.eventSupport = eventSupport;
+ }
+
/**
* Set the model element associated with this context
*
@@ -89,46 +102,52 @@ public class ExecutionContext extends AntContext {
}
/**
- * Initilaise this context's environment
+ * Get an implementation of one of the core's service interfaces
*
- * @param executionFrame the frame containing this context
- * @param eventSupport the event support instance used to send build
- * events
+ * @param serviceInterfaceClass the interface class for which an
+ * implementation is required
+ * @return the core's implementation of the interface.
+ * @exception ExecutionException if there is a problem finding the
+ * interface
*/
- public void initEnvironment(ExecutionFrame executionFrame,
- BuildEventSupport eventSupport) {
- this.executionFrame = executionFrame;
- this.eventSupport = eventSupport;
+ public Object getCoreService(Class serviceInterfaceClass)
+ throws ExecutionException {
+ return frame.getCoreService(serviceInterfaceClass);
}
/**
- * Log a message as a build event
+ * Get the build fiel location with which this context is associated
*
- * @param message the message to be logged
- * @param level the priority level of the message
+ * @return the associated location object.
*/
- public void log(String message, int level) {
- eventSupport.fireMessageLogged(modelElement, message, level);
+ public Location getLocation() {
+ if (modelElement != null) {
+ return modelElement.getLocation();
+ }
+ return Location.UNKNOWN_LOCATION;
}
/**
- * Resolve a file according to the base directory of the project
- * associated with this context
+ * Get the base directory for this execution of this frame
*
- * @param fileName the file name to be resolved.
- * @return the file resolved to the project's base dir
- * @exception AntException if the file cannot be resolved
+ * @return the base directory
*/
- public File resolveFile(String fileName) throws AntException {
- URL baseURL = executionFrame.getBaseURL();
- if (!baseURL.getProtocol().equals("file")) {
- throw new ExecutionException("Cannot resolve name " + fileName
- + " to a file because the project basedir is not a file: "
- + baseURL);
- }
+ public File getBaseDir() {
+ return frame.getBaseDir();
+ }
- return fileUtils.resolveFile(fileUtils.normalize(baseURL.getFile()),
- fileName);
+ /**
+ * Log a message as a build event
+ *
+ * @param message the message to be logged
+ * @param level the priority level of the message
+ */
+ public void log(String message, int level) {
+ ModelElement source = modelElement;
+ if (modelElement == null) {
+ source = frame.getProject();
+ }
+ eventSupport.fireMessageLogged(source, message, level);
}
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionDataService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionDataService.java
new file mode 100644
index 000000000..9bd323952
--- /dev/null
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionDataService.java
@@ -0,0 +1,212 @@
+/*
+ * 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.ArrayList;
+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;
+
+/**
+ * This is the core's implementation of the DataService service interface.
+ * It gives Ant libraries access to property values maintained in the
+ * ExecutionFrame.
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public class ExecutionDataService implements DataService {
+ /** The ExecutionFrame this service instance is working for */
+ private ExecutionFrame frame;
+
+ /**
+ * Constructor
+ *
+ * @param frame the frame containing this context
+ */
+ public ExecutionDataService(ExecutionFrame frame) {
+ this.frame = frame;
+ }
+
+ /**
+ * Set a data value. If an existing data value exists, associated with
+ * the given name, the value will not be changed
+ *
+ * @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
+ */
+ public void setDataValue(String valueName, Object value)
+ throws ExecutionException {
+ frame.setDataValue(valueName, value, false);
+ }
+
+ /**
+ * 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
+ */
+ public void setMutableDataValue(String valueName, Object value)
+ throws ExecutionException {
+ frame.setDataValue(valueName, value, true);
+ }
+
+ /**
+ * Get a data value
+ *
+ * @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.
+ */
+ public Object getDataValue(String valueName) throws ExecutionException {
+ return frame.getDataValue(valueName);
+ }
+
+ /**
+ * Indicate if a data value has been set
+ *
+ * @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
+ * does not exist
+ */
+ public boolean isDataValueSet(String name) throws ExecutionException {
+ return frame.isDataValueSet(name);
+ }
+
+ /**
+ * Replace ${} style constructions in the given value with the string
+ * value of the corresponding data values in the frame
+ *
+ * @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
+ */
+ public String replacePropertyRefs(String value)
+ throws ExecutionException {
+ if (value == null) {
+ return null;
+ }
+
+ List fragments = new ArrayList();
+ List propertyRefs = new ArrayList();
+ PropertyUtils.parsePropertyString(value, fragments, propertyRefs);
+
+ StringBuffer sb = new StringBuffer();
+ Iterator i = fragments.iterator();
+ Iterator j = propertyRefs.iterator();
+ while (i.hasNext()) {
+ String fragment = (String)i.next();
+ if (fragment == null) {
+ String propertyName = (String)j.next();
+ if (!isDataValueSet(propertyName)) {
+ throw new ExecutionException("Property " + propertyName
+ + " has not been set");
+ }
+ fragment = getDataValue(propertyName).toString();
+ }
+ sb.append(fragment);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Replace ${} style constructions in the given value with the string
+ * value of the objects in the given map. Any values which are not found
+ * are left unchanged.
+ *
+ * @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
+ */
+ public String replacePropertyRefs(String value, Map replacementValues)
+ throws ExecutionException {
+ if (value == null) {
+ return null;
+ }
+
+ List fragments = new ArrayList();
+ List propertyRefs = new ArrayList();
+ PropertyUtils.parsePropertyString(value, fragments, propertyRefs);
+
+ StringBuffer sb = new StringBuffer();
+ Iterator i = fragments.iterator();
+ Iterator j = propertyRefs.iterator();
+ while (i.hasNext()) {
+ String fragment = (String)i.next();
+ if (fragment == null) {
+ String propertyName = (String)j.next();
+ if (!replacementValues.containsKey(propertyName)) {
+ fragment = "${" + propertyName + "}";
+ } else {
+ fragment
+ = replacementValues.get(propertyName).toString();
+ }
+ }
+ sb.append(fragment);
+ }
+
+ return sb.toString();
+ }
+
+}
+
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFileService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFileService.java
new file mode 100644
index 000000000..e46503762
--- /dev/null
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFileService.java
@@ -0,0 +1,97 @@
+/*
+ * 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.io.File;
+import org.apache.ant.common.service.FileService;
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.FileUtils;
+
+/**
+ * The core's implementation of the File Service. The File Service is used
+ * by Ant Library components to perform operations on the local file system
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public class ExecutionFileService implements FileService {
+ /** The ExecutionFrame this service instance is working for */
+ private ExecutionFrame executionFrame;
+
+ /** General file utilities */
+ private FileUtils fileUtils = new FileUtils();
+
+ /**
+ * Constructor
+ *
+ * @param executionFrame the frame containing this context
+ */
+ public ExecutionFileService(ExecutionFrame executionFrame) {
+ this.executionFrame = executionFrame;
+ }
+
+ /**
+ * Resolve a file according to the base directory of the project
+ * associated with this context
+ *
+ * @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.
+ */
+ public File resolveFile(String fileName) throws ExecutionException {
+ File base = executionFrame.getBaseDir();
+ return fileUtils.resolveFile(fileUtils.normalize(base.getPath()),
+ fileName);
+ }
+}
+
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java
index c0d029a32..9bfc072a3 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionFrame.java
@@ -52,28 +52,35 @@
* .
*/
package org.apache.ant.antcore.execution;
-import java.net.MalformedURLException;
+import java.io.File;
import java.net.URL;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
-import org.apache.ant.common.converter.Converter;
-import org.apache.ant.common.task.DataType;
-import org.apache.ant.common.task.Task;
-import org.apache.ant.common.task.TaskContainer;
-import org.apache.ant.common.task.TaskException;
-import org.apache.ant.common.util.Location;
import org.apache.ant.antcore.antlib.AntLibDefinition;
import org.apache.ant.antcore.antlib.AntLibrary;
-import org.apache.ant.antcore.event.BuildEventSupport;
-import org.apache.ant.antcore.event.BuildListener;
+import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.antcore.model.BuildElement;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.antcore.model.Target;
import org.apache.ant.antcore.util.ConfigException;
+import org.apache.ant.common.antlib.AntLibFactory;
+import org.apache.ant.common.antlib.Converter;
+import org.apache.ant.common.antlib.ExecutionComponent;
+import org.apache.ant.common.antlib.StandardLibFactory;
+import org.apache.ant.common.antlib.Task;
+import org.apache.ant.common.antlib.TaskContainer;
+import org.apache.ant.common.event.BuildListener;
+import org.apache.ant.common.service.ComponentService;
+import org.apache.ant.common.service.DataService;
+import org.apache.ant.common.service.FileService;
+import org.apache.ant.common.util.AntException;
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.Location;
+import org.apache.ant.common.util.MessageLevel;
+import org.apache.ant.init.InitConfig;
/**
* An ExecutionFrame maintains the state of a project during an execution.
@@ -143,12 +150,15 @@ public class ExecutionFrame {
/** The prefix for library ids that are automatically imported */
public final static String ANT_LIB_PREFIX = "ant.";
- /** the base dir of the project expressed as a URL */
- private URL baseURL;
+ /** the base dir of the project */
+ private File baseDir;
/** The Project that this execution frame is processing */
private Project project = null;
+ /** The factory objects for each library, indexed by the library Id */
+ private Map libFactories = new HashMap();
+
/** The referenced frames corresponding to the referenced projects */
private Map referencedFrames = new HashMap();
@@ -162,8 +172,20 @@ public class ExecutionFrame {
private Map dataValues = new HashMap();
/**
- * The available libraries from which taskdefs, typedefs, etc may be
- * imported
+ * Ant's initialization configuration with information on the location
+ * of Ant and its libraries.
+ */
+ private InitConfig initConfig;
+
+ /**
+ * These are the standard libraries from which taskdefs, typedefs, etc
+ * may be imported.
+ */
+ private Map standardLibs;
+
+ /**
+ * These are AntLibraries which have been loaded in this
+ * ExecutionFrame's build file.
*/
private Map antLibraries;
@@ -179,72 +201,56 @@ public class ExecutionFrame {
*/
private Map converters = new HashMap();
+ /**
+ * The services map is a map of service interface classes to instances
+ * which provide the service.
+ */
+ private Map services = new HashMap();
+
+ /**
+ * The configuration to be used in this execution of Ant. It is formed
+ * from the system, user and any runtime configs.
+ */
+ private AntConfig config;
+
+ /**
+ * The Data Service instance used by the frame for data management
+ */
+ private DataService dataService;
+
/**
* Create an Execution Frame for the given project
*
- * @param antLibraries The libraries of tasks and types available to
+ * @param standardLibs The libraries of tasks and types available to
* this frame
+ * @param config the user config to use for this execution of Ant
+ * @param initConfig Ant's initialisation config
* @exception ConfigException if a component of the library cannot be
* imported
*/
- public ExecutionFrame(Map antLibraries) throws ConfigException {
- this.antLibraries = antLibraries;
-
- // go through the libraries and import all standard ant libraries
- for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) {
- String libraryId = (String)i.next();
- if (libraryId.startsWith(ANT_LIB_PREFIX)) {
- // standard library - import whole library
- importLibrary(libraryId);
- }
- }
- }
+ protected ExecutionFrame(Map standardLibs, InitConfig initConfig,
+ AntConfig config) throws ConfigException {
+ this.standardLibs = standardLibs;
+ this.config = config;
+ this.initConfig = initConfig;
- /**
- * This method will parse a string containing ${value} style property
- * values into two lists. The first list is a collection of text
- * fragments, while the other is a set of string property names. Null
- * entries in the first list indicate a property reference from the
- * second list.
- *
- * @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 getting property
- * values
- */
- public static void parsePropertyString(String value, List fragments,
- List propertyRefs)
- throws ExecutionException {
- int prev = 0;
- int pos;
- while ((pos = value.indexOf("$", prev)) >= 0) {
- if (pos > 0) {
- fragments.add(value.substring(prev, pos));
- }
+ configureServices();
+
+ antLibraries = new HashMap(standardLibs);
- if (pos == (value.length() - 1)) {
- fragments.add("$");
- prev = pos + 1;
- } else if (value.charAt(pos + 1) != '{') {
- fragments.add(value.substring(pos + 1, pos + 2));
- prev = pos + 2;
- } else {
- int endName = value.indexOf('}', pos);
- if (endName < 0) {
- throw new ExecutionException("Syntax error in property: "
- + value);
+ try {
+ // go through the libraries and import all standard ant libraries
+ for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) {
+ String libraryId = (String)i.next();
+ if (libraryId.startsWith(ANT_LIB_PREFIX)) {
+ // standard library - import whole library
+ importLibrary(libraryId);
}
- String propertyName = value.substring(pos + 2, endName);
- fragments.add(null);
- propertyRefs.add(propertyName);
- prev = endName + 1;
}
+ } catch (ExecutionException e) {
+ throw new ConfigException(e);
}
- if (prev < value.length()) {
- fragments.add(value.substring(prev));
- }
}
/**
@@ -261,6 +267,25 @@ public class ExecutionFrame {
return currentLoader;
}
+ /**
+ * Gets the project model this frame is working with
+ *
+ * @return the project model
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Log a message as a build event
+ *
+ * @param message the message to be logged
+ * @param level the priority level of the message
+ */
+ public void log(String message, int level) {
+ eventSupport.fireMessageLogged(project, message, level);
+ }
+
/**
* Sets the Project of the ExecutionFrame
*
@@ -268,13 +293,18 @@ public class ExecutionFrame {
* @exception ConfigException if any required sub-frames cannot be
* created and configured
*/
- public void setProject(Project project) throws ConfigException {
- try {
- this.project = project;
- baseURL = new URL(project.getSourceURL(), project.getBase());
- } catch (MalformedURLException e) {
- throw new ConfigException("Unable to determine project base dir",
- e, project.getLocation());
+ protected void setProject(Project project) throws ConfigException {
+ this.project = project;
+ URL projectURL = project.getSourceURL();
+ if (projectURL.getProtocol().equals("file")) {
+ File projectFile = new File(projectURL.getFile());
+ String base = project.getBase();
+ if (base == null) {
+ base = ".";
+ }
+ baseDir = new File(projectFile.getParentFile(), base);
+ } else {
+ baseDir = new File(".");
}
referencedFrames = new HashMap();
@@ -284,7 +314,7 @@ public class ExecutionFrame {
Project referencedProject
= project.getReferencedProject(referenceName);
ExecutionFrame referencedFrame
- = new ExecutionFrame(antLibraries);
+ = new ExecutionFrame(standardLibs, initConfig, config);
referencedFrame.setProject(referencedProject);
referencedFrames.put(referenceName, referencedFrame);
@@ -296,29 +326,82 @@ public class ExecutionFrame {
}
/**
- * Set a value in this frame or any of its imported frames
+ * Set a value in this frame or any of its imported frames.
*
* @param name the name of the value
* @param value the actual value
+ * @param mutable if true, existing values can be changed
* @exception ExecutionException if the value name is invalid
*/
- public void setDataValue(String name, Object value)
+ protected void setDataValue(String name, Object value, boolean mutable)
throws ExecutionException {
ExecutionFrame frame = getContainingFrame(name);
if (frame == this) {
- dataValues.put(name, value);
+ if (dataValues.containsKey(name) && !mutable) {
+ log("Ignoring oveeride for data value " + name,
+ MessageLevel.MSG_VERBOSE);
+ } else {
+ dataValues.put(name, value);
+ }
} else {
- frame.setDataValue(getNameInFrame(name), value);
+ frame.setDataValue(getNameInFrame(name), value, mutable);
}
}
/**
- * Gets the baseURL of the ExecutionFrame
+ * Get the collection of Ant Libraries defined for this frame
*
- * @return the baseURL value
+ * @return a map of Ant Libraries indexed by thier library Id
*/
- public URL getBaseURL() {
- return baseURL;
+ protected Map getAntLibraries() {
+ return antLibraries;
+ }
+
+ /**
+ * Get the Ant initialization configuration for this frame.
+ *
+ * @return Ant's initialization configuration
+ */
+ protected InitConfig getInitConfig() {
+ return initConfig;
+ }
+
+
+ /**
+ * Get the config instance being used by this frame.
+ *
+ * @return the config associated with this frame.
+ */
+ protected AntConfig getConfig() {
+ return config;
+ }
+
+ /**
+ * Get the core's implementation of the given service interface.
+ *
+ * @param serviceInterfaceClass the service interface for which an
+ * implementation is require
+ * @return the core's implementation of the service interface
+ * @exception ExecutionException if the core does not provide an
+ * implementatin of the requested interface
+ */
+ protected Object getCoreService(Class serviceInterfaceClass)
+ throws ExecutionException {
+ Object service = services.get(serviceInterfaceClass);
+ if (service == null) {
+ throw new ExecutionException("No service of interface class "
+ + serviceInterfaceClass);
+ }
+ return service;
+ }
+
+ /**
+ * Gets the baseDir of the ExecutionFrame
+ *
+ * @return the baseDir value
+ */
+ protected File getBaseDir() {
+ return baseDir;
}
/**
@@ -328,7 +411,7 @@ public class ExecutionFrame {
* @return the ExecutionFrame asscociated with the given reference name
* or null if there is no such project.
*/
- public ExecutionFrame getReferencedFrame(String referenceName) {
+ protected ExecutionFrame getReferencedFrame(String referenceName) {
return (ExecutionFrame)referencedFrames.get(referenceName);
}
@@ -337,7 +420,7 @@ public class ExecutionFrame {
*
* @return an iterator which returns the referenced ExeuctionFrames..
*/
- public Iterator getReferencedFrames() {
+ protected Iterator getReferencedFrames() {
return referencedFrames.values().iterator();
}
@@ -347,7 +430,7 @@ public class ExecutionFrame {
* @param fullname The name of the object
* @return the name of the object within its containing frame
*/
- public String getNameInFrame(String fullname) {
+ protected String getNameInFrame(String fullname) {
int index = fullname.lastIndexOf(Project.REF_DELIMITER);
if (index == -1) {
return fullname;
@@ -363,7 +446,7 @@ public class ExecutionFrame {
* @return the data value fetched from the appropriate frame
* @exception ExecutionException if the value is not defined
*/
- public Object getDataValue(String name) throws ExecutionException {
+ protected Object getDataValue(String name) throws ExecutionException {
ExecutionFrame frame = getContainingFrame(name);
if (frame == this) {
return dataValues.get(name);
@@ -381,9 +464,9 @@ public class ExecutionFrame {
* @exception ExecutionException if the containing frame for the value
* does not exist
*/
- public boolean isDataValueSet(String name) throws ExecutionException {
+ protected boolean isDataValueSet(String name) throws ExecutionException {
ExecutionFrame frame = getContainingFrame(name);
- if (frame == null) {
+ if (frame == this) {
return dataValues.containsKey(name);
} else {
return frame.isDataValueSet(getNameInFrame(name));
@@ -395,7 +478,7 @@ public class ExecutionFrame {
*
* @param listener the listener to be added to the frame
*/
- public void addBuildListener(BuildListener listener) {
+ protected void addBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
ExecutionFrame referencedFrame = (ExecutionFrame)i.next();
referencedFrame.addBuildListener(listener);
@@ -408,7 +491,7 @@ public class ExecutionFrame {
*
* @param listener the listener to be removed
*/
- public void removeBuildListener(BuildListener listener) {
+ protected void removeBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
ExecutionFrame subFrame = (ExecutionFrame)i.next();
subFrame.removeBuildListener(listener);
@@ -422,17 +505,23 @@ public class ExecutionFrame {
* @param targets a list of target names which are to be evaluated
* @exception ExecutionException if there is a problem in the build
*/
- public void runBuild(List targets) throws ExecutionException {
+ protected void runBuild(List targets) throws ExecutionException {
+ System.out.println("Initilizing frame");
initialize();
+ log("Initialized", MessageLevel.MSG_DEBUG);
if (targets.isEmpty()) {
// we just execute the default target if any
String defaultTarget = project.getDefaultTarget();
if (defaultTarget != null) {
+ log("Executing default target: " + defaultTarget,
+ MessageLevel.MSG_DEBUG);
executeTarget(defaultTarget);
}
} else {
for (Iterator i = targets.iterator(); i.hasNext(); ) {
- executeTarget((String)i.next());
+ String targetName = (String)i.next();
+ log("Executing target: " + targetName, MessageLevel.MSG_DEBUG);
+ executeTarget(targetName);
}
}
}
@@ -445,7 +534,7 @@ public class ExecutionFrame {
* @exception ExecutionException if there is a problem executing the
* tasks of the target
*/
- public void executeTarget(String targetName) throws ExecutionException {
+ protected void executeTarget(String targetName) throws ExecutionException {
// to execute a target we must determine its dependencies and
// execute them in order.
@@ -470,7 +559,8 @@ public class ExecutionFrame {
* @exception ExecutionException if there is execution problem while
* executing tasks
*/
- public void executeTasks(Iterator taskIterator) throws ExecutionException {
+ protected void executeTasks(Iterator taskIterator)
+ throws ExecutionException {
while (taskIterator.hasNext()) {
Throwable failureCause = null;
BuildElement model = (BuildElement)taskIterator.next();
@@ -478,8 +568,8 @@ public class ExecutionFrame {
ImportInfo importInfo
= (ImportInfo)definitions.get(model.getType());
if (importInfo == null) {
- throw new ExecutionException("There is no definition for the "
- + model.getType() + " element", model.getLocation());
+ throw new ExecutionException("There is no definition for the <"
+ + model.getType() + "> element", model.getLocation());
}
try {
@@ -491,17 +581,16 @@ public class ExecutionFrame {
= setContextLoader(taskContext.getLoader());
taskContext.execute();
setContextLoader(currentLoader);
- releaseTaskContext(taskContext);
+ taskContext.destroy();
} else {
// typedef
String typeId = model.getAspectValue(ANT_ASPECT, "id");
Object typeInstance = configureType(model.getType(), model);
if (typeId != null) {
- setDataValue(typeId, typeInstance);
+ setDataValue(typeId, typeInstance, true);
}
}
-
- } catch (TaskException te) {
+ } catch (AntException te) {
ExecutionException e
= new ExecutionException(te, te.getLocation());
if (e.getLocation() == null
@@ -528,7 +617,7 @@ public class ExecutionFrame {
* be executed.
* @exception ExecutionException if there is a problem executing tasks
*/
- public void executeTargetTasks(String targetName)
+ protected void executeTargetTasks(String targetName)
throws ExecutionException {
Throwable failureCause = null;
Target target = project.getTarget(targetName);
@@ -537,10 +626,12 @@ public class ExecutionFrame {
eventSupport.fireTargetStarted(target);
executeTasks(taskIterator);
} catch (ExecutionException e) {
+ System.out.println("Exception location is " + e.getLocation());
if (e.getLocation() == null
|| e.getLocation() == Location.UNKNOWN_LOCATION) {
e.setLocation(target.getLocation());
}
+ System.out.println("Exception location is now " + e.getLocation());
failureCause = e;
throw e;
} catch (RuntimeException e) {
@@ -558,49 +649,36 @@ public class ExecutionFrame {
* @exception ExecutionException if the top level tasks of the frame
* failed
*/
- public void initialize() throws ExecutionException {
+ protected void initialize() throws ExecutionException {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
ExecutionFrame referencedFrame = (ExecutionFrame)i.next();
referencedFrame.initialize();
}
-// Iterator taskIterator = project.getTasks();
-// executeTopLevelTasks(taskIterator);
+ Iterator taskIterator = project.getTasks();
+ executeTasks(taskIterator);
}
+
/**
- * Replace ${} style constructions in the given value with the string
- * value of the corresponding data types.
+ * Import a complete library into this frame
*
- * @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
+ * @param libraryId The id of the library to be imported
+ * @exception ExecutionException if the library cannot be imported
*/
- public String replacePropertyRefs(String value) throws ExecutionException {
- if (value == null) {
- return null;
+ protected void importLibrary(String libraryId) throws ExecutionException {
+ AntLibrary library = (AntLibrary)antLibraries.get(libraryId);
+ if (library == null) {
+ throw new ExecutionException("Unable to import library " + libraryId
+ + " as it has not been loaded");
}
-
- List fragments = new ArrayList();
- List propertyRefs = new ArrayList();
- parsePropertyString(value, fragments, propertyRefs);
-
- StringBuffer sb = new StringBuffer();
- Iterator i = fragments.iterator();
- Iterator j = propertyRefs.iterator();
- while (i.hasNext()) {
- String fragment = (String)i.next();
- if (fragment == null) {
- String propertyName = (String)j.next();
- if (!isDataValueSet(propertyName)) {
- throw new ExecutionException("Property " + propertyName
- + " has not been set");
- }
- fragment = getDataValue(propertyName).toString();
- }
- sb.append(fragment);
+ Map libDefs = library.getDefinitions();
+ for (Iterator i = libDefs.keySet().iterator(); i.hasNext(); ) {
+ String defName = (String)i.next();
+ AntLibDefinition libdef
+ = (AntLibDefinition)libDefs.get(defName);
+ definitions.put(defName, new ImportInfo(library, libdef));
}
-
- return sb.toString();
+ addLibraryConverters(library);
}
/**
@@ -649,35 +727,75 @@ public class ExecutionFrame {
return currentFrame;
}
+ /**
+ * Gets the factory object for the given library
+ *
+ * @param antLibrary the library for which the factory instance is
+ * required.
+ * @return the library;s factory object
+ * @exception ExecutionException the factory object for the library
+ * cannot be created.
+ */
+ private AntLibFactory getLibFactory(AntLibrary antLibrary)
+ throws ExecutionException {
+ String libraryId = antLibrary.getLibraryId();
+ if (libFactories.containsKey(libraryId)) {
+ return (AntLibFactory)libFactories.get(libraryId);
+ }
+ AntLibFactory libFactory = antLibrary.getFactory();
+ if (libFactory == null) {
+ libFactory = new StandardLibFactory();
+ }
+ libFactories.put(libraryId, libFactory);
+ libFactory.init(new ExecutionContext(this, eventSupport));
+ return libFactory;
+ }
+
+ /**
+ * Configure the services that the frame makes available to its library
+ * components
+ */
+ private void configureServices() {
+ // create services and make them available in our services map
+ services.put(FileService.class, new ExecutionFileService(this));
+ services.put(ComponentService.class,
+ new ExecutionComponentService(this, config.isRemoteLibAllowed()));
+ dataService = new ExecutionDataService(this);
+ services.put(DataService.class, dataService);
+ }
+
/**
* Add the converters from the given library to those managed by this
* frame.
*
* @param library the library from which the converters are required
- * @exception ConfigException if a converter defined in the library
+ * @exception ExecutionException if a converter defined in the library
* cannot be instantiated
*/
private void addLibraryConverters(AntLibrary library)
- throws ConfigException {
+ throws ExecutionException {
if (!library.hasConverters()) {
return;
}
String className = null;
try {
+ AntLibFactory libFactory = getLibFactory(library);
ClassLoader converterLoader = library.getClassLoader();
for (Iterator i = library.getConverterClassNames(); i.hasNext(); ) {
className = (String)i.next();
Class converterClass
= Class.forName(className, true, converterLoader);
if (!Converter.class.isAssignableFrom(converterClass)) {
- throw new ConfigException("The converter class "
+ throw new ExecutionException("In Ant library \""
+ + library.getLibraryId() + "\" the converter class "
+ converterClass.getName()
+ " does not implement the Converter interface");
}
- Converter converter = (Converter)converterClass.newInstance();
- ExecutionContext context = new ExecutionContext();
- context.initEnvironment(this, eventSupport);
+ Converter converter
+ = libFactory.createConverter(converterClass);
+ ExecutionContext context
+ = new ExecutionContext(this, eventSupport);
converter.init(context);
Class[] converterTypes = converter.getTypes();
for (int j = 0; j < converterTypes.length; ++j) {
@@ -685,16 +803,23 @@ public class ExecutionFrame {
}
}
} catch (ClassNotFoundException e) {
- throw new ConfigException("Converter Class " + className
- + " was not found", e);
+ throw new ExecutionException("In Ant library \""
+ + library.getLibraryId() + "\" converter class "
+ + className + " was not found", e);
} catch (NoClassDefFoundError e) {
- throw new ConfigException("Could not load a dependent class ("
+ throw new ExecutionException("In Ant library \""
+ + library.getLibraryId()
+ + "\" could not load a dependent class ("
+ e.getMessage() + ") for converter " + className);
} catch (InstantiationException e) {
- throw new ConfigException("Unable to instantiate converter class "
+ throw new ExecutionException("In Ant library \""
+ + library.getLibraryId()
+ + "\" unable to instantiate converter class "
+ className, e);
} catch (IllegalAccessException e) {
- throw new ConfigException("Unable to access converter class "
+ throw new ExecutionException("In Ant library \""
+ + library.getLibraryId()
+ + "\" unable to access converter class "
+ className, e);
}
}
@@ -705,10 +830,9 @@ public class ExecutionFrame {
* @param element the object to be configured
* @param model the BuildElement describing the object in the build file
* @exception ExecutionException if the element cannot be configured
- * @exception TaskException if a nested task has a problem
*/
private void configureElement(Object element, BuildElement model)
- throws ExecutionException, TaskException {
+ throws ExecutionException {
Reflector reflector = getReflector(element.getClass());
@@ -716,12 +840,22 @@ public class ExecutionFrame {
for (Iterator i = model.getAttributeNames(); i.hasNext(); ) {
String attributeName = (String)i.next();
String attributeValue = model.getAttributeValue(attributeName);
+ if (!reflector.supportsAttribute(attributeName)) {
+ throw new ExecutionException(model.getType()
+ + " does not support the \"" + attributeName
+ + "\" attribute", model.getLocation());
+ }
reflector.setAttribute(element, attributeName,
- replacePropertyRefs(attributeValue));
+ dataService.replacePropertyRefs(attributeValue));
}
String modelText = model.getText().trim();
if (modelText.length() != 0) {
- reflector.addText(element, replacePropertyRefs(modelText));
+ if (!reflector.supportsText()) {
+ throw new ExecutionException(model.getType()
+ + " does not support content", model.getLocation());
+ }
+ reflector.addText(element,
+ dataService.replacePropertyRefs(modelText));
}
// now do the nested elements
@@ -742,34 +876,71 @@ public class ExecutionFrame {
// method of executing tasks
container.addTask(nestedContext.getTask());
} else {
- Object nestedElement = createNestedElement(reflector, element,
- nestedElementModel);
- reflector.addElement(element, nestedElementName, nestedElement);
+ if (reflector.supportsNestedAdder(nestedElementName)) {
+ addNestedElement(reflector, element, nestedElementModel);
+ } else if (reflector.supportsNestedCreator(nestedElementName)) {
+ createNestedElement(reflector, element, nestedElementModel);
+ } else {
+ throw new ExecutionException(model.getType()
+ + " does not support the \"" + nestedElementName
+ + "\" nested element",
+ nestedElementModel.getLocation());
+ }
}
}
+
+ }
+
+ /**
+ * Create a nested element for the given object according to the model.
+ *
+ * @param reflector the reflector instance of the container object
+ * @param element the container object for which a nested element is
+ * required.
+ * @param model the build model for the nestd element
+ * @exception ExecutionException if the nested element cannot be
+ * created.
+ */
+ private void createNestedElement(Reflector reflector, Object element,
+ BuildElement model)
+ throws ExecutionException {
+ log("The use of create methods is deprecated - class: "
+ + element.getClass().getName(), MessageLevel.MSG_INFO);
+
+ String nestedElementName = model.getType();
+ Object nestedElement
+ = reflector.createElement(element, nestedElementName);
+ if (nestedElement instanceof ExecutionComponent) {
+ ExecutionComponent component = (ExecutionComponent)nestedElement;
+ ExecutionContext context
+ = new ExecutionContext(this, eventSupport);
+ context.setModelElement(model);
+ component.init(context);
+ }
+
+ try {
+ configureElement(nestedElement, model);
+ } catch (ExecutionException e) {
+ e.setLocation(model.getLocation());
+ throw e;
+ }
}
+
/**
- * Create a nested element
+ * Create and add a nested element
*
* @param reflector The reflector instance for the container element
* @param element the container element in which the nested element will
* be created
* @param model the model of the nested element
- * @return a configured nested element
* @exception ExecutionException if the nested element cannot be created
- * @exception TaskException if the nested element has a problem
*/
- private Object createNestedElement(Reflector reflector, Object element,
- BuildElement model)
- throws ExecutionException, TaskException {
+ private void addNestedElement(Reflector reflector, Object element,
+ BuildElement model)
+ throws ExecutionException {
String nestedElementName = model.getType();
- if (!reflector.supportsNestedElement(nestedElementName)) {
- throw new ExecutionException("The element name " + nestedElementName
- + " is not a supported nested element of "
- + element.getClass().getName());
- }
Class nestedType = reflector.getType(nestedElementName);
// is there a polymorph indicator - look in Ant aspects
@@ -800,8 +971,8 @@ public class ExecutionFrame {
model.getLocation());
}
if (typeInstance == null) {
- throw new ExecutionException("The given ant:refid value '"
- + refId + "' is not defined", model.getLocation());
+ throw new ExecutionException("The given ant:refid value '"
+ + refId + "' is not defined", model.getLocation());
}
} else {
// We need to create an instance of the class expected by the nested
@@ -813,7 +984,7 @@ public class ExecutionFrame {
model.getLocation());
}
- typeInstance = createTypeInstance(nestedType, model);
+ typeInstance = createTypeInstance(nestedType, null, model);
}
// is the typeInstance compatible with the type expected
@@ -831,7 +1002,7 @@ public class ExecutionFrame {
model.getLocation());
}
}
- return typeInstance;
+ reflector.addElement(element, nestedElementName, typeInstance);
}
@@ -842,10 +1013,9 @@ public class ExecutionFrame {
* @return an execution context for managing the task
* @exception ExecutionException if there is a problem configuring the
* task
- * @exception TaskException if the task or a nested task has a problem
*/
private TaskContext configureTask(BuildElement model)
- throws ExecutionException, TaskException {
+ throws ExecutionException {
String taskType = model.getType();
ImportInfo taskDefInfo = (ImportInfo)definitions.get(taskType);
@@ -862,7 +1032,9 @@ public class ExecutionFrame {
ClassLoader taskClassLoader = antLibrary.getClassLoader();
Class elementClass
= Class.forName(className, true, taskClassLoader);
- Object element = elementClass.newInstance();
+ AntLibFactory libFactory = getLibFactory(antLibrary);
+ Object element = libFactory.createTaskInstance(elementClass);
+
Task task = null;
if (element instanceof Task) {
// create a Task context for the Task
@@ -873,7 +1045,7 @@ public class ExecutionFrame {
// set the context loader while configuring the element
ClassLoader currentLoader = setContextLoader(taskClassLoader);
- TaskContext taskContext = allocateTaskContext();
+ TaskContext taskContext = new TaskContext(this, eventSupport);
taskContext.init(taskClassLoader, task, model);
configureElement(element, model);
setContextLoader(currentLoader);
@@ -884,7 +1056,8 @@ public class ExecutionFrame {
model.getLocation());
} catch (NoClassDefFoundError e) {
throw new ExecutionException("Could not load a dependent class ("
- + e.getMessage() + ") for task " + taskType);
+ + e.getMessage() + ") for task " + taskType,
+ e, model.getLocation());
} catch (InstantiationException e) {
throw new ExecutionException("Unable to instantiate task class "
+ className + " for task <" + taskType + ">",
@@ -893,9 +1066,13 @@ public class ExecutionFrame {
throw new ExecutionException("Unable to access task class "
+ className + " for task <" + taskType + ">",
e, model.getLocation());
+ } catch (ExecutionException e) {
+ e.setLocation(model.getLocation());
+ throw e;
}
}
+
/**
* Configure a type instance from the given build model. The name given
* may not match the name in the model type value. This allows the
@@ -905,10 +1082,9 @@ public class ExecutionFrame {
* @param model the model describing the type
* @return an instance of the type, configured from the model
* @exception ExecutionException if the type could not be created
- * @exception TaskException there was a problem within the type
*/
private Object configureType(String typeName, BuildElement model)
- throws ExecutionException, TaskException {
+ throws ExecutionException {
ImportInfo typeDefInfo = (ImportInfo)definitions.get(typeName);
if (typeDefInfo == null
|| typeDefInfo.getDefinitionType() != AntLibrary.TYPEDEF) {
@@ -925,7 +1101,9 @@ public class ExecutionFrame {
= Class.forName(className, true, typeClassLoader);
ClassLoader currentLoader = setContextLoader(typeClassLoader);
- Object typeInstance = createTypeInstance(typeClass, model);
+ AntLibFactory libFactory = getLibFactory(antLibrary);
+ Object typeInstance
+ = createTypeInstance(typeClass, libFactory, model);
setContextLoader(currentLoader);
return typeInstance;
@@ -945,22 +1123,30 @@ public class ExecutionFrame {
* @param typeClass the class from which the instance should be created
* @param model the model describing the required configuration of the
* instance
+ * @param libFactory the factory object of the typeClass's Ant library
* @return an instance of the given class appropriately configured
* @exception ExecutionException if there is a problem creating the type
* instance
- * @exception TaskException if there is a problem configuring the type
- * instance.
*/
- private Object createTypeInstance(Class typeClass, BuildElement model)
- throws ExecutionException, TaskException {
+ private Object createTypeInstance(Class typeClass, AntLibFactory libFactory,
+ BuildElement model)
+ throws ExecutionException {
try {
- Object typeInstance = typeClass.newInstance();
- if (typeInstance instanceof DataType) {
- DataType dataType = (DataType)typeInstance;
- TypeContext typeContext = new TypeContext();
- typeContext.initEnvironment(this, eventSupport);
- typeContext.init(dataType, model);
+ Object typeInstance = null;
+ if (libFactory == null) {
+ typeInstance = typeClass.newInstance();
+ } else {
+ typeInstance = libFactory.createTypeInstance(typeClass);
+ }
+
+ if (typeInstance instanceof ExecutionComponent) {
+ ExecutionComponent component = (ExecutionComponent)typeInstance;
+ ExecutionContext context
+ = new ExecutionContext(this, eventSupport);
+ context.setModelElement(model);
+ component.init(context);
}
+
configureElement(typeInstance, model);
return typeInstance;
} catch (InstantiationException e) {
@@ -971,47 +1157,11 @@ public class ExecutionFrame {
throw new ExecutionException("Unable to access type class "
+ typeClass.getName() + " for type <" + model.getType() + ">",
e, model.getLocation());
+ } catch (ExecutionException e) {
+ e.setLocation(model.getLocation());
+ throw e;
}
}
-
- /**
- * Allocate a context for use
- *
- * @return ExecutionContext for use
- */
- private TaskContext allocateTaskContext() {
- TaskContext context = new TaskContext();
- context.initEnvironment(this, eventSupport);
- return context;
- }
-
- /**
- * Release a context. Any associated tasks are destroyed.
- *
- * @param context the cotext to be released
- */
- private void releaseTaskContext(TaskContext context) {
- context.destroy();
- }
-
-
- /**
- * Import a complete library into this frame
- *
- * @param libraryId The id of the library to be imported
- * @exception ConfigException if the library cannot be imported
- */
- private void importLibrary(String libraryId) throws ConfigException {
- AntLibrary library = (AntLibrary)antLibraries.get(libraryId);
- Map libDefs = library.getDefinitions();
- for (Iterator i = libDefs.keySet().iterator(); i.hasNext(); ) {
- String defName = (String)i.next();
- AntLibDefinition libdef
- = (AntLibDefinition)libDefs.get(defName);
- definitions.put(defName, new ImportInfo(library, libdef));
- }
- addLibraryConverters(library);
- }
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java
index 18e07a296..8006d01be 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java
@@ -52,34 +52,20 @@
* .
*/
package org.apache.ant.antcore.execution;
-import java.io.File;
-import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import org.apache.ant.common.util.AntException;
-import org.apache.ant.antcore.antlib.AntLibHandler;
+import org.apache.ant.antcore.antlib.AntLibManager;
import org.apache.ant.antcore.antlib.AntLibrary;
-import org.apache.ant.antcore.antlib.AntLibrarySpec;
import org.apache.ant.antcore.config.AntConfig;
-import org.apache.ant.antcore.config.AntConfigHandler;
-import org.apache.ant.antcore.event.BuildEventSupport;
-import org.apache.ant.antcore.event.BuildListener;
import org.apache.ant.antcore.model.Project;
-import org.apache.ant.antcore.util.CircularDependencyChecker;
-import org.apache.ant.antcore.util.CircularDependencyException;
import org.apache.ant.antcore.util.ConfigException;
-import org.apache.ant.antcore.xml.ParseContext;
-import org.apache.ant.antcore.xml.XMLParseException;
-import org.apache.ant.init.InitUtils;
+import org.apache.ant.common.event.BuildListener;
+import org.apache.ant.common.util.AntException;
import org.apache.ant.init.InitConfig;
-import org.apache.ant.init.LoaderUtils;
/**
* The ExecutionManager is used to manage the execution of a build. The
@@ -100,70 +86,59 @@ public class ExecutionManager {
/** The Execution Frame for the top level project being executed */
private ExecutionFrame 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 ConfigException if there is a problem with one of Ant's
* tasks
*/
- public ExecutionManager(InitConfig initConfig)
+ public ExecutionManager(InitConfig initConfig, AntConfig config)
throws ConfigException {
- Map librarySpecs = new HashMap();
-
- AntConfig userConfig = getAntConfig(initConfig.getUserConfigArea());
- AntConfig systemConfig = getAntConfig(initConfig.getSystemConfigArea());
-
- AntConfig config = systemConfig;
- if (config == null) {
- config = userConfig;
- } else if (userConfig != null) {
- config.merge(userConfig);
- }
+ this.config = config;
+ this.initConfig = initConfig;
+ Map librarySpecs = new HashMap(10);
try {
// start by loading the task libraries
- URL taskBaseURL = new URL(initConfig.getLibraryURL(), "antlibs");
- addAntLibraries(librarySpecs, taskBaseURL);
+ URL standardLibsURL
+ = new URL(initConfig.getLibraryURL(), "antlibs/");
- if (config != null) {
- // Now add in any found in the dirs specified in
- // the config files
- for (Iterator i = config.getTaskDirLocations(); i.hasNext(); ) {
- // try file first
- String taskDirString = (String)i.next();
- File taskDir = new File(taskDirString);
- if (!taskDir.exists()) {
- URL taskDirURL = new URL(taskDirString);
- addAntLibraries(librarySpecs, taskDirURL);
- } else {
- addAntLibraries(librarySpecs,
- InitUtils.getFileURL(taskDir));
- }
- }
- }
+ AntLibManager libManager
+ = new AntLibManager(config.isRemoteLibAllowed());
- configLibraries(initConfig, librarySpecs);
+ libManager.addAntLibraries(librarySpecs, standardLibsURL);
+ libManager.configLibraries(initConfig, librarySpecs, antLibraries);
+ librarySpecs.clear();
+ // add any additional libraries.
if (config != null) {
- // now add any additional library Paths specified by the config
- for (Iterator i = config.getLibraryIds(); i.hasNext(); ) {
- String libraryId = (String)i.next();
- if (antLibraries.containsKey(libraryId)) {
- AntLibrary antLib
- = (AntLibrary)antLibraries.get(libraryId);
- List pathList = config.getLibraryPathList(libraryId);
- for (Iterator j = pathList.iterator(); j.hasNext(); ) {
- URL pathElementURL = (URL)j.next();
- antLib.addLibraryURL(pathElementURL);
- }
- }
+ for (Iterator i = config.getLibraryLocations(); i.hasNext(); ) {
+ // try file first
+ String libLocation = (String)i.next();
+ libManager.loadLib(librarySpecs, libLocation);
}
}
+ libManager.configLibraries(initConfig, librarySpecs, antLibraries);
+
+ addConfigLibPaths();
- mainFrame = new ExecutionFrame(antLibraries);
+ mainFrame = new ExecutionFrame(antLibraries, initConfig, config);
} catch (MalformedURLException e) {
throw new ConfigException("Unable to load Ant libraries", e);
}
@@ -172,8 +147,8 @@ public class ExecutionManager {
/**
* Run a build, executing each of the targets on the given project
*
- * @param project The project model on which to run the build
- * @param targets The list of target names
+ * @param project the project model to be used for the build
+ * @param targets a list of target names to be executed.
*/
public void runBuild(Project project, List targets) {
Throwable buildFailureCause = null;
@@ -215,203 +190,35 @@ public class ExecutionManager {
}
/**
- * Get the AntConfig from the given config area if it is available
+ * Add the library paths from the AntConfig instance to the Ant
+ * Libraries.
*
- * @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
- * formed.
+ * @exception ConfigException if remote libraries are not allowed.
*/
- private AntConfig getAntConfig(URL configArea) throws ConfigException {
- try {
- URL configFileURL = new URL(configArea, "antconfig.xml");
-
- ParseContext context = new ParseContext();
- AntConfigHandler configHandler = new AntConfigHandler();
-
- context.parse(configFileURL, "antconfig", configHandler);
-
- return configHandler.getAntConfig();
- } catch (MalformedURLException e) {
- throw new ConfigException("Unable to form URL to read config from "
- + configArea, e);
- } catch (XMLParseException e) {
- if (!(e.getCause() instanceof FileNotFoundException)) {
- throw new ConfigException("Unable to parse config file from "
- + configArea, e);
- }
- // ignore missing config files
- return null;
- }
- }
-
- /**
- * Add all the Ant libraries that can be found at the given URL
- *
- * @param librarySpecs A map to which additional library specifications
- * are added.
- * @param taskBaseURL the URL from which Ant libraries are to be loaded
- * @exception MalformedURLException if the URL for the individual
- * library components cannot be formed
- * @exception ConfigException if the library specs cannot be parsed
- */
- private void addAntLibraries(Map librarySpecs, URL taskBaseURL)
- throws MalformedURLException, ConfigException {
- URL[] taskURLs = LoaderUtils.getLoaderURLs(taskBaseURL, null,
- new String[]{".tsk", ".jar", ".zip"});
-
- if (taskURLs == null) {
+ private void addConfigLibPaths()
+ throws ConfigException {
+ if (config == null) {
return;
}
- // parse each task library to get its library definition
- for (int i = 0; i < taskURLs.length; ++i) {
- URL libURL = new URL("jar:" + taskURLs[i]
- + "!/META-INF/antlib.xml");
- try {
- AntLibrarySpec antLibrarySpec = parseLibraryDef(libURL);
- if (antLibrarySpec != null) {
- String libraryId = antLibrarySpec.getLibraryId();
- if (librarySpecs.containsKey(libraryId)) {
- throw new ConfigException("Found more than one "
- + "copy of library with id = " + libraryId +
- " (" + taskURLs[i] + ")");
- }
- antLibrarySpec.setLibraryURL(taskURLs[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 ConfigException("Unable to parse Ant library "
- + taskURLs[i], e);
- }
- }
- }
- }
-
- /**
- * Configures the Ant Libraries. Configuration of an Ant Library
- * involves resolving any dependencies between libraries and then
- * creating the class loaders for the library
- *
- * @param initConfig the Ant initialized config
- * @param librarySpecs the loaded specifications of the Ant libraries
- * @exception ConfigException if a library cannot be configured from the
- * given specification
- */
- private void configLibraries(InitConfig initConfig, Map librarySpecs)
- throws ConfigException {
- Set configured = new HashSet();
- CircularDependencyChecker configuring
- = new CircularDependencyChecker("configuring Ant libraries");
- for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext(); ) {
+ // now add any additional library Paths specified by the config
+ for (Iterator i = config.getLibraryIds(); i.hasNext(); ) {
String libraryId = (String)i.next();
- if (!configured.contains(libraryId)) {
- configLibrary(initConfig, librarySpecs, libraryId,
- configured, configuring);
- }
- }
- }
-
- /**
- * 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 configured the set of libraries which have been configured
- * already
- * @param configuring A circualr dependency chcker for library
- * dependencies.
- * @exception ConfigException if the library cannot be configured.
- */
- private void configLibrary(InitConfig initConfig, Map librarySpecs,
- String libraryId, Set configured,
- CircularDependencyChecker configuring)
- throws ConfigException {
-
- try {
-
- configuring.visitNode(libraryId);
-
- AntLibrarySpec librarySpec
- = (AntLibrarySpec)librarySpecs.get(libraryId);
- String extendsId = librarySpec.getExtendsLibraryId();
- if (extendsId != null) {
- if (!configured.contains(extendsId)) {
- if (!librarySpecs.containsKey(extendsId)) {
- throw new ConfigException("Could not find library, "
- + extendsId + ", upon which library "
- + libraryId + " depends");
+ if (antLibraries.containsKey(libraryId)) {
+ AntLibrary antLib
+ = (AntLibrary)antLibraries.get(libraryId);
+ List pathList = config.getLibraryPathList(libraryId);
+ for (Iterator j = pathList.iterator(); j.hasNext(); ) {
+ URL pathElementURL = (URL)j.next();
+ if (!pathElementURL.getProtocol().equals("file")
+ && !config.isRemoteLibAllowed()) {
+ throw new ConfigException("Remote libpaths are not"
+ + " allowed: " + pathElementURL);
}
- configLibrary(initConfig, librarySpecs, extendsId,
- configured, configuring);
+ antLib.addLibraryURL(pathElementURL);
}
}
-
- // now create the library for the specification
- AntLibrary antLibrary = new AntLibrary(librarySpec);
-
- // determine the URLs required for this task. These are the
- // task URL itself, the XML parser URLs if required, the
- // tools jar URL if required
- List urlsList = new ArrayList();
-
- if (librarySpec.getLibraryURL() != null) {
- urlsList.add(librarySpec.getLibraryURL());
- }
- if (librarySpec.isToolsJarRequired()
- && initConfig.getToolsJarURL() != null) {
- urlsList.add(initConfig.getToolsJarURL());
- }
-
- URL[] parserURLs = initConfig.getParserURLs();
- if (librarySpec.usesAntXML()) {
- for (int i = 0; i < parserURLs.length; ++i) {
- urlsList.add(parserURLs[i]);
- }
- }
-
- for (Iterator i = urlsList.iterator(); i.hasNext(); ) {
- antLibrary.addLibraryURL((URL)i.next());
- }
- if (extendsId != null) {
- AntLibrary extendsLibrary
- = (AntLibrary)antLibraries.get(extendsId);
- antLibrary.setExtendsLibrary(extendsLibrary);
- }
- antLibrary.setParentLoader(initConfig.getCommonLoader());
- antLibraries.put(libraryId, antLibrary);
- configuring.leaveNode(libraryId);
- } catch (CircularDependencyException e) {
- throw new ConfigException(e);
}
}
-
-
- /**
- * Read an Ant library definition from a URL
- *
- * @param antlibURL the URL of the library definition
- * @return the AntLibrary specification read from the library XML
- * definition
- * @exception XMLParseException if the library cannot be parsed
- */
- private AntLibrarySpec parseLibraryDef(URL antlibURL)
- throws XMLParseException {
- ParseContext context = new ParseContext();
- AntLibHandler libHandler = new AntLibHandler();
-
- context.parse(antlibURL, "antlib", libHandler);
-
- return libHandler.getAntLibrarySpec();
- }
-
}
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 17168526b..3aa991094 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
@@ -56,10 +56,10 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
-import org.apache.ant.common.converter.ConversionException;
-import org.apache.ant.common.converter.Converter;
-import org.apache.ant.common.task.TaskException;
+import org.apache.ant.common.antlib.Converter;
+import org.apache.ant.common.util.ExecutionException;
/**
* A reflector is used to set attributes and add nested elements to an
@@ -90,12 +90,10 @@ public class Reflector {
* @exception IllegalAccessException if the method cannot be invoked
* @exception ExecutionException if the conversion of the value
* fails
- * @exception ConversionException if the string value cannot be
- * converted to the required type
*/
void set(Object obj, String value)
throws InvocationTargetException, IllegalAccessException,
- ExecutionException, ConversionException;
+ ExecutionException;
}
/**
@@ -120,6 +118,33 @@ public class Reflector {
throws InvocationTargetException, IllegalAccessException;
}
+ /**
+ * Element Creator's a factory method provided by an Ant Library
+ * Component for creating its own nested element instances. These
+ * methods are now deprecated. It is better to use the add style methods
+ * and support polymorphic interfaces.
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+ private interface ElementCreator {
+ /**
+ * Create a nested element object for the given container object
+ *
+ * @param container the object in which the nested element is to be
+ * created.
+ * @return the nested element.
+ * @exception InvocationTargetException if the create method fails
+ * @exception IllegalAccessException if the create method cannot be
+ * accessed
+ * @exception InstantiationException if the nested element instance
+ * cannot be created.
+ */
+ Object create(Object container)
+ throws InvocationTargetException, IllegalAccessException,
+ InstantiationException;
+ }
+
/** The method used to add content to the element */
private Method addTextMethod;
@@ -133,9 +158,12 @@ public class Reflector {
*/
private Map elementTypes = new HashMap();
- /** the list of element adders indexed by their element names */
+ /** the collection of element adders indexed by their element names */
private Map elementAdders = new HashMap();
+ /** the collection of element creators indexed by their element names */
+ private Map elementCreators = new HashMap();
+
/**
* Set an attribute value on an object
*
@@ -143,30 +171,27 @@ public class Reflector {
* @param attributeName the name of the attribute
* @param value the string represenation of the attribute's value
* @exception ExecutionException if the object does not support the
- * attribute
- * @exception TaskException if the object has a problem setting the
- * value
+ * attribute or the object has a problem setting the value
*/
public void setAttribute(Object obj, String attributeName,
String value)
- throws ExecutionException, TaskException {
+ throws ExecutionException {
+ String name = attributeName.toLowerCase();
AttributeSetter as
- = (AttributeSetter)attributeSetters.get(attributeName);
+ = (AttributeSetter)attributeSetters.get(name);
if (as == null) {
- throw new ExecutionException("Class " + obj.getClass().getName() +
- " doesn't support the \"" + attributeName + "\" attribute");
+ throw new ExecutionException("Class " + obj.getClass().getName()
+ + " doesn't support the \"" + attributeName + "\" attribute");
}
try {
as.set(obj, value);
} catch (IllegalAccessException e) {
// impossible as getMethods should only return public methods
throw new ExecutionException(e);
- } catch (ConversionException e) {
- throw new ExecutionException(e);
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
- if (t instanceof TaskException) {
- throw (TaskException)t;
+ if (t instanceof ExecutionException) {
+ throw (ExecutionException)t;
}
throw new ExecutionException(t);
}
@@ -196,12 +221,11 @@ public class Reflector {
*
* @param obj the instance whose content is being provided
* @param text the required content
- * @exception ExecutionException if the object does not support content
- * @exception TaskException if the object has a problem setting the
- * content
+ * @exception ExecutionException if the object does not support
+ * contentor the object has a problem setting the content
*/
public void addText(Object obj, String text)
- throws ExecutionException, TaskException {
+ throws ExecutionException {
if (addTextMethod == null) {
throw new ExecutionException("Class " + obj.getClass().getName() +
@@ -214,8 +238,8 @@ public class Reflector {
throw new ExecutionException(ie);
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
- if (t instanceof TaskException) {
- throw (TaskException)t;
+ if (t instanceof ExecutionException) {
+ throw (ExecutionException)t;
}
throw new ExecutionException(t);
}
@@ -228,40 +252,123 @@ public class Reflector {
* @param elementName the name of the element
* @param value the object to be added - the nested element
* @exception ExecutionException if the object does not support content
- * @exception TaskException if the object has a problem setting the
- * content
+ * or the object has a problem setting the content
*/
public void addElement(Object obj, String elementName, Object value)
- throws ExecutionException, TaskException {
- ElementAdder ea = (ElementAdder)elementAdders.get(elementName);
- if (ea == null) {
- throw new ExecutionException("Class " + obj.getClass().getName() +
- " doesn't support the \"" + elementName + "\" nested element");
+ throws ExecutionException {
+ String name = elementName.toLowerCase();
+ ElementAdder adder = (ElementAdder)elementAdders.get(name);
+ if (adder == null) {
+ throw new ExecutionException("Class " + obj.getClass().getName()
+ + " doesn't support the \"" + elementName
+ + "\" nested element");
}
try {
- ea.add(obj, value);
+ adder.add(obj, value);
} catch (IllegalAccessException ie) {
// impossible as getMethods should only return public methods
throw new ExecutionException(ie);
} catch (InvocationTargetException ite) {
Throwable t = ite.getTargetException();
- if (t instanceof TaskException) {
- throw (TaskException)t;
+ if (t instanceof ExecutionException) {
+ throw (ExecutionException)t;
+ }
+ throw new ExecutionException(t);
+ }
+
+ }
+
+ /**
+ * Create a nested element using the object's element factory method.
+ *
+ * @param container the object in which the nested element is required.
+ * @param elementName the name of the nested element
+ * @return the new instance of the nested element
+ * @exception ExecutionException if the nested element cannot be
+ * created.
+ */
+ public Object createElement(Object container, String elementName)
+ throws ExecutionException {
+
+ ElementCreator creator
+ = (ElementCreator)elementCreators.get(elementName.toLowerCase());
+ if (creator == null) {
+ throw new ExecutionException("Class "
+ + container.getClass().getName()
+ + " doesn't support the \"" + elementName
+ + "\" nested element");
+ }
+
+ try {
+ return creator.create(container);
+ } catch (IllegalAccessException e) {
+ // impossible as getMethods should only return public methods
+ throw new ExecutionException(e);
+ } catch (InstantiationException e) {
+ // impossible as getMethods should only return public methods
+ throw new ExecutionException(e);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ if (t instanceof ExecutionException) {
+ throw (ExecutionException)t;
}
throw new ExecutionException(t);
}
+ }
+ /**
+ * Indicate if the class assocated with this reflector supports the
+ * addition of text content.
+ *
+ * @return true if the class supports an addText method
+ */
+ public boolean supportsText() {
+ return addTextMethod != null;
+ }
+
+ /**
+ * Indicate if the class assocated with this reflector supports the
+ * given attribute
+ *
+ * @param attributeName the name of the attribute
+ * @return true if the given attribute is supported
+ */
+ public boolean supportsAttribute(String attributeName) {
+ return attributeSetters.containsKey(attributeName.toLowerCase());
}
/**
* Determine if the class associated with this reflector supports a
- * particular nested element
+ * particular nested element via a create factory method
+ *
+ * @param elementName the name of the element
+ * @return true if the class supports creation of that element
+ */
+ public boolean supportsNestedCreator(String elementName) {
+ return elementCreators.containsKey(elementName.toLowerCase());
+ }
+
+ /**
+ * Determine if the class associated with this reflector supports a
+ * particular nested element via an add method
*
* @param elementName the name of the element
* @return true if the class supports addition of that element
*/
+ public boolean supportsNestedAdder(String elementName) {
+ return elementAdders.containsKey(elementName.toLowerCase());
+ }
+
+ /**
+ * Determine if the class associated with this reflector supports a
+ * particular nested element
+ *
+ * @param elementName the name of the element
+ * @return true if the class supports the given type of nested element
+ */
public boolean supportsNestedElement(String elementName) {
- return elementAdders.containsKey(elementName);
+ return supportsNestedAdder(elementName)
+ || supportsNestedCreator(elementName);
}
/**
@@ -279,18 +386,13 @@ public class Reflector {
if (converters != null && converters.containsKey(type)) {
// we have a converter to use to convert the String
// value into something the set method expects.
- final Converter converter = (Converter)converters.get(type);
- attributeSetters.put(propertyName,
- new AttributeSetter() {
- public void set(Object obj, String value)
- throws InvocationTargetException, ExecutionException,
- IllegalAccessException, ConversionException {
- Object convertedValue = converter.convert(value, type);
- m.invoke(obj, new Object[]{convertedValue});
- }
- });
- } else if (type.equals(String.class)) {
- attributeSetters.put(propertyName,
+ Converter converter = (Converter)converters.get(type);
+ addConvertingSetter(m, propertyName, converter, type);
+ return;
+ }
+
+ if (type.equals(String.class)) {
+ attributeSetters.put(propertyName.toLowerCase(),
new AttributeSetter() {
public void set(Object parent, String value)
throws InvocationTargetException,
@@ -298,26 +400,45 @@ public class Reflector {
m.invoke(parent, new String[]{value});
}
});
- } else {
- try {
- final Constructor c =
- type.getConstructor(new Class[]{java.lang.String.class});
- attributeSetters.put(propertyName,
- new AttributeSetter() {
- public void set(Object parent, String value)
- throws InvocationTargetException,
- IllegalAccessException, ExecutionException {
- try {
- Object newValue
- = c.newInstance(new String[]{value});
- m.invoke(parent, new Object[]{newValue});
- } catch (InstantiationException ie) {
- throw new ExecutionException(ie);
- }
+ return;
+ }
+
+ try {
+ final Constructor c =
+ type.getConstructor(new Class[]{java.lang.String.class});
+ attributeSetters.put(propertyName.toLowerCase(),
+ new AttributeSetter() {
+ public void set(Object parent, String value)
+ throws InvocationTargetException,
+ IllegalAccessException, ExecutionException {
+ try {
+ Object newValue
+ = c.newInstance(new String[]{value});
+ m.invoke(parent, new Object[]{newValue});
+ } catch (InstantiationException ie) {
+ throw new ExecutionException(ie);
}
- });
- } catch (NoSuchMethodException nme) {
- // ignore
+ }
+ });
+ return;
+ } catch (NoSuchMethodException nme) {
+ // ignore
+ }
+
+ if (converters != null) {
+ // desparate by now - try top find a converter which handles a super
+ // class of this type and which supports subclass instantiation
+ for (Iterator i = converters.keySet().iterator(); i.hasNext(); ) {
+ Class converterType = (Class)i.next();
+ if (converterType.isAssignableFrom(type)) {
+ // could be a candidate
+ Converter converter
+ = (Converter)converters.get(converterType);
+ if (converter.canConvertSubType(type)) {
+ addConvertingSetter(m, propertyName, converter, type);
+ return;
+ }
+ }
}
}
}
@@ -332,7 +453,7 @@ public class Reflector {
public void addElementMethod(final Method m, String elementName) {
final Class type = m.getParameterTypes()[0];
elementTypes.put(elementName, type);
- elementAdders.put(elementName,
+ elementAdders.put(elementName.toLowerCase(),
new ElementAdder() {
public void add(Object container, Object obj)
throws InvocationTargetException, IllegalAccessException {
@@ -340,5 +461,46 @@ public class Reflector {
}
});
}
+
+
+ /**
+ * Add a create factory method.
+ *
+ * @param m the create method
+ * @param elementName the name of the nested element the create method
+ * supports.
+ */
+ public void addCreateMethod(final Method m, String elementName) {
+ elementCreators.put(elementName.toLowerCase(),
+ new ElementCreator() {
+ public Object create(Object container)
+ throws InvocationTargetException, IllegalAccessException {
+ return m.invoke(container, new Object[]{});
+ }
+ });
+ }
+
+ /**
+ * Add an attribute setter with an associated converter
+ *
+ * @param m the attribute setter method
+ * @param propertyName the name of the attribute this method supports
+ * @param converter the converter to be used to construct the value
+ * expected by the method.
+ * @param type the type expected by the method.
+ */
+ private void addConvertingSetter(final Method m, String propertyName,
+ final Converter converter,
+ final Class type) {
+ attributeSetters.put(propertyName.toLowerCase(),
+ new AttributeSetter() {
+ public void set(Object obj, String value)
+ throws InvocationTargetException, ExecutionException,
+ IllegalAccessException {
+ Object convertedValue = converter.convert(value, type);
+ m.invoke(obj, new Object[]{convertedValue});
+ }
+ });
+ }
}
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 2361eaae6..e6737c70d 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
@@ -54,8 +54,8 @@
package org.apache.ant.antcore.execution;
import java.lang.reflect.Method;
-import org.apache.ant.common.task.AbstractTask;
-import org.apache.ant.common.task.TaskException;
+import org.apache.ant.common.antlib.AbstractTask;
+import org.apache.ant.common.util.ExecutionException;
/**
* Use introspection to "adapt" an arbitrary Bean (not extending Task, but
@@ -100,14 +100,13 @@ public class TaskAdapter extends AbstractTask {
* Standard Task execute method. This invokes the execute method of the
* worker instance
*
- * @exception TaskException if there is an exception in the
- * worker's execute method
+ * @exception ExecutionException if the proxied object throws an exception
*/
- public void execute() throws TaskException {
+ public void execute() throws ExecutionException {
try {
executeMethod.invoke(worker, null);
- } catch (Exception ex) {
- throw new TaskException(ex);
+ } catch (Throwable t) {
+ throw new ExecutionException(t);
}
}
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
index f2bcc9643..331299167 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
@@ -52,9 +52,9 @@
* .
*/
package org.apache.ant.antcore.execution;
-import org.apache.ant.common.task.Task;
-import org.apache.ant.common.task.TaskException;
import org.apache.ant.antcore.model.ModelElement;
+import org.apache.ant.common.antlib.Task;
+import org.apache.ant.common.util.ExecutionException;
/**
* This is the core's implementation of the AntContext for Tasks.
*
@@ -73,6 +73,18 @@ public class TaskContext extends ExecutionContext {
*/
private ClassLoader loader;
+ /**
+ * Initilaise this context's environment
+ *
+ * @param frame the frame containing this context
+ * @param eventSupport the event support instance used to send build
+ * events
+ */
+ public TaskContext(ExecutionFrame frame,
+ BuildEventSupport eventSupport) {
+ super(frame, eventSupport);
+ }
+
/**
* Get the task associated with this context
*
@@ -97,8 +109,10 @@ public class TaskContext extends ExecutionContext {
* @param task the task to be manager
* @param loader the classloader
* @param modelElement the model element associated with this context
+ * @exception ExecutionException if the task cannot be initialized
*/
- public void init(ClassLoader loader, Task task, ModelElement modelElement) {
+ public void init(ClassLoader loader, Task task, ModelElement modelElement)
+ throws ExecutionException {
this.task = task;
this.loader = loader;
setModelElement(modelElement);
@@ -108,9 +122,9 @@ public class TaskContext extends ExecutionContext {
/**
* execute this context's task
*
- * @exception TaskException if the task cannot execute properly
+ * @exception ExecutionException if there is a problem executing the task
*/
- public void execute() throws TaskException {
+ public void execute() throws ExecutionException {
task.execute();
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/Project.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/Project.java
index a173f7700..1516384be 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/Project.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/Project.java
@@ -373,11 +373,6 @@ public class Project extends ModelElement {
* @exception ModelException if the element is invalid
*/
public void validate(String globalName) throws ModelException {
- if (defaultTarget == null) {
- throw new ModelException("Project must have a default "
- + "attribute", getLocation());
- }
-
Set keys = referencedProjects.keySet();
for (Iterator i = keys.iterator(); i.hasNext(); ) {
String refName = (String)i.next();
@@ -500,7 +495,6 @@ public class Project extends ModelElement {
if (flattenedList.contains(fullTargetName)) {
return;
}
- Project containingProject = getRefProject(fullTargetName);
String fullProjectName = getFullProjectName(fullTargetName);
Target target = getRefTarget(fullTargetName);
if (target == null) {
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/BuildElementHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/BuildElementHandler.java
old mode 100755
new mode 100644
similarity index 99%
rename from proposal/mutant/src/java/cli/org/apache/ant/cli/xml/BuildElementHandler.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/BuildElementHandler.java
index 2526c32ad..077e6b9d5
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/BuildElementHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/BuildElementHandler.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.cli.xml;
+package org.apache.ant.antcore.model.xmlparser;
import java.util.Iterator;
import org.apache.ant.antcore.model.BuildElement;
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/IncludeHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/IncludeHandler.java
old mode 100755
new mode 100644
similarity index 99%
rename from proposal/mutant/src/java/cli/org/apache/ant/cli/xml/IncludeHandler.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/IncludeHandler.java
index 42832ebfc..353359d48
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/IncludeHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/IncludeHandler.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.cli.xml;
+package org.apache.ant.antcore.model.xmlparser;
import java.net.MalformedURLException;
import java.net.URL;
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/NoProjectReadException.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/NoProjectReadException.java
old mode 100755
new mode 100644
similarity index 98%
rename from proposal/mutant/src/java/cli/org/apache/ant/cli/xml/NoProjectReadException.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/NoProjectReadException.java
index 5940dc25c..0b9e22c6d
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/NoProjectReadException.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/NoProjectReadException.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.cli.xml;
+package org.apache.ant.antcore.model.xmlparser;
/**
* A NoProjectReadException is used to indicate that a project was not read
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/ProjectHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/ProjectHandler.java
old mode 100755
new mode 100644
similarity index 99%
rename from proposal/mutant/src/java/cli/org/apache/ant/cli/xml/ProjectHandler.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/ProjectHandler.java
index 1b955b696..a73f8ded8
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/ProjectHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/ProjectHandler.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.cli.xml;
+package org.apache.ant.antcore.model.xmlparser;
import org.apache.ant.antcore.model.ModelException;
import org.apache.ant.antcore.model.Project;
import org.apache.ant.antcore.xml.ElementHandler;
@@ -148,6 +148,7 @@ public class ProjectHandler extends ElementHandler {
public void startElement(String uri, String localName, String qualifiedName,
Attributes attributes)
throws SAXParseException {
+
if (qualifiedName.equals("ref")) {
RefHandler refHandler = new RefHandler();
refHandler.start(getParseContext(), getXMLReader(), this,
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/RefHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/RefHandler.java
old mode 100755
new mode 100644
similarity index 99%
rename from proposal/mutant/src/java/cli/org/apache/ant/cli/xml/RefHandler.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/RefHandler.java
index 3e7d45e0d..197f3a7c9
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/RefHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/RefHandler.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.cli.xml;
+package org.apache.ant.antcore.model.xmlparser;
import java.net.MalformedURLException;
import java.net.URL;
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/TargetHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/TargetHandler.java
old mode 100755
new mode 100644
similarity index 98%
rename from proposal/mutant/src/java/cli/org/apache/ant/cli/xml/TargetHandler.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/TargetHandler.java
index 250ddd65c..5c1c40cf2
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/TargetHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/TargetHandler.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.cli.xml;
+package org.apache.ant.antcore.model.xmlparser;
import java.util.StringTokenizer;
import org.apache.ant.antcore.model.Target;
@@ -97,7 +97,6 @@ public class TargetHandler extends ElementHandler {
*/
public void processElement(String elementName)
throws SAXParseException {
- String targetName = null;
target = new Target(getLocation(), getAttribute(NAME_ATTR));
target.setDescription(getAttribute(DESC_ATTR));
target.setAspects(getAspects());
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/XMLProjectParser.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/XMLProjectParser.java
old mode 100755
new mode 100644
similarity index 98%
rename from proposal/mutant/src/java/cli/org/apache/ant/cli/xml/XMLProjectParser.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/XMLProjectParser.java
index f9ceaf58a..911d654f0
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/xml/XMLProjectParser.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/model/xmlparser/XMLProjectParser.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.cli.xml;
+package org.apache.ant.antcore.model.xmlparser;
import java.net.URL;
import org.apache.ant.common.util.Location;
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java
index 67517d312..6ebfb19c3 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java
@@ -64,6 +64,7 @@ import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
+import org.apache.ant.common.util.PropertyUtils;
/**
* An Element Handler is a handler which handles a single element by
@@ -125,6 +126,16 @@ public abstract class ElementHandler extends DefaultHandler {
return (String)elementAttributes.get(attributeName);
}
+ /**
+ * Get an attribute as a boolean value
+ *
+ * @param attributeName the name of the attribute
+ * @return the attribute value as a boolean
+ */
+ protected boolean getBooleanAttribute(String attributeName) {
+ return PropertyUtils.toBoolean(getAttribute(attributeName));
+ }
+
/**
* Get an iterator to this elements attributes
*
@@ -304,7 +315,8 @@ public abstract class ElementHandler extends DefaultHandler {
throws SAXParseException {
aspects = new HashMap();
elementAttributes = new HashMap();
- for (int i = 0; i < attributes.getLength(); ++i) {
+ int length = attributes.getLength();
+ for (int i = 0; i < length; ++i) {
String attributeName = attributes.getQName(i);
String attributeValue = attributes.getValue(i);
if (attributeName.indexOf(":") != -1) {
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java
index 18c542fec..8fd28c5bc 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java
@@ -128,11 +128,9 @@ public class ParseContext {
Location location = new Location(e.getSystemId(),
e.getLineNumber(), e.getColumnNumber());
if (e.getException() != null) {
- throw new XMLParseException("XML Parsing Exception",
- e.getException(), location);
+ throw new XMLParseException(e.getException(), location);
} else {
- throw new XMLParseException("XML Parsing Exception",
- e, location);
+ throw new XMLParseException(e, location);
}
} catch (SAXException e) {
throw new XMLParseException(e);
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml b/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml
new file mode 100644
index 000000000..fd2bed73b
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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
new file mode 100644
index 000000000..b7eaaa754
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Converter.java
@@ -0,0 +1,136 @@
+/*
+ * 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.antlib.AbstractConverter;
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * A converter to convert to the types supported by the Ant1 Ant library
+ *
+ * @author Conor MacNeill
+ * @created 1 February 2002
+ */
+public class Ant1Converter extends AbstractConverter {
+
+ /** The project instance for this converter */
+ private Project project;
+
+ /**
+ * Constructor for the Ant1Converter object
+ *
+ * @param project the project for this converter. It is used in the
+ * conversion of some of the supported types.
+ */
+ public Ant1Converter(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Get the list of classes this converter is able to convert to.
+ *
+ * @return an array of Class objects representing the classes this
+ * converter handles.
+ */
+ public Class[] getTypes() {
+ return new Class[]{Path.class, EnumeratedAttribute.class};
+ }
+
+ /**
+ * Convert a string from the value given to an instance of the given
+ * type.
+ *
+ * @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
+ */
+ public Object convert(String value, Class type) throws ExecutionException {
+ if (type.equals(Path.class)) {
+ return new Path(project, value);
+ } else if (EnumeratedAttribute.class.isAssignableFrom(type)) {
+ try {
+ EnumeratedAttribute ea
+ = (EnumeratedAttribute)type.newInstance();
+ ea.setValue(value);
+ return ea;
+ } catch (InstantiationException e) {
+ throw new ExecutionException(e);
+ } catch (IllegalAccessException e) {
+ throw new ExecutionException(e);
+ }
+
+ } else {
+ throw new ExecutionException("This converter does not handle "
+ + type.getName());
+ }
+ }
+
+ /**
+ * 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
+ * the given subclass of one of its main class
+ */
+ public boolean canConvertSubType(Class subType) {
+ return EnumeratedAttribute.class.isAssignableFrom(subType);
+ }
+
+}
+
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
new file mode 100644
index 000000000..fd7815a63
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java
@@ -0,0 +1,189 @@
+/*
+ * 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.antlib.AntContext;
+import org.apache.ant.common.antlib.Converter;
+import org.apache.ant.common.antlib.StandardLibFactory;
+import org.apache.ant.common.util.ExecutionException;
+
+/**
+ * The factory object for the Ant1 compatability Ant library
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public class Ant1Factory extends StandardLibFactory {
+ /**
+ * A Project instance associated with the factory - used in the creation
+ * of tasks and types
+ */
+ private Project project;
+ /** The Ant context for this factory */
+ private AntContext context;
+
+ /**
+ * Initialise the factory
+ *
+ * @param context the context for this factory to use to access core
+ * services.
+ * @exception ExecutionException if the factory cannot be initialised.
+ */
+ public void init(AntContext context) throws ExecutionException {
+ this.context = context;
+ project = new Project();
+ project.init(context);
+ }
+
+ /**
+ * Create an instance of the requested type class
+ *
+ * @param typeClass the class from which an instance is required
+ * @return an instance of the requested class
+ * @exception ExecutionException the instance could not be created.
+ * @exception InstantiationException if the type cannot be instantiated
+ * @exception IllegalAccessException if the type cannot be accessed
+ */
+ public Object createTypeInstance(Class typeClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException {
+ try {
+ java.lang.reflect.Constructor ctor = null;
+ // DataType can have a "no arg" constructor or take a single
+ // Project argument.
+ Object o = null;
+ try {
+ ctor = typeClass.getConstructor(new Class[0]);
+ o = ctor.newInstance(new Object[0]);
+ } catch (NoSuchMethodException nse) {
+ ctor = typeClass.getConstructor(new Class[]{Project.class});
+ o = ctor.newInstance(new Object[]{project});
+ }
+
+ if (o instanceof ProjectComponent) {
+ ((ProjectComponent)o).setProject(project);
+ }
+ return o;
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ Throwable t = ite.getTargetException();
+ String msg = "Could not create datatype of type: "
+ + typeClass.getName() + " due to " + t;
+ throw new ExecutionException(msg, t);
+ } catch (NoSuchMethodException e) {
+ throw new ExecutionException("Unable to find an appropriate "
+ + "constructor for type " + typeClass.getName(), e);
+ }
+ }
+
+ /**
+ * Create an instance of the requested task class
+ *
+ * @param taskClass the class from which an instance is required
+ * @return an instance of the requested class
+ * @exception InstantiationException if the task cannot be instantiated
+ * @exception IllegalAccessException if the task cannot be accessed
+ */
+ public Object createTaskInstance(Class taskClass)
+ throws InstantiationException, IllegalAccessException {
+ Object o = taskClass.newInstance();
+ if (o instanceof ProjectComponent) {
+ ((ProjectComponent)o).setProject(project);
+ }
+
+ // XXX task.setTaskType(taskType);
+
+ // set default value, can be changed by the user
+ // XXX task.setTaskName(taskType);
+
+ return o;
+ }
+
+ /**
+ * Create a converter.
+ *
+ * @param converterClass the class of the converter.
+ * @return an instance of the requested converter class
+ * @exception InstantiationException if the converter cannot be
+ * instantiated
+ * @exception IllegalAccessException if the converter cannot be accessed
+ * @exception ExecutionException if the converter cannot be created
+ */
+ public Converter createConverter(Class converterClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException {
+
+ java.lang.reflect.Constructor c = null;
+
+ Converter converter = null;
+ try {
+ try {
+ c = converterClass.getConstructor(new Class[0]);
+ converter = (Converter)c.newInstance(new Object[0]);
+ } catch (NoSuchMethodException nse) {
+ c = converterClass.getConstructor(new Class[]{Project.class});
+ converter = (Converter)c.newInstance(new Object[]{project});
+ }
+
+ return converter;
+ } catch (java.lang.reflect.InvocationTargetException ite) {
+ Throwable t = ite.getTargetException();
+ String msg = "Could not create converter of type: "
+ + converterClass.getName() + " due to " + t;
+ throw new ExecutionException(msg, t);
+ } catch (NoSuchMethodException e) {
+ throw new ExecutionException("Unable to find an appropriate "
+ + "constructor for converter " + converterClass.getName(), e);
+ }
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/AntClassLoader.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/AntClassLoader.java
new file mode 100644
index 000000000..53298a28f
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/AntClassLoader.java
@@ -0,0 +1,280 @@
+/*
+ * 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 java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import org.apache.ant.common.event.BuildEvent;
+import org.apache.ant.init.InitUtils;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * AntClassLoader facade
+ *
+ * @author Conor MacNeill
+ * @created 2 February 2002
+ */
+public class AntClassLoader extends URLClassLoader
+ implements BuildListener {
+ /**
+ * The context loader saved when setting the thread's current context
+ * loader.
+ */
+ private ClassLoader savedContextLoader = null;
+
+ /**
+ * Flag which indicates if this loader is currently set as the thread's
+ * context loader
+ */
+ private boolean isContextLoaderSaved = false;
+
+ /**
+ * indicates this loader should load classes by delegating to the parent
+ * loader first
+ */
+ private boolean parentFirst = true;
+
+ /** label used in debugging messages */
+ private String debugLabel = null;
+
+ /** flag to indicate of debugging is turned on */
+ private boolean debug = false;
+
+ /**
+ * Create an AntClassLoader
+ *
+ * @param project Project instance this loader is associated with
+ * @param classpath the classpath to use in searching for classes
+ */
+ public AntClassLoader(Project project, Path classpath) {
+ super(new URL[0]);
+ addPath(classpath);
+ }
+
+ /**
+ * Constructor for the AntClassLoader object
+ *
+ * @param project Project instance this loader is associated with
+ * @param classpath the classpath to use in searching for classes
+ * @param parentFirst true if this loader should delagate to its parent
+ * loader
+ */
+ public AntClassLoader(Project project, Path classpath,
+ boolean parentFirst) {
+ this(project, classpath);
+ this.parentFirst = parentFirst;
+ }
+
+ /**
+ * Constructor for the AntClassLoader object
+ *
+ * @param parent the parent classloader
+ * @param project Project instance this loader is associated with
+ * @param classpath the classpath to use in searching for classes
+ * @param parentFirst true if this loader should delagate to its parent
+ * loader
+ */
+ public AntClassLoader(ClassLoader parent, Project project, Path classpath,
+ boolean parentFirst) {
+ super(new URL[0], parent);
+ addPath(classpath);
+ this.parentFirst = parentFirst;
+ }
+
+ /**
+ * Initialize the given class
+ *
+ * @param theClass XXX Description of Parameter
+ */
+ public static void initializeClass(Class theClass) {
+ // do nothing in Ant2
+ }
+
+ /**
+ * Set this classloader to operate in isolated mode
+ *
+ * @param isolated true if this loader should isolate it from other
+ * classes in the VM
+ */
+ public void setIsolated(boolean isolated) {
+ }
+
+ /**
+ * Set the current thread's context loader to this classloader, storing
+ * the current loader value for later resetting
+ */
+ public void setThreadContextLoader() {
+ if (isContextLoaderSaved) {
+ throw new BuildException("Context loader has not been reset");
+ }
+ Thread currentThread = Thread.currentThread();
+ savedContextLoader = currentThread.getContextClassLoader();
+ currentThread.setContextClassLoader(this);
+ isContextLoaderSaved = true;
+ }
+
+ /**
+ * sets this loader to debug mode
+ *
+ * @param debug true if loads should be debugged
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ dumpURLs();
+ }
+
+ /**
+ * Sets the debugLabel of the AntClassLoader
+ *
+ * @param debugLabel the label to use in debug statements
+ */
+ public void setDebugLabel(String debugLabel) {
+ this.debugLabel = debugLabel;
+ }
+
+ /** Cleanup this loader */
+ public void cleanup() {
+ }
+
+ /**
+ * New build listener interface
+ *
+ * @param be the build event to be processed
+ */
+ public void processBuildEvent(BuildEvent be) {
+ }
+
+ /**
+ * Force a class to be loaded by this loader
+ *
+ * @param classname the name of the class to be loaded
+ * @return an instance of the requested class
+ * @exception ClassNotFoundException if the class cannot be found
+ */
+ public Class forceLoadClass(String classname)
+ throws ClassNotFoundException {
+ return super.loadClass(classname);
+ }
+
+ /** Reset the thread's class loader to its original value */
+ public void resetThreadContextLoader() {
+ if (!isContextLoaderSaved) {
+ throw new BuildException("Context loader is not currently set");
+ }
+ Thread currentThread = Thread.currentThread();
+ currentThread.setContextClassLoader(savedContextLoader);
+ isContextLoaderSaved = false;
+ }
+
+ /**
+ * Add a path tot his loader
+ *
+ * @param path the path to be added to this loader
+ */
+ private void addPath(Path path) {
+ try {
+ String[] pathElements = path.list();
+ for (int i = 0; i < pathElements.length; ++i) {
+ File elementFile = new File(pathElements[i]);
+ URL elementURL = InitUtils.getFileURL(elementFile);
+ addURL(elementURL);
+ }
+ } catch (MalformedURLException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /** Dump the URLs being used for this loader */
+ private void dumpURLs() {
+ if (debug && debugLabel != null) {
+ System.out.println(debugLabel + ": loader URLs");
+ URL[] urls = getURLs();
+ for (int i = 0; i < urls.length; ++i) {
+ System.out.println(debugLabel + ": URL: " + urls[i]);
+ }
+ }
+ }
+
+ /*
+ protected Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ if (debug && debugLabel != null) {
+ System.out.println(debugLabel + ": Trying to load class " + name);
+ }
+ Class c = findLoadedClass(name);
+ if (c == null) {
+ try {
+ c = findClass(name);
+ if (debug && debugLabel != null) {
+ System.out.println(debugLabel + ": Found class "
+ + name + " in this loader");
+ }
+ } catch (ClassNotFoundException e) {
+ c = super.loadClass(name, resolve);
+ if (debug && debugLabel != null) {
+ System.out.println(debugLabel + ": Found class "
+ + name + " in parent loader");
+ }
+ return c;
+ }
+ }
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+*/
+}
+
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildEvent.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildEvent.java
new file mode 100644
index 000000000..699e22a8b
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildEvent.java
@@ -0,0 +1,72 @@
+/*
+ * 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;
+
+/**
+ * BuildEvent facade
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public class BuildEvent extends org.apache.ant.common.event.BuildEvent {
+ /**
+ * Construct a BuildEvent for a task level event
+ *
+ * @param task the task that emitted the event.
+ */
+ public BuildEvent(Task task) {
+ super(task, MESSAGE);
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildListener.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildListener.java
new file mode 100644
index 000000000..983b010cc
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/BuildListener.java
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+/**
+ * BuildListener facade
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public interface BuildListener
+ extends org.apache.ant.common.event.BuildListener {
+}
+
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
new file mode 100644
index 000000000..41c99b91f
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
@@ -0,0 +1,622 @@
+/*
+ * 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 java.io.File;
+import java.io.IOException;
+import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.service.DataService;
+import org.apache.ant.common.service.FileService;
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.PropertyUtils;
+import org.apache.ant.common.util.MessageLevel;
+import org.apache.tools.ant.taskdefs.ExecTask;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.FilterSet;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Project facade
+ *
+ * @author Conor MacNeill
+ * @created 30 January 2002
+ */
+public class Project {
+
+ /** String which indicates Java version 1.0 */
+ public final static String JAVA_1_0 = "1.0";
+ /** String which indicates Java version 1.1 */
+ public final static String JAVA_1_1 = "1.1";
+ /** String which indicates Java version 1.2 */
+ public final static String JAVA_1_2 = "1.2";
+ /** String which indicates Java version 1.3 */
+ public final static String JAVA_1_3 = "1.3";
+ /** String which indicates Java version 1.4 */
+ public final static String JAVA_1_4 = "1.4";
+
+ /**
+ * @see MessageLevel.MSG_ERR
+ */
+ public final static int MSG_ERR = MessageLevel.MSG_ERR;
+ /**
+ * @see MessageLevel.MSG_WARN
+ */
+ public final static int MSG_WARN = MessageLevel.MSG_WARN;
+ /**
+ * @see MessageLevel.MSG_INFO
+ */
+ public final static int MSG_INFO = MessageLevel.MSG_INFO;
+ /**
+ * @see MessageLevel.MSG_VERBOSE
+ */
+ public final static int MSG_VERBOSE = MessageLevel.MSG_VERBOSE;
+ /**
+ * @see MessageLevel.MSG_DEBUG
+ */
+ public final static int MSG_DEBUG = MessageLevel.MSG_DEBUG;
+
+ /** The java version detected that Ant is running on */
+ private static String javaVersion;
+
+ /** The project description */
+ private String description;
+
+ /** The global filters of this project */
+ private FilterSet globalFilterSet = new FilterSet();
+
+ /** The AntContext that is used to access core services */
+ private AntContext context;
+
+ /** The core's FileService instance */
+ private FileService fileService;
+
+ /** The core's DataService instance */
+ private DataService dataService;
+
+ /** Ant1 FileUtils instance fro manipulating files */
+ private FileUtils fileUtils;
+ /** The collection of global filters */
+ private FilterSetCollection globalFilters
+ = new FilterSetCollection(globalFilterSet);
+
+ static {
+
+ // Determine the Java version by looking at available classes
+ // java.lang.StrictMath was introduced in JDK 1.3
+ // java.lang.ThreadLocal was introduced in JDK 1.2
+ // java.lang.Void was introduced in JDK 1.1
+ // Count up version until a NoClassDefFoundError ends the try
+
+ try {
+ javaVersion = JAVA_1_0;
+ Class.forName("java.lang.Void");
+ javaVersion = JAVA_1_1;
+ Class.forName("java.lang.ThreadLocal");
+ javaVersion = JAVA_1_2;
+ Class.forName("java.lang.StrictMath");
+ javaVersion = JAVA_1_3;
+ Class.forName("java.lang.CharSequence");
+ javaVersion = JAVA_1_4;
+ } catch (ClassNotFoundException cnfe) {
+ // swallow as we've hit the max class version that
+ // we have
+ }
+ }
+
+ /** Create the project */
+ public Project() {
+ fileUtils = FileUtils.newFileUtils();
+ }
+
+ /**
+ * static query of the java version
+ *
+ * @return a string indicating the Java version
+ */
+ public static String getJavaVersion() {
+ return javaVersion;
+ }
+
+ /**
+ * returns the boolean equivalent of a string, which is considered true
+ * if either "on", "true", or "yes" is found, ignoring case.
+ *
+ * @param s the string value to be interpreted at a boolean
+ * @return the value of s as a boolean
+ */
+ public static boolean toBoolean(String s) {
+ return PropertyUtils.toBoolean(s);
+ }
+
+ /**
+ * Translate a path into its native (platform specific) format.
+ *
+ * This method uses the PathTokenizer class to separate the input path
+ * into its components. This handles DOS style paths in a relatively
+ * sensible way. The file separators are then converted to their
+ * platform specific versions.
+ *
+ * @param to_process the path to be converted
+ * @return the native version of to_process or an empty string if
+ * to_process is null or empty
+ */
+ public static String translatePath(String to_process) {
+ if (to_process == null || to_process.length() == 0) {
+ return "";
+ }
+
+ StringBuffer path = new StringBuffer(to_process.length() + 50);
+ PathTokenizer tokenizer = new PathTokenizer(to_process);
+ while (tokenizer.hasMoreTokens()) {
+ String pathComponent = tokenizer.nextToken();
+ pathComponent = pathComponent.replace('/', File.separatorChar);
+ pathComponent = pathComponent.replace('\\', File.separatorChar);
+ if (path.length() != 0) {
+ path.append(File.pathSeparatorChar);
+ }
+ path.append(pathComponent);
+ }
+
+ return path.toString();
+ }
+
+ /**
+ * set the project description
+ *
+ * @param description text
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Set a project property
+ *
+ * @param name the property name
+ * @param value the property value
+ */
+ public void setProperty(String name, String value) {
+ try {
+ dataService.setMutableDataValue(name, value);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Set a property which must be a new value
+ *
+ * @param name the property name
+ * @param value the property value
+ */
+ public void setNewProperty(String name, String value) {
+ try {
+ dataService.setDataValue(name, value);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Sets a userProperty of the Project. Note under Ant2, there is no
+ * distinction between user and system properties
+ *
+ * @param name the property name
+ * @param value the property value
+ */
+ public void setUserProperty(String name, String value) {
+ try {
+ dataService.setMutableDataValue(name, value);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Gets the AntContext of the Project
+ *
+ * @return the AntContext
+ */
+ public AntContext getContext() {
+ return context;
+ }
+
+ /**
+ * get the project description
+ *
+ * @return description or null if no description has been set
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Get a project property
+ *
+ * @param name the property name
+ * @return the value of the property
+ */
+ public String getProperty(String name) {
+ try {
+ Object value = dataService.getDataValue(name);
+ return value == null ? null : value.toString();
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Get a project property. Ant2 does not distinguish between User and
+ * system proerties
+ *
+ * @param name the property name
+ * @return the value of the property
+ */
+ public String getUserProperty(String name) {
+ try {
+ return dataService.getDataValue(name).toString();
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Get a reference to a project property. Note that in Ant2, properties
+ * and references occupy the same namespace.
+ *
+ * @param refId the reference Id
+ * @return the object specified by the reference id
+ */
+ public Object getReference(String refId) {
+ try {
+ return dataService.getDataValue(refId);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Gets the globalFilterSet of the Project
+ *
+ * @return the globalFilterSet
+ */
+ public FilterSet getGlobalFilterSet() {
+ return globalFilterSet;
+ }
+
+ /**
+ * Gets the baseDir of the Project
+ *
+ * @return the baseDir
+ */
+ public File getBaseDir() {
+ return context.getBaseDir();
+ }
+
+ /**
+ * Gets the coreLoader of the Project
+ *
+ * @return the coreLoader value
+ */
+ public ClassLoader getCoreLoader() {
+ return getClass().getClassLoader();
+ }
+
+ /**
+ * Add a reference to an object. NOte that in Ant2 objects and
+ * properties occupy the same namespace.
+ *
+ * @param name the reference name
+ * @param value the object to be associated with the given name.
+ */
+ public void addReference(String name, Object value) {
+ try {
+ dataService.setDataValue(name, value);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+
+ /**
+ * Convienence method to copy a file from a source to a destination. No
+ * filtering is performed.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(String sourceFile, String destFile)
+ throws IOException {
+ fileUtils.copyFile(sourceFile, destFile);
+ }
+
+ /**
+ * Convienence method to copy a file from a source to a destination
+ * specifying if token filtering must be used.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @param filtering true if the copy should apply filters
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(String sourceFile, String destFile, boolean filtering)
+ throws IOException {
+ fileUtils.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null);
+ }
+
+ /**
+ * Convienence method to copy a file from a source to a destination
+ * specifying if token filtering must be used and if source files may
+ * overwrite newer destination files.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @param filtering true if the copy should apply filters
+ * @param overwrite true if the destination can be overwritten
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(String sourceFile, String destFile, boolean filtering,
+ boolean overwrite) throws IOException {
+ fileUtils.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null, overwrite);
+ }
+
+ /**
+ * 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 modified
+ * time of sourceFile
.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @param filtering true if the copy should apply filters
+ * @param overwrite true if the destination can be overwritten
+ * @param preserveLastModified true if the last modified time of the
+ * source file is preserved
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(String sourceFile, String destFile, boolean filtering,
+ boolean overwrite, boolean preserveLastModified)
+ throws IOException {
+ fileUtils.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null,
+ overwrite, preserveLastModified);
+ }
+
+ /**
+ * Convienence method to copy a file from a source to a destination. No
+ * filtering is performed.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(File sourceFile, File destFile) throws IOException {
+ fileUtils.copyFile(sourceFile, destFile);
+ }
+
+ /**
+ * Convienence method to copy a file from a source to a destination
+ * specifying if token filtering must be used.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @param filtering true if the copy should apply filters
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(File sourceFile, File destFile, boolean filtering)
+ throws IOException {
+ fileUtils.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null);
+ }
+
+ /**
+ * Convienence method to copy a file from a source to a destination
+ * specifying if token filtering must be used and if source files may
+ * overwrite newer destination files.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @param filtering true if the copy should apply filters
+ * @param overwrite true if the destination can be overwritten
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(File sourceFile, File destFile, boolean filtering,
+ boolean overwrite) throws IOException {
+ fileUtils.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null, overwrite);
+ }
+
+ /**
+ * 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 modified
+ * time of sourceFile
.
+ *
+ * @param sourceFile the source file to be copied
+ * @param destFile the destination to which the file is copied
+ * @param filtering true if the copy should apply filters
+ * @param overwrite true if the destination can be overwritten
+ * @param preserveLastModified true if the last modified time of the
+ * source file is preserved
+ * @exception IOException if the file cannot be copied
+ * @deprecated
+ */
+ public void copyFile(File sourceFile, File destFile, boolean filtering,
+ boolean overwrite, boolean preserveLastModified)
+ throws IOException {
+ fileUtils.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null, overwrite, preserveLastModified);
+ }
+
+ /**
+ * Initialise this porject
+ *
+ * @param context the context the project uses to access core services
+ * @exception ExecutionException if the project cannot be initialised.
+ */
+ public void init(AntContext context) throws ExecutionException {
+ this.context = context;
+ fileService = (FileService)context.getCoreService(FileService.class);
+ dataService = (DataService)context.getCoreService(DataService.class);
+ }
+
+ /**
+ * Output a message to the log with the default log level of MSG_INFO
+ *
+ * @param msg text to log
+ */
+
+ public void log(String msg) {
+ log(msg, MSG_INFO);
+ }
+
+ /**
+ * Output a message to the log with the given log level and an event
+ * scope of project
+ *
+ * @param msg text to log
+ * @param msgLevel level to log at
+ */
+ public void log(String msg, int msgLevel) {
+ context.log(msg, msgLevel);
+ }
+
+ /**
+ * Output a message to the log with the given log level and an event
+ * scope of a task
+ *
+ * @param task task to use in the log
+ * @param msg text to log
+ * @param msgLevel level to log at
+ */
+ public void log(Task task, String msg, int msgLevel) {
+ context.log(msg, msgLevel);
+ }
+
+ /**
+ * Resolve a file relative to the project's basedir
+ *
+ * @param fileName the file name
+ * @return the file as a File resolved relative to the project's basedir
+ */
+ public File resolveFile(String fileName) {
+ try {
+ return fileService.resolveFile(fileName);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Replace property references (${} values) in the given string
+ *
+ * @param value the string in which property references are replaced
+ * @return the string with the properties replaced.
+ */
+ public String replaceProperties(String value) {
+ try {
+ return dataService.replacePropertyRefs(value);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * add a build listener to this project
+ *
+ * @param listener the listener to be added to the project
+ */
+ public void addBuildListener(BuildListener listener) {
+ // XXX do nothing for now
+ }
+
+ /**
+ * Create a Task. This faced hard codes a few well known tasks at this
+ * time
+ *
+ * @param taskName the name of the task to be created.
+ * @return the created task instance
+ */
+ public Task createTask(String taskName) {
+ // we piggy back the task onto the current context
+ Task task = null;
+ if (taskName.equals("java")) {
+ task = new Java();
+ } else if (taskName.equals("exec")) {
+ task = new ExecTask();
+ } else {
+ return null;
+ }
+ try {
+ task.setProject(this);
+ task.init(context);
+ return task;
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/io/code/org/apache/ant/taskdef/io/Echo.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
old mode 100755
new mode 100644
similarity index 54%
rename from proposal/mutant/src/java/antlibs/io/code/org/apache/ant/taskdef/io/Echo.java
rename to proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
index c3ee9f37a..cbfbefaa3
--- a/proposal/mutant/src/java/antlibs/io/code/org/apache/ant/taskdef/io/Echo.java
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
@@ -51,112 +51,106 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.taskdef.io;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
+package org.apache.tools.ant;
-import org.apache.ant.common.task.AbstractTask;
-import org.apache.ant.common.task.TaskException;
-import org.apache.ant.common.util.MessageLevel;
+import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.util.ExecutionException;
/**
- * Basic Echo Tast for testing
+ * ProjectComponent facade
*
* @author Conor MacNeill
- * @created 16 January 2002
+ * @created 31 January 2002
*/
-public class Echo extends AbstractTask {
- /** The message to be echoed */
- private String message = "";
- /** the file to which output is sent if any */
- private File file = null;
- /** indicates if the fileoutput is to be appended to an existing file */
- private boolean append = false;
-
- // by default, messages are always displayed
- /** the log level to be used when echoing - defaults to Warning level */
- private int logLevel = MessageLevel.MSG_WARN;
+public abstract class ProjectComponent {
+ /** The project in which the project component operates */
+ protected Project project;
+ /** The location within the build file of this project component */
+ protected Location location;
+ /** The core context for this component */
+ private AntContext context;
/**
- * Sets the message variable.
+ * Sets the project of the ProjectComponent
*
- * @param msg Sets the value for the message variable.
+ * @param project the project object with which this component is
+ * associated
*/
- public void setMessage(String msg) {
- this.message = msg;
+ public void setProject(Project project) {
+ this.project = project;
}
/**
- * Set the file to which output is to be sent
+ * Sets the file location where this task was defined.
*
- * @param file the new file value
+ * @param location the new location value
*/
- public void setFile(File file) {
- this.file = file;
+ public void setLocation(Location location) {
+ this.location = location;
}
/**
- * Indicate if output is to be appended to the file
+ * Gets the project of the ProjectComponent
*
- * @param append true if output should be appended
+ * @return the project
*/
- public void setAppend(boolean append) {
- this.append = append;
+ public Project getProject() {
+ return project;
}
/**
- * Does the work.
+ * Gets the location of the ProjectComponent's associated model element
+ * in the build file
*
- * @throws TaskException if cannot output message
+ * @return the location of the associated model element
*/
- public void execute() throws TaskException {
- if (file == null) {
- log(message, logLevel);
- } else {
- FileWriter out = null;
- try {
- out = new FileWriter(file.getAbsolutePath(), append);
- out.write(message, 0, message.length());
- } catch (IOException ioe) {
- throw new TaskException(ioe);
- } finally {
- if (out != null) {
- try {
- out.close();
- } catch (IOException ioex) {
- }
- }
- }
- }
+ public Location getLocation() {
+ return location;
}
/**
- * Set a multiline message.
+ * Initialise this component
*
- * @param msg the message
+ * @param context the core context for this component
+ * @exception ExecutionException if the component cannot be initialized
*/
- public void addText(String msg) {
- message += msg;
+ public void init(AntContext context) throws ExecutionException {
+ this.context = context;
+ org.apache.ant.common.util.Location contextLocation
+ = context.getLocation();
+
+ if (contextLocation
+ == org.apache.ant.common.util.Location.UNKNOWN_LOCATION) {
+ location = Location.UNKNOWN_LOCATION;
+ } else {
+ location = new Location(contextLocation.getSource(),
+ contextLocation.getLineNumber(),
+ contextLocation.getColumnNumber());
+ }
+ }
+
+ /** Destroy this component */
+ public void destroy() {
+ // nothing to do
}
/**
- * testing only
+ * Log a message as a build event
*
- * @param frame testing
+ * @param message the message to be logged
+ * @param level the priority level of the message
*/
- public void addFrame(java.awt.Frame frame) {
- log("Adding frame " + frame, MessageLevel.MSG_WARN);
+ public void log(String message, int level) {
+ context.log(message, level);
}
/**
- * testing
+ * Log a message as a build event
*
- * @param runnable testing
+ * @param message the message to be logged
*/
- public void addRun(Runnable runnable) {
- log("Adding runnable of type "
- + runnable.getClass().getName(), MessageLevel.MSG_WARN);
+ public void log(String message) {
+ context.log(message, Project.MSG_INFO);
}
}
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
new file mode 100644
index 000000000..5ecd1a5d9
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectHelper.java
@@ -0,0 +1,135 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.tools.ant;
+import java.util.Hashtable;
+import java.util.Vector;
+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;
+
+/**
+ * Ant1 ProjectHelper facade
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public class ProjectHelper {
+ /**
+ * This method will parse a string containing ${value} style property
+ * values into two lists. The first list is a collection of text
+ * fragments, while the other is a set of string property names null
+ * entries in the first list indicate a property reference from the
+ * second list.
+ *
+ * @param value the string to be parsed
+ * @param fragments the fragments parsed out of the string
+ * @param propertyRefs the property refs to be replaced
+ */
+ public static void parsePropertyString(String value, Vector fragments,
+ Vector propertyRefs) {
+ try {
+ PropertyUtils.parsePropertyString(value, fragments, propertyRefs);
+ } catch (AntException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Replace ${} style constructions in the given value with the string
+ * value of the corresponding data types.
+ *
+ * @param value the string to be scanned for property references.
+ * @param project the project object which contains the property values
+ * @return the string with the property references replaced with their
+ * project values
+ * @exception BuildException if there is a problem replacing the
+ * property values.
+ */
+ public static String replaceProperties(Project project, String value)
+ throws BuildException {
+ try {
+ AntContext context = project.getContext();
+ DataService dataService
+ = (DataService)context.getCoreService(DataService.class);
+ return dataService.replacePropertyRefs(value);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Replace ${} style constructions in the given value with the string
+ * value of the corresponding data types.
+ *
+ * @param value the string to be scanned for property references.
+ * @param project the project object
+ * @param keys the collection of property values to use
+ * @return the string with the property references replaced with their
+ * project values
+ */
+ public static String replaceProperties(Project project, String value,
+ Hashtable keys) {
+ try {
+ AntContext context = project.getContext();
+ DataService dataService
+ = (DataService)context.getCoreService(DataService.class);
+ return dataService.replacePropertyRefs(value, keys);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Target.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Target.java
new file mode 100644
index 000000000..26fa2f595
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Target.java
@@ -0,0 +1,64 @@
+/*
+ * 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;
+
+/**
+ * Ant1 Target facade.
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public class Target {
+}
+
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/task/TaskException.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
old mode 100755
new mode 100644
similarity index 56%
rename from proposal/mutant/src/java/common/org/apache/ant/common/task/TaskException.java
rename to proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
index 20b0d0c83..284949b68
--- a/proposal/mutant/src/java/common/org/apache/ant/common/task/TaskException.java
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
@@ -51,84 +51,107 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.task;
-
-import org.apache.ant.common.util.AntException;
-import org.apache.ant.common.util.Location;
+package org.apache.tools.ant;
/**
- * An TaskException indicates a problem while executing tasks in a build
+ * Ant1 Task facade
*
* @author Conor MacNeill
- * @created 16 January 2002
+ * @created 31 January 2002
*/
-public class TaskException extends AntException {
+public abstract class Task extends ProjectComponent
+ implements org.apache.ant.common.antlib.Task {
+ /** the name of this task */
+ protected String taskName;
+ /** The target with which this target is associated */
+ protected Target target = null;
+ /** The type of this target */
+ protected String taskType = null;
+ /** The description of this task */
+ protected String description = null;
+
/**
- * Constructs an exception with the given descriptive message.
+ * Set the name to use in logging messages.
*
- * @param msg Description of or information about the exception.
+ * @param name the name to use in logging messages.
*/
- public TaskException(String msg) {
- super(msg);
+ public void setTaskName(String name) {
+ this.taskName = name;
}
/**
- * Constructs an exception with the given descriptive message and a
- * location in a file.
+ * Sets the target object of this task.
*
- * @param msg Description of or information about the exception.
- * @param location Location in the project file where the error occured.
+ * @param target Target in whose scope this task belongs.
*/
- public TaskException(String msg, Location location) {
- super(msg, location);
+ public void setOwningTarget(Target target) {
+ this.target = target;
}
+ /**
+ * Sets a description of the current action. It will be usefull in
+ * commenting what we are doing.
+ *
+ * @param desc the new description value
+ */
+ public void setDescription(String desc) {
+ description = desc;
+ }
/**
- * Constructs an exception with the given message and exception as a
- * root cause.
+ * Get the name to use in logging messages.
*
- * @param msg Description of or information about the exception.
- * @param cause Throwable that might have cause this one.
+ * @return the name to use in logging messages.
*/
- public TaskException(String msg, Throwable cause) {
- super(msg, cause);
+ public String getTaskName() {
+ return taskName;
}
/**
- * Constructs an exception with the given message and exception as a
- * root cause and a location in a file.
+ * Get the Target to which this task belongs
*
- * @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.
+ * @return the task's target.
*/
- public TaskException(String msg, Throwable cause, Location location) {
- super(msg, cause, location);
+ public Target getOwningTarget() {
+ return target;
}
+ /**
+ * Gets the description of the Task
+ *
+ * @return the task's description
+ */
+ public String getDescription() {
+ return description;
+ }
/**
- * Constructs an exception with the given exception as a root cause.
+ * Handle output captured for this task
*
- * @param cause Exception that might have caused this one.
+ * @param line the captured output
*/
- public TaskException(Throwable cause) {
- super(cause);
+ protected void handleOutput(String line) {
+ log(line, Project.MSG_INFO);
}
+ /**
+ * Handle error output captured for this task
+ *
+ * @param line the captured error output
+ */
+ protected void handleErrorOutput(String line) {
+ log(line, Project.MSG_ERR);
+ }
/**
- * Constructs an exception with the given exception as a root cause and
- * a location in a file.
+ * Set the name with which the task has been invoked.
*
- * @param cause Exception that might have cause this one.
- * @param location Location in the project file where the error occured.
+ * @param type the name the task has been invoked as.
*/
- public TaskException(Throwable cause, Location location) {
- super(cause, location);
+ void setTaskType(String type) {
+ this.taskType = type;
}
}
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/TaskContainer.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/TaskContainer.java
new file mode 100644
index 000000000..39adddd3c
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/TaskContainer.java
@@ -0,0 +1,64 @@
+/*
+ * 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;
+
+/**
+ * TaskContainer facade
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public interface TaskContainer {
+}
+
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types/DataType.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types/DataType.java
new file mode 100644
index 000000000..9815b0356
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/types/DataType.java
@@ -0,0 +1,234 @@
+/*
+ * 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.types;
+import java.util.Stack;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Ant1 DataType facade
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public abstract class DataType extends ProjectComponent
+ implements org.apache.ant.common.antlib.DataType {
+
+ /** The description the user has set. */
+ protected String description = null;
+ /** Value to the refid attribute. */
+ protected Reference ref = null;
+ /**
+ * Are we sure we don't hold circular references?
+ *
+ * Subclasses are responsible for setting this value to false if we'd
+ * need to investigate this condition (usually because a child element
+ * has been added that is a subclass of DataType).
+ */
+ protected boolean checked = true;
+
+ /**
+ * Sets a description of the current data type. It will be useful in
+ * commenting what we are doing.
+ *
+ * @param desc the new description value
+ */
+ public void setDescription(String desc) {
+ description = desc;
+ }
+
+ /**
+ * Set the value of the refid attribute.
+ *
+ * Subclasses may need to check whether any other attributes have been
+ * set as well or child elements have been created and thus override
+ * this method. if they do the must call super.setRefid
.
+ *
+ *
+ * @param ref the new refid value
+ */
+ public void setRefid(Reference ref) {
+ this.ref = ref;
+ checked = false;
+ }
+
+ /**
+ * Sets the id of the DataType
+ *
+ * @param id the name under which the data type is to be referenced
+ */
+ public void setId(String id) {
+ project.addReference(id, this);
+ }
+
+ /**
+ * Return the description for the current data type.
+ *
+ * @return the data type's description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Has the refid attribute of this element been set?
+ *
+ * @return true if this data type is a refeence to another instance
+ */
+ public boolean isReference() {
+ return ref != null;
+ }
+
+ /**
+ * Performs the check for circular references and returns the referenced
+ * object.
+ *
+ * @param requiredClass the class which the object being referenced must
+ * support
+ * @param dataTypeName the name of the data type
+ * @return the refenced object
+ */
+ protected Object getCheckedRef(Class requiredClass, String dataTypeName) {
+ if (!checked) {
+ Stack stk = new Stack();
+ stk.push(this);
+ dieOnCircularReference(stk, getProject());
+ }
+
+ Object o = ref.getReferencedObject(getProject());
+ if (!(requiredClass.isAssignableFrom(o.getClass()))) {
+ String msg = ref.getRefId() + " doesn\'t denote a " + dataTypeName;
+ throw new BuildException(msg);
+ } else {
+ return o;
+ }
+ }
+
+ /**
+ * Check to see whether any DataType we hold references to is included
+ * in the Stack (which holds all DataType instances that directly or
+ * indirectly reference this instance, including this instance itself).
+ *
+ *
+ * If one is included, throw a BuildException created by {@link
+ * #circularReference circularReference}.
+ *
+ * This implementation is appropriate only for a DataType that cannot
+ * hold other DataTypes as children.
+ *
+ * The general contract of this method is that it shouldn't do anything
+ * if {@link #checked checked
} is true and set it to true
+ * on exit.
+ *
+ * @param stk stack used to check for a circular reference
+ * @param p the project
+ * @exception BuildException if this data type is a reference to an
+ * instance which depends on this data type
+ */
+ protected void dieOnCircularReference(Stack stk, Project p)
+ throws BuildException {
+
+ if (checked || !isReference()) {
+ return;
+ }
+ Object o = ref.getReferencedObject(p);
+
+ if (o instanceof DataType) {
+ if (stk.contains(o)) {
+ throw circularReference();
+ } else {
+ stk.push(o);
+ ((DataType)o).dieOnCircularReference(stk, p);
+ stk.pop();
+ }
+ }
+ checked = true;
+ }
+
+ /**
+ * Creates an exception that indicates that refid has to be the only
+ * attribute if it is set.
+ *
+ * @return an appropriate excpetion instance
+ */
+ protected BuildException tooManyAttributes() {
+ return new BuildException("You must not specify more than "
+ + "one attribute when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates that this XML element must not
+ * have child elements if the refid attribute is set.
+ *
+ * @return an appropriate excpetion instance
+ */
+ protected BuildException noChildrenAllowed() {
+ return new BuildException("You must not specify nested "
+ + "elements when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates the user has generated a loop of
+ * data types referencing each other.
+ *
+ * @return an appropriate excpetion instance
+ */
+ protected BuildException circularReference() {
+ return new BuildException("This data type contains a "
+ + "circular reference.");
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/file/antlib.xml b/proposal/mutant/src/java/antlibs/file/antlib.xml
deleted file mode 100755
index b545e73a1..000000000
--- a/proposal/mutant/src/java/antlibs/file/antlib.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
diff --git a/proposal/mutant/src/java/antlibs/io/antlib.xml b/proposal/mutant/src/java/antlibs/io/antlib.xml
deleted file mode 100755
index 67b5b729b..000000000
--- a/proposal/mutant/src/java/antlibs/io/antlib.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
diff --git a/proposal/mutant/src/java/antlibs/system/antlib.xml b/proposal/mutant/src/java/antlibs/system/antlib.xml
new file mode 100644
index 000000000..8cac5324f
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/antlib.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/proposal/mutant/src/java/antlibs/io/code/org/apache/ant/taskdef/io/FileConverter.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/FileConverter.java
old mode 100755
new mode 100644
similarity index 85%
rename from proposal/mutant/src/java/antlibs/io/code/org/apache/ant/taskdef/io/FileConverter.java
rename to proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/FileConverter.java
index e535c1223..107662f92
--- a/proposal/mutant/src/java/antlibs/io/code/org/apache/ant/taskdef/io/FileConverter.java
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/FileConverter.java
@@ -51,12 +51,13 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.taskdef.io;
+package org.apache.ant.antlib.system;
import java.io.File;
-import org.apache.ant.common.converter.AbstractConverter;
-import org.apache.ant.common.converter.ConversionException;
+import org.apache.ant.common.antlib.AbstractConverter;
+import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.AntException;
+import org.apache.ant.common.service.FileService;
/**
* A converter to convert to File objects, resolving against the
@@ -84,14 +85,16 @@ 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 ConversionException if the conversion cannot be made
+ * @exception ExecutionException if the conversion cannot be made
*/
- public Object convert(String value, Class type) throws ConversionException {
+ public Object convert(String value, Class type) throws ExecutionException {
try {
- return getContext().resolveFile(value);
+ FileService fileService
+ = (FileService)getContext().getCoreService(FileService.class);
+ return fileService.resolveFile(value);
}
catch (AntException e) {
- throw new ConversionException("Unable to resolve file: "
+ throw new ExecutionException("Unable to resolve file: "
+ value, e);
}
}
diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Import.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Import.java
new file mode 100644
index 000000000..1313b4431
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Import.java
@@ -0,0 +1,74 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.ant.antlib.system;
+
+import org.apache.ant.common.antlib.AbstractTask;
+
+/**
+ * Task to import a component or components from a library
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public class Import extends AbstractTask {
+ /** The Ant LIbrary Id from which the component must be imported */
+ private String antlibId = null;
+ /** The name of the component to be imported */
+ private String componentName = null;
+
+ /** Do thw work and import the components */
+ public void execute() {
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LibPath.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LibPath.java
new file mode 100644
index 000000000..115b7f67e
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LibPath.java
@@ -0,0 +1,72 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.ant.antlib.system;
+
+import org.apache.ant.common.antlib.AbstractTask;
+
+/**
+ * Task to add an additional classpath search path to the given library
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public class LibPath extends AbstractTask {
+ /** The id of the library for which this additional path is being set */
+ private String libraryId;
+
+ /** Add the libpath to the set of paths associated with the library */
+ public void execute() {
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LoadLib.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LoadLib.java
new file mode 100644
index 000000000..431956636
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/LoadLib.java
@@ -0,0 +1,162 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.ant.antlib.system;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import org.apache.ant.common.antlib.AbstractTask;
+import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.service.ComponentService;
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.init.InitUtils;
+
+/**
+ * Load an AntLibrary and optionally import all its components
+ *
+ * @author Conor MacNeill
+ * @created 29 January 2002
+ */
+public class LoadLib extends AbstractTask {
+ /** Flag which indicates if all components should be imported */
+ private boolean importAll;
+
+ /**
+ * This is the location, either file or URL of the library or libraries
+ * to be loaded
+ */
+ private URL url;
+
+ /**
+ * Sets the URL of the library to be loaded
+ *
+ * @param url the URL from which the library is to be loaded
+ * @exception ExecutionException if the URL cannot be set
+ */
+ public void setURL(URL url) throws ExecutionException {
+ checkNullURL();
+ this.url = url;
+ }
+
+ /**
+ * Set the file from which the library should be loaded.
+ *
+ * @param file the file from which the library should be loaded
+ * @exception ExecutionException if the file attribute cannot be set
+ */
+ public void setFile(File file) throws ExecutionException {
+ checkNullURL();
+ try {
+ this.url = InitUtils.getFileURL(file);
+ } catch (MalformedURLException e) {
+ throw new ExecutionException(e);
+ }
+ }
+
+ /**
+ * Set the dir in which to search for AntLibraries.
+ *
+ * @param dir the dir from which all Ant Libraries found will be loaded.
+ * @exception ExecutionException if the dir attribute cannot be set
+ */
+ public void setDir(File dir) throws ExecutionException {
+ checkNullURL();
+ try {
+ this.url = InitUtils.getFileURL(dir);
+ } catch (MalformedURLException e) {
+ throw new ExecutionException(e);
+ }
+ }
+
+ /**
+ * Indicate whether all components from the library should be imported
+ *
+ * @param importAll true if all components in the library should be
+ * imported.
+ */
+ public void setImportAll(boolean importAll) {
+ this.importAll = importAll;
+ }
+
+
+ /**
+ * Load the library or libraries and optiinally import their components
+ *
+ * @exception ExecutionException if the library or libraries cannot be
+ * loaded.
+ */
+ public void execute() throws ExecutionException {
+ if (url == null) {
+ throw new ExecutionException("A location from which to load "
+ + "libraries must be provided");
+ }
+ AntContext context = getContext();
+ ComponentService componentService = (ComponentService)
+ context.getCoreService(ComponentService.class);
+ componentService.loadLib(url.toString(), importAll);
+ }
+
+ /**
+ * Check if any of the location specifying attributes have already been
+ * set.
+ *
+ * @exception ExecutionException if the search URL has already been set
+ */
+ private void checkNullURL() throws ExecutionException {
+ if (url != null) {
+ throw new ExecutionException("Location of library has already been "
+ + "set. Please use only one of file, dir or url attributes");
+ }
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/PrimitiveConverter.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/PrimitiveConverter.java
new file mode 100644
index 000000000..4009e43c5
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/PrimitiveConverter.java
@@ -0,0 +1,113 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.ant.antlib.system;
+
+import org.apache.ant.common.antlib.AbstractConverter;
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.PropertyUtils;
+
+/**
+ * A converter to convert to Java's primitie types
+ *
+ * @author Conor MacNeill
+ */
+public class PrimitiveConverter extends AbstractConverter {
+
+ /**
+ * Get the list of classes this converter is able to convert to.
+ *
+ * @return an array of Class objects representing the classes this
+ * converter handles.
+ */
+ public Class[] getTypes() {
+ return new Class[] {
+ Character.class, Character.TYPE, Byte.TYPE, Short.TYPE,
+ Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE,
+ Boolean.class, Boolean.TYPE};
+ }
+
+ /**
+ * Convert a string from the value given to an instance of the given
+ * type.
+ *
+ * @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
+ */
+ public Object convert(String value, Class type) throws ExecutionException {
+ if (type.equals(Character.class)
+ || type.equals(Character.TYPE)) {
+ return new Character(value.charAt(0));
+ } else if (type.equals(Byte.TYPE)) {
+ return new Byte(value);
+ } else if (type.equals(Short.TYPE)) {
+ return new Short(value);
+ } else if (type.equals(Integer.TYPE)) {
+ return new Integer(value);
+ } else if (type.equals(Long.TYPE)) {
+ return new Long(value);
+ } else if (type.equals(Float.TYPE)) {
+ return new Float(value);
+ } else if (type.equals(Double.TYPE)) {
+ return new Double(value);
+ } 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());
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Taskdef.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Taskdef.java
new file mode 100644
index 000000000..a736dd107
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Taskdef.java
@@ -0,0 +1,69 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.ant.antlib.system;
+
+import org.apache.ant.common.antlib.AbstractTask;
+
+/**
+ * Define a new task for use in the build file
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public class Taskdef extends AbstractTask {
+ /** Define the new task */
+ public void execute() {
+ }
+}
+
diff --git a/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Typedef.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Typedef.java
new file mode 100644
index 000000000..4577e6f08
--- /dev/null
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Typedef.java
@@ -0,0 +1,69 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ */
+package org.apache.ant.antlib.system;
+
+import org.apache.ant.common.antlib.AbstractTask;
+
+/**
+ * Define a new type to be used in the build
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public class Typedef extends AbstractTask {
+ /** define the type */
+ public void execute() {
+ }
+}
+
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TypeContext.java b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/URLConverter.java
old mode 100755
new mode 100644
similarity index 70%
rename from proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TypeContext.java
rename to proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/URLConverter.java
index b7ceadcb2..e48f67d02
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TypeContext.java
+++ b/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/URLConverter.java
@@ -51,41 +51,46 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.antcore.execution;
-import org.apache.ant.common.task.DataType;
-import org.apache.ant.antcore.model.ModelElement;
+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;
/**
- * This is the core's implementation of the AntContext for Types
+ * A converter to convert to URLs relative to the project base dir
*
* @author Conor MacNeill
- * @created 20 January 2002
*/
-public class TypeContext extends ExecutionContext {
- /** The task being managed by this context */
- private DataType typeInstance;
+public class URLConverter extends AbstractConverter {
/**
- * get the DataType instance associated with this context.
+ * Get the list of classes this converter is able to convert to.
*
- * @return the DataType instance
+ * @return an array of Class objects representing the classes this
+ * converter handles.
*/
- public DataType getInstance() {
- return typeInstance;
+ public Class[] getTypes() {
+ return new Class[]{URL.class};
}
/**
- * Initilaise the context and associate it with the given DataType
- * instance
+ * Convert a string from the value given to an instance of the given
+ * type.
*
- * @param typeInstance the DataType instance
- * @param modelElement the model element associated with this context
+ * @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
*/
- public void init(DataType typeInstance, ModelElement modelElement) {
- this.typeInstance = typeInstance;
- setModelElement(modelElement);
- typeInstance.init(this);
+ public Object convert(String value, Class type) throws ExecutionException {
+ try {
+ return new URL(value);
+ }
+ catch (MalformedURLException e) {
+ throw new ExecutionException(e);
+ }
}
-
}
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/BuildLogger.java b/proposal/mutant/src/java/cli/org/apache/ant/cli/BuildLogger.java
index e02360255..eeb2dcdf0 100755
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/BuildLogger.java
+++ b/proposal/mutant/src/java/cli/org/apache/ant/cli/BuildLogger.java
@@ -54,7 +54,7 @@
package org.apache.ant.cli;
import java.io.PrintStream;
-import org.apache.ant.antcore.event.BuildListener;
+import org.apache.ant.common.event.BuildListener;
/**
* Interface used by Ant to log the build output. A build logger is a build
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java b/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java
index d17afdb0b..6f762e350 100755
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java
+++ b/proposal/mutant/src/java/cli/org/apache/ant/cli/Commandline.java
@@ -53,6 +53,7 @@
*/
package org.apache.ant.cli;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
@@ -61,20 +62,23 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import org.apache.ant.cli.xml.XMLProjectParser;
-import org.apache.ant.common.util.AntException;
-import org.apache.ant.common.util.Location;
-import org.apache.ant.common.util.MessageLevel;
-import org.apache.ant.antcore.event.BuildListener;
+import org.apache.ant.antcore.config.AntConfig;
+import org.apache.ant.antcore.config.AntConfigHandler;
import org.apache.ant.antcore.execution.ExecutionManager;
import org.apache.ant.antcore.model.Project;
+import org.apache.ant.antcore.model.xmlparser.XMLProjectParser;
import org.apache.ant.antcore.util.ConfigException;
+import org.apache.ant.antcore.xml.ParseContext;
import org.apache.ant.antcore.xml.XMLParseException;
-import org.apache.ant.init.InitUtils;
+import org.apache.ant.common.event.BuildListener;
+import org.apache.ant.common.util.AntException;
+import org.apache.ant.common.util.Location;
+import org.apache.ant.common.util.MessageLevel;
import org.apache.ant.init.InitConfig;
+import org.apache.ant.init.InitUtils;
/**
- * This is the command line front end to end. It drives the core
+ * This is the command line front end. It drives the core.
*
* @author Conor MacNeill
* @created 9 January 2002
@@ -112,7 +116,7 @@ public class Commandline {
private String loggerClassname = null;
/** Our current message output status. Follows MessageLevel values */
- private int messageOutputLevel = MessageLevel.MSG_VERBOSE;
+ private int messageOutputLevel = MessageLevel.MSG_INFO;
/**
* Start the command line front end for mutant.
@@ -163,41 +167,98 @@ public class Commandline {
}
}
+ /**
+ * Get the AntConfig from the given config area if it is available
+ *
+ * @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
+ * formed.
+ */
+ private AntConfig getAntConfig(File configArea) throws ConfigException {
+ try {
+ File configFile = new File(configArea, "antconfig.xml");
+ URL configFileURL = InitUtils.getFileURL(configFile);
+
+ ParseContext context = new ParseContext();
+ AntConfigHandler configHandler = new AntConfigHandler();
+
+ context.parse(configFileURL, "antconfig", configHandler);
+
+ return configHandler.getAntConfig();
+ } catch (MalformedURLException e) {
+ throw new ConfigException("Unable to form URL to read config from "
+ + configArea, e);
+ } catch (XMLParseException e) {
+ if (!(e.getCause() instanceof FileNotFoundException)) {
+ throw new ConfigException("Unable to parse config file from "
+ + configArea, e);
+ }
+ // ignore missing config files
+ return null;
+ }
+ }
+
/**
* Start the command line front end for mutant.
*
* @param args the commandline arguments
- * @param config the initialisation configuration
+ * @param initConfig Ant's initialization configuration
*/
- private void process(String[] args, InitConfig config) {
- this.config = config;
+ private void process(String[] args, InitConfig initConfig) {
+ this.config = initConfig;
+ System.out.println("Ant Home is " + initConfig.getAntHome());
try {
parseArguments(args);
+
+ AntConfig userConfig = getAntConfig(initConfig.getUserConfigArea());
+ AntConfig systemConfig
+ = getAntConfig(initConfig.getSystemConfigArea());
+
+ AntConfig config = systemConfig;
+ if (config == null) {
+ config = userConfig;
+ } else if (userConfig != null) {
+ config.merge(userConfig);
+ }
+
+ if (!buildFileURL.getProtocol().equals("file")
+ && !config.isRemoteProjectAllowed()) {
+ throw new ConfigException("Remote Projects are not allowed: "
+ + buildFileURL);
+ }
+
Project project = parseProject();
// create the execution manager to execute the build
- ExecutionManager executionManager = new ExecutionManager(config);
+ ExecutionManager executionManager
+ = new ExecutionManager(initConfig, config);
addBuildListeners(executionManager);
executionManager.runBuild(project, targets);
- } catch (AntException e) {
- Location location = e.getLocation();
- Throwable cause = e.getCause();
- System.out.println(e.getMessage());
-
- if (cause != null) {
- System.out.print("Root cause: " + cause.getClass().getName());
- if (!cause.getMessage().equals(e.getMessage())) {
- System.out.print(": " + cause.getMessage());
+ } catch (Throwable t) {
+ if (t instanceof AntException) {
+ AntException e = (AntException)t;
+ Location location = e.getLocation();
+ Throwable cause = e.getCause();
+ if (location != null && location != Location.UNKNOWN_LOCATION) {
+ System.out.print(location);
}
- System.out.println();
- }
+ System.out.println(e.getMessage());
- e.printStackTrace();
+ if (messageOutputLevel >= MessageLevel.MSG_VERBOSE) {
+ t.printStackTrace();
+ }
+
+ if (cause != null) {
+ System.out.println("Root cause: " + cause.toString());
+ }
+ } else {
+ t.printStackTrace(System.err);
+ }
- System.exit(1);
- } catch (Throwable t) {
- t.printStackTrace();
System.exit(1);
}
}
@@ -224,20 +285,21 @@ public class Commandline {
*/
private void parseArguments(String[] args)
throws ConfigException {
- for (int i = 0; i < args.length; i++) {
- String arg = args[i];
+
+ int i = 0;
+ while (i < args.length) {
+ String arg = args[i++];
if (arg.equals("-buildfile") || arg.equals("-file")
|| arg.equals("-f")) {
try {
- String url = args[i + 1];
+ String url = args[i++];
if (url.indexOf(":") == -1) {
// We convert any hash characters to their URL escape.
buildFileURL = InitUtils.getFileURL(new File(url));
} else {
buildFileURL = new URL(url);
}
- i++;
} catch (MalformedURLException e) {
System.err.println("Buildfile is not valid: " +
e.getMessage());
@@ -249,8 +311,7 @@ public class Commandline {
}
} else if (arg.equals("-logfile") || arg.equals("-l")) {
try {
- File logFile = new File(args[i + 1]);
- i++;
+ File logFile = new File(args[i++]);
out = new PrintStream(new FileOutputStream(logFile));
err = out;
} catch (IOException ioe) {
@@ -270,8 +331,7 @@ public class Commandline {
messageOutputLevel = MessageLevel.MSG_VERBOSE;
} else if (arg.equals("-listener")) {
try {
- listeners.add(args[i + 1]);
- i++;
+ listeners.add(args[i++]);
} catch (ArrayIndexOutOfBoundsException aioobe) {
System.err.println("You must specify a classname when " +
"using the -listener argument");
@@ -284,7 +344,7 @@ public class Commandline {
return;
}
try {
- loggerClassname = args[++i];
+ loggerClassname = args[i++];
} catch (ArrayIndexOutOfBoundsException aioobe) {
System.err.println("You must specify a classname when " +
"using the -logger argument");
diff --git a/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java b/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java
index 2bdc977eb..c3bc61f8f 100755
--- a/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java
+++ b/proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java
@@ -57,7 +57,7 @@ import java.io.PrintStream;
import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.Location;
import org.apache.ant.common.util.MessageLevel;
-import org.apache.ant.antcore.event.BuildEvent;
+import org.apache.ant.common.event.BuildEvent;
import org.apache.ant.antcore.model.BuildElement;
import org.apache.ant.antcore.model.Target;
@@ -170,7 +170,7 @@ public class DefaultLogger implements BuildLogger {
out.println(e.getMessage());
if (messageOutputLevel >= MessageLevel.MSG_VERBOSE) {
- t.printStackTrace();
+ t.printStackTrace(out);
}
if (cause != null) {
@@ -207,7 +207,7 @@ public class DefaultLogger implements BuildLogger {
break;
case BuildEvent.TARGET_STARTED:
if (MessageLevel.MSG_INFO <= messageOutputLevel) {
- Target target = (Target)event.getModelElement();
+ Target target = (Target)event.getSource();
out.println(lSep + target.getName() + ":");
}
break;
@@ -223,10 +223,10 @@ public class DefaultLogger implements BuildLogger {
// Filter out messages based on priority
if (event.getPriority() <= messageOutputLevel
- && event.getModelElement() instanceof BuildElement) {
+ && event.getSource() instanceof BuildElement) {
// Print out the name of the task if we're in one
BuildElement buildElement
- = (BuildElement)event.getModelElement();
+ = (BuildElement)event.getSource();
String name = buildElement.getType();
if (!emacsMode) {
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/converter/AbstractConverter.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractConverter.java
old mode 100755
new mode 100644
similarity index 85%
rename from proposal/mutant/src/java/common/org/apache/ant/common/converter/AbstractConverter.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractConverter.java
index e1e07db78..b7a461b58
--- a/proposal/mutant/src/java/common/org/apache/ant/common/converter/AbstractConverter.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractConverter.java
@@ -51,9 +51,8 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.converter;
+package org.apache.ant.common.antlib;
-import org.apache.ant.common.context.AntContext;
/**
* Abstract implementation of the Converter interface
@@ -82,5 +81,19 @@ public abstract class AbstractConverter implements Converter {
protected AntContext getContext() {
return context;
}
+
+ /**
+ * 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
+ * the given subclass of one of its main class
+ */
+ public boolean canConvertSubType(Class subType) {
+ return false;
+ }
+
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/task/AbstractTask.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
old mode 100755
new mode 100644
similarity index 97%
rename from proposal/mutant/src/java/common/org/apache/ant/common/task/AbstractTask.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
index c0e488e38..6c8e705a3
--- a/proposal/mutant/src/java/common/org/apache/ant/common/task/AbstractTask.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
@@ -51,8 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.task;
-import org.apache.ant.common.context.AntContext;
+package org.apache.ant.common.antlib;
/**
* Abstract implementation of the Task interface
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
new file mode 100644
index 000000000..67d475c81
--- /dev/null
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
@@ -0,0 +1,104 @@
+/*
+ * 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 java.io.File;
+
+import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.Location;
+
+/**
+ * The AntContext is the interface through which the Ant container and the
+ * Ant components communicate. Common operations are provided directly in
+ * this interface. Other core services are available through the generic
+ * service objects supported by the core.
+ *
+ * @author Conor MacNeill
+ * @created 14 January 2002
+ */
+public interface AntContext {
+ /**
+ * Log a message
+ *
+ * @param message the message to be logged
+ * @param level the priority level of the message
+ */
+ void log(String message, int level);
+
+ /**
+ * Get a instance of the specified service interface with which to
+ * interact with the core.
+ *
+ * @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
+ */
+ Object getCoreService(Class serviceInterfaceClass)
+ throws ExecutionException;
+
+ /**
+ * Get the build file location with which this context is associated.
+ *
+ * @return the associated build file location
+ */
+ Location getLocation();
+
+ /**
+ * Get the basedir for the current execution
+ *
+ * @return the base directory for this execution of Ant
+ */
+ File getBaseDir();
+}
+
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
new file mode 100644
index 000000000..040a36ed4
--- /dev/null
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java
@@ -0,0 +1,116 @@
+/*
+ * 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.ExecutionException;
+
+/**
+ * An Ant Library Factory is a class is used to create instances of the
+ * classes in the AntLibrary. An separate instance of the factory will be
+ * created by each ExecutiuonFrame which uses this library. The factory will
+ * be created before any instances are required.
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public interface AntLibFactory {
+ /**
+ * Create an instance of the given type class
+ *
+ * @param typeClass the class for which an instance is required
+ * @return an instance of the required class
+ * @exception InstantiationException if the class cannot be instantiated
+ * @exception IllegalAccessException if the instance cannot be accessed
+ * @exception ExecutionException if there is a problem creating the type
+ */
+ Object createTypeInstance(Class typeClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException;
+
+ /**
+ * Initialise the factory
+ *
+ * @param context the factory's context
+ * @exception ExecutionException if the factory cannot be initialized
+ */
+ void init(AntContext context) throws ExecutionException;
+
+ /**
+ * Create an instance of the given task class
+ *
+ * @param taskClass the class for which an instance is required
+ * @return an instance of the required class
+ * @exception InstantiationException if the class cannot be instantiated
+ * @exception IllegalAccessException if the instance cannot be accessed
+ * @exception ExecutionException if there is a problem creating the task
+ */
+ Object createTaskInstance(Class taskClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException;
+
+ /**
+ * Create an instance of the given converter class
+ *
+ * @param converterClass the converter class for which an instance is
+ * required
+ * @return a converter instance
+ * @exception InstantiationException if the class cannot be instantiated
+ * @exception IllegalAccessException if the instance cannot be accessed
+ * @exception ExecutionException if there is a problem creating the
+ * converter
+ */
+ Converter createConverter(Class converterClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException;
+}
+
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/converter/Converter.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Converter.java
old mode 100755
new mode 100644
similarity index 83%
rename from proposal/mutant/src/java/common/org/apache/ant/common/converter/Converter.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/Converter.java
index 07c4f4548..b697df883
--- a/proposal/mutant/src/java/common/org/apache/ant/common/converter/Converter.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Converter.java
@@ -51,9 +51,9 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.converter;
+package org.apache.ant.common.antlib;
-import org.apache.ant.common.context.AntContext;
+import org.apache.ant.common.util.ExecutionException;
/**
* Convert between a string and a data type
@@ -69,9 +69,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 ConversionException if the conversion cannot be made
+ * @exception ExecutionException if the conversion cannot be made
*/
- Object convert(String value, Class type) throws ConversionException;
+ Object convert(String value, Class type) throws ExecutionException;
/**
* Initialise the converter. The converter may use the AntContext to
@@ -88,5 +88,17 @@ public interface Converter {
* converter handles.
*/
Class[] getTypes();
+
+
+ /**
+ * 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
+ * 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/task/DataType.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/DataType.java
old mode 100755
new mode 100644
similarity index 89%
rename from proposal/mutant/src/java/common/org/apache/ant/common/task/DataType.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/DataType.java
index 256e154a6..5da1bb939
--- a/proposal/mutant/src/java/common/org/apache/ant/common/task/DataType.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/DataType.java
@@ -51,8 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.task;
-import org.apache.ant.common.context.AntContext;
+package org.apache.ant.common.antlib;
/**
* This is the interface used to descibe Ant types. A class used as a
@@ -62,13 +61,6 @@ import org.apache.ant.common.context.AntContext;
* @author Conor MacNeill
* @created 20 January 2002
*/
-public interface DataType {
- /**
- * Initialise the type instance. The type instance may use the
- * AntContext to request services from the Ant core.
- *
- * @param context the type's context
- */
- void init(AntContext context);
+public interface DataType extends ExecutionComponent {
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/task/Task.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
old mode 100755
new mode 100644
similarity index 85%
rename from proposal/mutant/src/java/common/org/apache/ant/common/task/Task.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
index 1bb2c41f4..e80392f52
--- a/proposal/mutant/src/java/common/org/apache/ant/common/task/Task.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
@@ -51,32 +51,24 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.task;
-import org.apache.ant.common.context.AntContext;
+package org.apache.ant.common.antlib;
+import org.apache.ant.common.util.ExecutionException;
/**
- * The Task interface defines the methods that a Task must implement.
+ * An execution component is a component from an AntLibrary which is used in the
+ * execution of an Ant build. A component can have a context.
*
* @author Conor MacNeill
- * @created 16 January 2002
+ * @created 1 February 2002
*/
-public interface Task {
+public interface ExecutionComponent {
/**
* Initialise the task. The task may use the AntContext to request
* services from the Ant core.
*
* @param context the Task's context
+ * @exception ExecutionException if the component cannot be initialised
*/
- void init(AntContext context);
-
- /**
- * Execute the task.
- *
- * @exception TaskException if the task has a problem executing.
- */
- void execute() throws TaskException;
-
- /** Task is about to be cleaned up */
- void destroy();
+ void init(AntContext context) throws ExecutionException;
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/converter/ConversionException.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
old mode 100755
new mode 100644
similarity index 54%
rename from proposal/mutant/src/java/common/org/apache/ant/common/converter/ConversionException.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
index b92185b36..8a5ba729e
--- a/proposal/mutant/src/java/common/org/apache/ant/common/converter/ConversionException.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
@@ -51,85 +51,72 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.converter;
-
-import org.apache.ant.common.util.AntException;
-import org.apache.ant.common.util.Location;
+package org.apache.ant.common.antlib;
+import org.apache.ant.common.util.ExecutionException;
/**
- * Exception class for problems when converting values
+ * Standard Ant Library Factory
*
* @author Conor MacNeill
- * @created 20 January 2002
+ * @created 1 February 2002
+ * @see AntLibFactory
*/
-public class ConversionException extends AntException {
+public class StandardLibFactory implements AntLibFactory {
/**
- * Constructs an exception with the given descriptive message.
+ * Create an instance of the given task class
*
- * @param msg Description of or information about the exception.
+ * @param taskClass the class for which an instance is required
+ * @return an instance of the required class
+ * @exception InstantiationException if the class cannot be instantiated
+ * @exception IllegalAccessException if the instance cannot be accessed
+ * @exception ExecutionException if there is a problem creating the task
*/
- public ConversionException(String msg) {
- super(msg);
+ public Object createTaskInstance(Class taskClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException {
+ return taskClass.newInstance();
}
-
/**
- * Constructs an exception with the given descriptive message and a
- * location in a file.
+ * Create an instance of the given type class
*
- * @param msg Description of or information about the exception.
- * @param location Location in the project file where the error occured.
+ * @param typeClass the class for which an instance is required
+ * @return an instance of the required class
+ * @exception InstantiationException if the class cannot be instantiated
+ * @exception IllegalAccessException if the instance cannot be accessed
+ * @exception ExecutionException if there is a problem creating the type
*/
- public ConversionException(String msg, Location location) {
- super(msg, location);
+ public Object createTypeInstance(Class typeClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException {
+ return typeClass.newInstance();
}
-
/**
- * Constructs an exception with the given message and exception as a
- * root cause.
+ * Initilaise the factory
*
- * @param msg Description of or information about the exception.
- * @param cause Throwable that might have cause this one.
+ * @param context the factory's context
+ * @exception ExecutionException if the factory cannot be initialized
*/
- public ConversionException(String msg, Throwable cause) {
- super(msg, cause);
+ public void init(AntContext context) throws ExecutionException {
+ // do nothing
}
-
/**
- * Constructs an exception with the given message and exception as a
- * root cause and a location in a file.
+ * Create an instance of the given converter class
*
- * @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.
+ * @param converterClass the converter class for which an instance is
+ * required
+ * @return a converter instance
+ * @exception InstantiationException if the class cannot be instantiated
+ * @exception IllegalAccessException if the instance cannot be accessed
+ * @exception ExecutionException if there is a problem creating the
+ * converter
*/
- public ConversionException(String msg, Throwable cause, Location location) {
- super(msg, cause, location);
+ public Converter createConverter(Class converterClass)
+ throws InstantiationException, IllegalAccessException,
+ ExecutionException {
+ return (Converter)converterClass.newInstance();
}
-
-
- /**
- * Constructs an exception with the given exception as a root cause.
- *
- * @param cause Exception that might have caused this one.
- */
- public ConversionException(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 ConversionException(Throwable cause, Location location) {
- super(cause, location);
- }
-
}
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
new file mode 100644
index 000000000..a3f8a3af5
--- /dev/null
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ExecutionException;
+
+/**
+ * The Task interface defines the methods that a Task must implement.
+ *
+ * @author Conor MacNeill
+ * @created 16 January 2002
+ */
+public interface Task extends ExecutionComponent {
+ /**
+ * Execute the task.
+ *
+ * @exception ExecutionException if the task has a problem executing.
+ */
+ void execute() throws ExecutionException;
+
+ /** Task is about to be cleaned up */
+ void destroy();
+}
+
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/task/TaskContainer.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java
old mode 100755
new mode 100644
similarity index 92%
rename from proposal/mutant/src/java/common/org/apache/ant/common/task/TaskContainer.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java
index 2397dce02..e7bdeb52a
--- a/proposal/mutant/src/java/common/org/apache/ant/common/task/TaskContainer.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/TaskContainer.java
@@ -51,7 +51,8 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.task;
+package org.apache.ant.common.antlib;
+import org.apache.ant.common.util.ExecutionException;
/**
* A TaskContainer is an object which can contain and manage ExecutionTasks.
@@ -64,8 +65,8 @@ public interface TaskContainer {
* Add a task to the container.
*
* @param task the task tobe added
- * @exception TaskException if the container cannot add the task
+ * @exception ExecutionException if the container cannot add the task
*/
- void addTask(Task task) throws TaskException;
+ void addTask(Task task) throws ExecutionException;
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildEvent.java b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
old mode 100755
new mode 100644
similarity index 86%
rename from proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildEvent.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
index aec2fd0e1..281deead3
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildEvent.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
@@ -51,10 +51,9 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.antcore.event;
+package org.apache.ant.common.event;
import java.util.EventObject;
-import org.apache.ant.antcore.model.ModelElement;
/**
* A BuildEvent indicates the occurence of a significant event in the build.
@@ -95,10 +94,10 @@ public class BuildEvent extends EventObject {
* Create a build event.
*
* @param eventType the type of the buildEvent.
- * @param modelElement the element with which this event is associated
+ * @param source the element with which this event is associated
*/
- public BuildEvent(ModelElement modelElement, int eventType) {
- super(modelElement);
+ public BuildEvent(Object source, int eventType) {
+ super(source);
this.eventType = eventType;
}
@@ -107,25 +106,25 @@ public class BuildEvent extends EventObject {
*
* @param eventType the type of the buildEvent.
* @param cause An exception if associated with the event
- * @param modelElement the element with which this event is associated
+ * @param source the object with which this event is associated
*/
- public BuildEvent(ModelElement modelElement, int eventType,
+ public BuildEvent(Object source, int eventType,
Throwable cause) {
- this(modelElement, eventType);
+ this(source, eventType);
this.cause = cause;
}
/**
* Create a build event for a message
*
- * @param modelElement the build element with which the event is
+ * @param source the object with which the event is
* associated.
* @param message the message associated with this event
* @param priority the message priority
*/
- public BuildEvent(ModelElement modelElement, String message,
+ public BuildEvent(Object source, String message,
int priority) {
- this(modelElement, MESSAGE);
+ this(source, MESSAGE);
this.message = message;
this.messagePriority = priority;
}
@@ -139,15 +138,6 @@ public class BuildEvent extends EventObject {
return eventType;
}
- /**
- * Get the build element involved in this event.
- *
- * @return the build element to which this event is associated.
- */
- public ModelElement getModelElement() {
- return (ModelElement)getSource();
- }
-
/**
* Returns the logging message. This field will only be set for
* "messageLogged" events.
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildListener.java b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListener.java
old mode 100755
new mode 100644
similarity index 98%
rename from proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildListener.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListener.java
index 6e23c2b54..86d830f85
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/event/BuildListener.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildListener.java
@@ -51,7 +51,7 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.antcore.event;
+package org.apache.ant.common.event;
import java.util.EventListener;
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
new file mode 100644
index 000000000..8599b12c8
--- /dev/null
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
@@ -0,0 +1,84 @@
+/*
+ * 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;
+import org.apache.ant.common.util.ExecutionException;
+
+/**
+ * The Component Service is used to manage the definitions that Ant uses at
+ * runtime. It supports the following operations
+ *
+ * - Definition of library search paths
+ *
- Importing tasks from a library
+ *
- taskdefs
+ *
- typedefs
+ *
+ *
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public interface ComponentService {
+ /**
+ * Load a single or multiple Ant libraries
+ *
+ * @param libLocation the location of the library or the libraries
+ * @param importAll true if all components of the loaded libraries
+ * should be imported
+ * @exception ExecutionException if the library or libraries cannot be
+ * imported.
+ */
+ void loadLib(String libLocation, boolean importAll)
+ throws ExecutionException;
+}
+
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
new file mode 100644
index 000000000..9f02cdb6e
--- /dev/null
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/DataService.java
@@ -0,0 +1,132 @@
+/*
+ * 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;
+import java.util.Map;
+
+import org.apache.ant.common.util.ExecutionException;
+
+/**
+ * Service interface for Data value manipulation operations provided by the
+ * core.
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public interface DataService {
+ /**
+ * Get a data value
+ *
+ * @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.
+ */
+ Object getDataValue(String valueName) throws ExecutionException;
+
+ /**
+ * Indicate if a data value has been set
+ *
+ * @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
+ * does not exist
+ */
+ boolean isDataValueSet(String name) throws ExecutionException;
+
+ /**
+ * Set a data value. If an existing data value exists, associated with
+ * the given name, the value will not be changed
+ *
+ * @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
+ */
+ void setDataValue(String valueName, Object value) throws ExecutionException;
+
+ /**
+ * 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
+ */
+ void setMutableDataValue(String valueName, Object value)
+ throws ExecutionException;
+
+ /**
+ * Replace ${} style constructions in the given value with the string
+ * value of the corresponding data values in the frame
+ *
+ * @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
+ */
+ String replacePropertyRefs(String value) throws ExecutionException;
+
+ /**
+ * Replace ${} style constructions in the given value with the string
+ * value of the objects in the given map. Any values which are not found
+ * are left unchanged.
+ *
+ * @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
+ */
+ String replacePropertyRefs(String value, Map replacementValues)
+ throws ExecutionException;
+
+}
+
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/context/AntContext.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/FileService.java
old mode 100755
new mode 100644
similarity index 82%
rename from proposal/mutant/src/java/common/org/apache/ant/common/context/AntContext.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/service/FileService.java
index cd62184c0..43f89f6b2
--- a/proposal/mutant/src/java/common/org/apache/ant/common/context/AntContext.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/FileService.java
@@ -51,35 +51,27 @@
* information on the Apache Software Foundation, please see
* .
*/
-package org.apache.ant.common.context;
+package org.apache.ant.common.service;
import java.io.File;
-import org.apache.ant.common.util.AntException;
+import org.apache.ant.common.util.ExecutionException;
/**
- * The TaskContext is the interface through which the Ant Task container and
- * the Task instances communicate
+ * Service interface for File manipulation operations provided by the Ant
+ * Core
*
* @author Conor MacNeill
- * @created 14 January 2002
+ * @created 27 January 2002
*/
-public abstract class AntContext {
- /**
- * Log a message
- *
- * @param message the message to be logged
- * @param level the priority level of the message
- */
- public abstract void log(String message, int level);
-
+public interface FileService {
/**
* Resolve a file according to the base directory of the project
* associated with this context
*
* @param fileName the file name to be resolved.
* @return the file resolved to the project's base dir
- * @exception AntException if the file cannot be resolved
+ * @exception ExecutionException if the file cannot be resolved
*/
- public abstract File resolveFile(String fileName) throws AntException;
+ File resolveFile(String fileName) throws ExecutionException;
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/GeneralAntException.java b/proposal/mutant/src/java/common/org/apache/ant/common/util/ExecutionException.java
old mode 100755
new mode 100644
similarity index 88%
rename from proposal/mutant/src/java/common/org/apache/ant/common/util/GeneralAntException.java
rename to proposal/mutant/src/java/common/org/apache/ant/common/util/ExecutionException.java
index c930d8299..9a8aec1ff
--- a/proposal/mutant/src/java/common/org/apache/ant/common/util/GeneralAntException.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/ExecutionException.java
@@ -54,19 +54,19 @@
package org.apache.ant.common.util;
/**
- * An GeneralAntException is used to for any exception case for which there
- * is no specific AntException subclass which is appropriate
+ * An ExecutionException indicates a problem while executing tasks in a
+ * build
*
* @author Conor MacNeill
- * @created 21 January 2002
+ * @created 20 January 2002
*/
-public class GeneralAntException extends AntException {
+public class ExecutionException extends AntException {
/**
* Constructs an exception with the given descriptive message.
*
* @param msg Description of or information about the exception.
*/
- public GeneralAntException(String msg) {
+ public ExecutionException(String msg) {
super(msg);
}
@@ -78,7 +78,7 @@ public class GeneralAntException extends AntException {
* @param msg Description of or information about the exception.
* @param location Location in the project file where the error occured.
*/
- public GeneralAntException(String msg, Location location) {
+ public ExecutionException(String msg, Location location) {
super(msg, location);
}
@@ -90,7 +90,7 @@ public class GeneralAntException extends AntException {
* @param msg Description of or information about the exception.
* @param cause Throwable that might have cause this one.
*/
- public GeneralAntException(String msg, Throwable cause) {
+ public ExecutionException(String msg, Throwable cause) {
super(msg, cause);
}
@@ -103,7 +103,7 @@ public class GeneralAntException extends AntException {
* @param cause Exception that might have cause this one.
* @param location Location in the project file where the error occured.
*/
- public GeneralAntException(String msg, Throwable cause, Location location) {
+ public ExecutionException(String msg, Throwable cause, Location location) {
super(msg, cause, location);
}
@@ -113,7 +113,7 @@ public class GeneralAntException extends AntException {
*
* @param cause Exception that might have caused this one.
*/
- public GeneralAntException(Throwable cause) {
+ public ExecutionException(Throwable cause) {
super(cause);
}
@@ -125,7 +125,7 @@ public class GeneralAntException extends AntException {
* @param cause Exception that might have cause this one.
* @param location Location in the project file where the error occured.
*/
- public GeneralAntException(Throwable cause, Location location) {
+ public ExecutionException(Throwable cause, Location location) {
super(cause, location);
}
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 bfe62ae18..d7b6afdc8 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
@@ -78,32 +78,32 @@ public class FileUtils {
* null, this call is equivalent to
* new java.io.File(filename)
* .
- * @param filename a file name
+ * @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 GeneralAntException if the file cannot be resolved
+ * @exception ExecutionException if the file cannot be resolved
*/
public File resolveFile(File file, String filename)
- throws GeneralAntException {
- filename = filename.replace('/', File.separatorChar)
+ throws ExecutionException {
+ String platformFilename = filename.replace('/', File.separatorChar)
.replace('\\', File.separatorChar);
// deal with absolute files
- if (filename.startsWith(File.separator) ||
- (filename.length() >= 2 &&
- Character.isLetter(filename.charAt(0)) &&
- filename.charAt(1) == ':')
- ) {
- return normalize(filename);
+ if (platformFilename.startsWith(File.separator) ||
+ (platformFilename.length() >= 2 &&
+ Character.isLetter(platformFilename.charAt(0)) &&
+ platformFilename.charAt(1) == ':')) {
+ return normalize(platformFilename);
}
if (file == null) {
- return new File(filename);
+ return new File(platformFilename);
}
File helpFile = new File(file.getAbsolutePath());
- StringTokenizer tok = new StringTokenizer(filename, File.separator);
+ StringTokenizer tok
+ = new StringTokenizer(platformFilename, File.separator);
while (tok.hasMoreTokens()) {
String part = tok.nextToken();
if (part.equals("..")) {
@@ -112,7 +112,7 @@ public class FileUtils {
String msg = "The file or path you specified ("
+ filename + ") is invalid relative to "
+ file.getPath();
- throw new GeneralAntException(msg);
+ throw new ExecutionException(msg);
}
} else if (part.equals(".")) {
// Do nothing here
@@ -138,37 +138,35 @@ public class FileUtils {
*
*
* @param path the path to be normalized
- * @return the normalized path
- * @exception GeneralAntException if there is a problem with the path
+ * @return the normalized path
+ * @exception ExecutionException 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, GeneralAntException {
- String orig = path;
+ public File normalize(String path)
+ throws NullPointerException, ExecutionException {
- path = path.replace('/', File.separatorChar)
+ String platformPath = path.replace('/', File.separatorChar)
.replace('\\', File.separatorChar);
// make sure we are dealing with an absolute path
- if (!path.startsWith(File.separator) &&
- !(path.length() >= 2 &&
- Character.isLetter(path.charAt(0)) &&
- path.charAt(1) == ':')
- ) {
+ if (!platformPath.startsWith(File.separator) &&
+ !(platformPath.length() >= 2 &&
+ Character.isLetter(platformPath.charAt(0)) &&
+ platformPath.charAt(1) == ':')) {
String msg = path + " is not an absolute path";
- throw new GeneralAntException(msg);
+ throw new ExecutionException(msg);
}
boolean dosWithDrive = false;
String root = null;
// Eliminate consecutive slashes after the drive spec
- if (path.length() >= 2 &&
- Character.isLetter(path.charAt(0)) &&
- path.charAt(1) == ':') {
+ if (platformPath.length() >= 2 &&
+ Character.isLetter(platformPath.charAt(0)) &&
+ platformPath.charAt(1) == ':') {
dosWithDrive = true;
- char[] ca = path.replace('/', '\\').toCharArray();
+ char[] ca = platformPath.replace('/', '\\').toCharArray();
StringBuffer sb = new StringBuffer();
sb.append(Character.toUpperCase(ca[0])).append(':');
@@ -180,40 +178,40 @@ public class FileUtils {
}
}
- path = sb.toString().replace('\\', File.separatorChar);
- if (path.length() == 2) {
- root = path;
- path = "";
+ platformPath = sb.toString().replace('\\', File.separatorChar);
+ if (platformPath.length() == 2) {
+ root = platformPath;
+ platformPath = "";
} else {
- root = path.substring(0, 3);
- path = path.substring(3);
+ root = platformPath.substring(0, 3);
+ platformPath = platformPath.substring(3);
}
} else {
- if (path.length() == 1) {
+ if (platformPath.length() == 1) {
root = File.separator;
- path = "";
- } else if (path.charAt(1) == File.separatorChar) {
+ platformPath = "";
+ } else if (platformPath.charAt(1) == File.separatorChar) {
// UNC drive
root = File.separator + File.separator;
- path = path.substring(2);
+ platformPath = platformPath.substring(2);
} else {
root = File.separator;
- path = path.substring(1);
+ platformPath = platformPath.substring(1);
}
}
Stack s = new Stack();
s.push(root);
- StringTokenizer tok = new StringTokenizer(path, File.separator);
+ StringTokenizer tok = new StringTokenizer(platformPath, File.separator);
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (".".equals(thisToken)) {
continue;
} else if ("..".equals(thisToken)) {
if (s.size() < 2) {
- throw new GeneralAntException("Cannot resolve path "
- + orig);
+ throw new ExecutionException("Cannot resolve path "
+ + path);
} else {
s.pop();
}
@@ -232,11 +230,11 @@ public class FileUtils {
sb.append(s.elementAt(i));
}
- path = sb.toString();
+ platformPath = sb.toString();
if (dosWithDrive) {
- path = path.replace('/', '\\');
+ platformPath = platformPath.replace('/', '\\');
}
- return new File(path);
+ return new File(platformPath);
}
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/Location.java b/proposal/mutant/src/java/common/org/apache/ant/common/util/Location.java
index bdda5a012..dadebc835 100755
--- a/proposal/mutant/src/java/common/org/apache/ant/common/util/Location.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/Location.java
@@ -97,16 +97,16 @@ public class Location {
}
/** Creates an "unknown" location. */
- private Location() {
+ public Location() {
this(null, 0, 0);
}
/**
- * Get the source URL for this location
+ * Get the source for this location
*
- * @return a URL string
+ * @return the location's source
*/
- public String getSourceURL() {
+ public String getSource() {
return source;
}
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
new file mode 100644
index 000000000..6759c6905
--- /dev/null
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/PropertyUtils.java
@@ -0,0 +1,126 @@
+/*
+ * 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.util;
+
+import java.util.List;
+
+/**
+ * A set of utilities for handling Ant properties and values
+ *
+ * @author Conor MacNeill
+ * @created 31 January 2002
+ */
+public class PropertyUtils {
+ /**
+ * This method will parse a string containing ${value} style property
+ * values into two lists. The first list is a collection of text
+ * fragments, while the other is a set of string property names. Null
+ * entries in the first list indicate a property reference from the
+ * second list.
+ *
+ * @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
+ * values
+ */
+ public static void parsePropertyString(String value, List fragments,
+ List propertyRefs)
+ throws ExecutionException {
+ int prev = 0;
+ int pos;
+ while ((pos = value.indexOf("$", prev)) >= 0) {
+ if (pos > 0) {
+ fragments.add(value.substring(prev, pos));
+ }
+
+ if (pos == (value.length() - 1)) {
+ fragments.add("$");
+ prev = pos + 1;
+ } else if (value.charAt(pos + 1) != '{') {
+ fragments.add(value.substring(pos + 1, pos + 2));
+ prev = pos + 2;
+ } else {
+ int endName = value.indexOf('}', pos);
+ if (endName < 0) {
+ throw new ExecutionException("Syntax error in property: "
+ + value);
+ }
+ String propertyName = value.substring(pos + 2, endName);
+ fragments.add(null);
+ propertyRefs.add(propertyName);
+ prev = endName + 1;
+ }
+ }
+
+ if (prev < value.length()) {
+ fragments.add(value.substring(prev));
+ }
+ }
+
+ /**
+ * returns the boolean equivalent of a string, which is considered true
+ * if either "on", "true", or "yes" is found, ignoring case.
+ *
+ * @param s the string value to be interpreted at a boolean
+ * @return the value of s as a boolean
+ */
+ public static boolean toBoolean(String s) {
+ return (s != null && (s.equalsIgnoreCase("on")
+ || s.equalsIgnoreCase("true")
+ || s.equalsIgnoreCase("yes")));
+ }
+
+}
+
diff --git a/proposal/mutant/src/java/init/org/apache/ant/init/InitConfig.java b/proposal/mutant/src/java/init/org/apache/ant/init/InitConfig.java
index 7d259f7ac..51d3f97a8 100755
--- a/proposal/mutant/src/java/init/org/apache/ant/init/InitConfig.java
+++ b/proposal/mutant/src/java/init/org/apache/ant/init/InitConfig.java
@@ -54,6 +54,7 @@
package org.apache.ant.init;
import java.net.URL;
+import java.io.File;
/**
* InitConfig is the initialization configuration created to start Ant. This
@@ -98,20 +99,20 @@ public class InitConfig {
private URL libraryURL;
/** The location of the system configuration file */
- private URL systemConfigArea;
+ private File systemConfigArea;
/** The location of ANT_HOME */
private URL antHome;
/** The location of the user config file */
- private URL userConfigArea;
+ private File userConfigArea;
/**
* Sets the location of the user configuration files
*
* @param userConfigArea the new user config area
*/
- public void setUserConfigArea(URL userConfigArea) {
+ public void setUserConfigArea(File userConfigArea) {
this.userConfigArea = userConfigArea;
}
@@ -129,7 +130,7 @@ public class InitConfig {
*
* @param systemConfigArea the new system config area
*/
- public void setSystemConfigArea(URL systemConfigArea) {
+ public void setSystemConfigArea(File systemConfigArea) {
this.systemConfigArea = systemConfigArea;
}
@@ -192,7 +193,7 @@ public class InitConfig {
*
* @return the location of the user's Ant config files
*/
- public URL getUserConfigArea() {
+ public File getUserConfigArea() {
return userConfigArea;
}
@@ -210,7 +211,7 @@ public class InitConfig {
*
* @return the location of the system Ant config files
*/
- public URL getSystemConfigArea() {
+ public File getSystemConfigArea() {
return systemConfigArea;
}
diff --git a/proposal/mutant/src/java/init/org/apache/ant/init/LoaderUtils.java b/proposal/mutant/src/java/init/org/apache/ant/init/LoaderUtils.java
index db88b3ec8..12b04d4b9 100755
--- a/proposal/mutant/src/java/init/org/apache/ant/init/LoaderUtils.java
+++ b/proposal/mutant/src/java/init/org/apache/ant/init/LoaderUtils.java
@@ -81,38 +81,38 @@ public class LoaderUtils {
/**
- * Get the URLs to create class loader from the jars in a given location
+ * Get the URLs of a set of libraries in the given location
*
- * @param baseURL the baeURL is the location of the libs directory
+ * @param location the location to be searched
* @param defaultFile default file if none can be found
* @return an array of URLs for the relevant jars
* @exception MalformedURLException the URLs cannot be created
*/
- public static URL[] getLoaderURLs(URL baseURL, String defaultFile)
+ public static URL[] getLocationURLs(URL location, String defaultFile)
throws MalformedURLException {
- return getLoaderURLs(baseURL, defaultFile, new String[]{".jar"});
+ return getLocationURLs(location, defaultFile, new String[]{".jar"});
}
/**
- * Get the URLs for a class loader
+ * Get the URLs of a set of libraries in the given location
*
- * @param baseURL the baeURL is the location of the libs directory
+ * @param location the location to be searched
* @param extensions array of allowable file extensions
* @param defaultFile default file if none can be found
* @return an array of URLs for the relevant jars
* @exception MalformedURLException if the URL to the jars could not be
* formed
*/
- public static URL[] getLoaderURLs(URL baseURL, String defaultFile,
- String[] extensions)
+ public static URL[] getLocationURLs(URL location, String defaultFile,
+ String[] extensions)
throws MalformedURLException {
URL[] urls = null;
- if (baseURL.getProtocol().equals("file")) {
+ if (location.getProtocol().equals("file")) {
// URL is local filesystem.
- urls = getDirectoryURLs(new File(baseURL.getFile()), extensions);
+ urls = getLocalURLs(new File(location.getFile()), extensions);
} else {
// URL is remote - try to read a file with the list of jars
- URL jarListURL = new URL(baseURL, LIST_FILE);
+ URL jarListURL = new URL(location, LIST_FILE);
BufferedReader reader = null;
List jarList = new ArrayList();
try {
@@ -123,7 +123,7 @@ public class LoaderUtils {
while ((line = reader.readLine().trim()) != null) {
for (int i = 0; i < extensions.length; ++i) {
if (line.endsWith(extensions[i])) {
- jarList.add(new URL(baseURL, line));
+ jarList.add(new URL(location, line));
break;
}
}
@@ -132,7 +132,7 @@ public class LoaderUtils {
} catch (IOException e) {
// use the default location
if (defaultFile != null) {
- urls = new URL[]{new URL(baseURL, defaultFile)};
+ urls = new URL[]{new URL(location, defaultFile)};
}
} finally {
if (reader != null) {
@@ -180,25 +180,40 @@ public class LoaderUtils {
/**
- * Get an array of URLs for each jar file in the directory
+ * Get an array of URLs for each file in the filesystem. If the given
+ * location is a directory, it is searched for files of the given
+ * extension. If it is a file, it is returned as a URL if it matches the
+ * given extension list.
*
- * @param directory the local directory
+ * @param location the location within the local filesystem to be
+ * searched
* @param extensions an array of file extensions to be considered in the
* search
* @return an array of URLs for the file found in the directory.
* @exception MalformedURLException if the URLs to the jars cannot be
* formed
*/
- private static URL[] getDirectoryURLs(File directory,
- final String[] extensions)
+ private static URL[] getLocalURLs(File location,
+ final String[] extensions)
throws MalformedURLException {
URL[] urls = new URL[0];
- if (!directory.exists()) {
+ if (!location.exists()) {
return urls;
}
- File[] jars = directory.listFiles(
+ if (!location.isDirectory()) {
+ String path = location.getPath();
+ for (int i = 0; i < extensions.length; ++i) {
+ if (path.endsWith(extensions[i])) {
+ urls[0] = InitUtils.getFileURL(location);
+ break;
+ }
+ }
+ return urls;
+ }
+
+ File[] jars = location.listFiles(
new FilenameFilter() {
public boolean accept(File dir, String name) {
for (int i = 0; i < extensions.length; ++i) {
@@ -212,7 +227,6 @@ public class LoaderUtils {
urls = new URL[jars.length];
for (int i = 0; i < jars.length; ++i) {
urls[i] = InitUtils.getFileURL(jars[i]);
- // ps.println("Adding URL " + urls[i]);
}
return urls;
}
diff --git a/proposal/mutant/src/java/remote/org/apache/ant/remote/RemoteMain.java b/proposal/mutant/src/java/remote/org/apache/ant/remote/RemoteMain.java
new file mode 100644
index 000000000..71de737dd
--- /dev/null
+++ b/proposal/mutant/src/java/remote/org/apache/ant/remote/RemoteMain.java
@@ -0,0 +1,48 @@
+package org.apache.ant.remote;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.lang.reflect.Method;
+
+/**
+ * Command line to run Ant core from a remote server
+ *
+ * @author Conor MacNeill
+ * @created 27 January 2002
+ */
+public class RemoteMain {
+ /**
+ * The main program for the RemoteLauncher class
+ *
+ * @param args The command line arguments
+ * @exception Exception if the launcher encounters a problem
+ */
+ public static void main(String[] args) throws Exception {
+
+ if (args.length == 0) {
+ throw new Exception("You must specify the location of the "
+ + "remote server");
+ }
+
+ String antHome = args[0];
+
+ URL[] remoteStart = new URL[1];
+ remoteStart[0] = new URL(antHome + "/lib/start.jar");
+ URLClassLoader remoteLoader = new URLClassLoader(remoteStart);
+
+ String[] realArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, realArgs, 0, realArgs.length);
+
+ System.out.print("Loading remote Ant ... ");
+ Class launcher
+ = Class.forName("org.apache.ant.start.Main", true, remoteLoader);
+
+ final Class[] param = {Class.forName("[Ljava.lang.String;")};
+ final Method startMethod = launcher.getMethod("main", param);
+ final Object[] arguments = {realArgs};
+ System.out.println("Done");
+ System.out.println("Starting Ant from remote server");
+ startMethod.invoke(null, arguments);
+ }
+}
+
diff --git a/proposal/mutant/src/java/start/org/apache/ant/start/Main.java b/proposal/mutant/src/java/start/org/apache/ant/start/Main.java
index bcb2ad352..69e23fee6 100755
--- a/proposal/mutant/src/java/start/org/apache/ant/start/Main.java
+++ b/proposal/mutant/src/java/start/org/apache/ant/start/Main.java
@@ -138,7 +138,8 @@ public class Main {
private URL getToolsJarURL()
throws InitException {
try {
- Class compilerClass = Class.forName("sun.tools.javac.Main");
+ // just check whether this throws an exception
+ Class.forName("sun.tools.javac.Main");
// tools jar is on system classpath - no need for URL
return null;
} catch (ClassNotFoundException cnfe) {
@@ -195,14 +196,18 @@ public class Main {
InitConfig config = new InitConfig();
URL libraryURL = getLibraryURL();
+ System.out.println("Library URL is " + libraryURL);
config.setLibraryURL(libraryURL);
URL antHome = getAntHome();
config.setAntHome(antHome);
- config.setSystemConfigArea(new URL(antHome, "conf/"));
+ if (antHome.getProtocol().equals("file")) {
+ File systemConfigArea = new File(antHome.getFile(), "conf");
+ config.setSystemConfigArea(systemConfigArea);
+ }
File userConfigArea
= new File(System.getProperty("user.home"), ".ant/conf");
- config.setUserConfigArea(InitUtils.getFileURL(userConfigArea));
+ config.setUserConfigArea(userConfigArea);
// set up the class loaders that will be used when running Ant
ClassLoader systemLoader = getClass().getClassLoader();
@@ -210,20 +215,20 @@ public class Main {
URL toolsJarURL = getToolsJarURL();
config.setToolsJarURL(toolsJarURL);
- URL commonJarLib = new URL(libraryURL, "common");
+ URL commonJarLib = new URL(libraryURL, "common/");
ClassLoader commonLoader
- = new URLClassLoader(LoaderUtils.getLoaderURLs(commonJarLib,
+ = new URLClassLoader(LoaderUtils.getLocationURLs(commonJarLib,
"common.jar"), systemLoader);
config.setCommonLoader(commonLoader);
// core needs XML parser for parsing various XML components.
URL[] parserURLs
- = LoaderUtils.getLoaderURLs(new URL(libraryURL, "parser"),
+ = LoaderUtils.getLocationURLs(new URL(libraryURL, "parser/"),
"crimson.jar");
config.setParserURLs(parserURLs);
URL[] coreURLs
- = LoaderUtils.getLoaderURLs(new URL(libraryURL, "antcore"),
+ = LoaderUtils.getLocationURLs(new URL(libraryURL, "antcore/"),
"antcore.jar");
URL[] combinedURLs = new URL[parserURLs.length + coreURLs.length];
System.arraycopy(coreURLs, 0, combinedURLs, 0, coreURLs.length);
@@ -233,9 +238,9 @@ public class Main {
commonLoader);
config.setCoreLoader(coreLoader);
- URL cliJarLib = new URL(libraryURL, "cli");
+ URL cliJarLib = new URL(libraryURL, "cli/");
ClassLoader frontEndLoader
- = new URLClassLoader(LoaderUtils.getLoaderURLs(cliJarLib,
+ = new URLClassLoader(LoaderUtils.getLocationURLs(cliJarLib,
"cli.jar"), coreLoader);
// System.out.println("Front End Loader config");