diff --git a/proposal/mutant/bootstrap.sh b/proposal/mutant/bootstrap.sh
index eb418e850..1eb4ca0a1 100755
--- a/proposal/mutant/bootstrap.sh
+++ b/proposal/mutant/bootstrap.sh
@@ -25,4 +25,4 @@ java -classpath bin/init:bin/bootstrap org.apache.ant.bootstrap.Bootstrap
java -classpath bootstrap/lib/start.jar:bootstrap/lib/init.jar org.apache.ant.start.Main $*
# Use the full build as the build used by the build script
-cp -r dist/* bootstrap
+cp -r dist/lib bootstrap
diff --git a/proposal/mutant/build.sh b/proposal/mutant/build.sh
index c536e75cc..753bef805 100755
--- a/proposal/mutant/build.sh
+++ b/proposal/mutant/build.sh
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/sh -x
# Copyright (c) 2000-2001 The Apache Software Foundation. All rights
# reserved.
-java -classpath bootstrap/lib/start.jar:bootstrap/lib/init.jar org.apache.ant.start.Main $*
+java -classpath bootstrap/lib/start.jar:bootstrap/lib/init.jar org.apache.ant.start.Main $@
diff --git a/proposal/mutant/build/ant1compat.xml b/proposal/mutant/build/ant1compat.xml
index 5a9ba3781..ec8ea5c16 100644
--- a/proposal/mutant/build/ant1compat.xml
+++ b/proposal/mutant/build/ant1compat.xml
@@ -28,8 +28,8 @@
-
-
+
+
diff --git a/proposal/mutant/docs.xml b/proposal/mutant/docs.xml
deleted file mode 100644
index ca7cf5149..000000000
--- a/proposal/mutant/docs.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AnakiaTask is not present! Please check to make sure that
- velocity.jar is in your classpath.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
index 077caec44..462e25639 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
@@ -59,6 +59,7 @@ import java.util.List;
import org.apache.ant.common.model.ModelElement;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.event.BuildEvent;
+import org.apache.ant.common.antlib.Task;
/**
* BuildEventSupport is used by classes which which to send build events to
@@ -162,10 +163,10 @@ public class BuildEventSupport {
/**
* fire a task started event
*
- * @param element the build element with which the event is associated
+ * @param task the task with which the event is associated
*/
- public void fireTaskStarted(ModelElement element) {
- BuildEvent event = new BuildEvent(element, BuildEvent.TASK_STARTED);
+ public void fireTaskStarted(Task task) {
+ BuildEvent event = new BuildEvent(task, BuildEvent.TASK_STARTED);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
listener.taskStarted(event);
@@ -175,12 +176,12 @@ public class BuildEventSupport {
/**
* fire a task finished event
*
- * @param element the build element with which the event is associated
+ * @param task the task with which the event is associated
* @param cause an exception if there was a failure in the task
*/
- public void fireTaskFinished(ModelElement element,
+ public void fireTaskFinished(Task task,
Throwable cause) {
- BuildEvent event = new BuildEvent(element, BuildEvent.TASK_FINISHED,
+ BuildEvent event = new BuildEvent(task, BuildEvent.TASK_FINISHED,
cause);
for (Iterator i = listeners.iterator(); i.hasNext(); ) {
BuildListener listener = (BuildListener)i.next();
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
index 24c7c0b52..d6612e27a 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
@@ -68,10 +68,17 @@ import org.apache.ant.antcore.antlib.ComponentLibrary;
import org.apache.ant.antcore.antlib.DynamicLibrary;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.antlib.Converter;
+import org.apache.ant.common.antlib.DeferredTask;
+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.MessageLevel;
+import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.Location;
+import org.apache.ant.init.LoaderUtils;
/**
* The instance of the ComponentServices made available by the core to the
@@ -81,9 +88,6 @@ import org.apache.ant.common.util.ExecutionException;
* @created 27 January 2002
*/
public class ComponentManager implements ComponentService {
- /** The prefix for library ids that are automatically imported */
- public static final String ANT_LIB_PREFIX = "ant.";
-
/**
* Type converters for this frame. Converters are used when configuring
* Tasks to handle special type conversions.
@@ -120,6 +124,10 @@ public class ComponentManager implements ComponentService {
*/
private Map libPathsMap;
+ /** Reflector objects used to configure Tasks from the Task models. */
+ private Map setters = new HashMap();
+
+
/**
* Constructor
*
@@ -279,26 +287,41 @@ public class ComponentManager implements ComponentService {
*/
public void importFrameComponent(String relativeName, String alias)
throws ExecutionException {
- ImportInfo definition
- = frame.getReferencedDefinition(relativeName);
+ ImportInfo definition
+ = frame.getReferencedDefinition(relativeName);
if (definition == null) {
- throw new ExecutionException("The reference \"relativeName\" does"
- + " not refer to a defined component");
+ throw new ExecutionException("The reference \"relativeName\" does"
+ + " not refer to a defined component");
}
-
+
String label = alias;
if (label == null) {
label = frame.getNameInFrame(relativeName);
}
- frame.log("Adding referenced component <" + definition.getLocalName()
- + "> as <" + label + "> from library \""
+ frame.log("Adding referenced component <" + definition.getLocalName()
+ + "> as <" + label + "> from library \""
+ definition.getComponentLibrary().getLibraryId() + "\", class: "
+ definition.getClassName(), MessageLevel.MSG_DEBUG);
definitions.put(label, definition);
}
+ /**
+ * Create a component. The component will have a context but will not be
+ * configured. It should be configured using the appropriate set methods
+ * and then validated before being used.
+ *
+ * @param componentName the name of the component
+ * @return the created component. The return type of this method depends
+ * on the component type.
+ * @exception ExecutionException if the component cannot be created
+ */
+ public Object createComponent(String componentName)
+ throws ExecutionException {
+ return createComponent(componentName, null);
+ }
+
/**
* Set the standard libraries (i.e. those which are independent of the
* build files) to be used in this component manager
@@ -316,7 +339,7 @@ public class ComponentManager implements ComponentService {
// 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)) {
+ if (libraryId.startsWith(Constants.ANT_LIB_PREFIX)) {
// standard library - import whole library
importLibrary(libraryId);
}
@@ -348,8 +371,9 @@ public class ComponentManager implements ComponentService {
if (libFactories.containsKey(libraryId)) {
return (AntLibFactory)libFactories.get(libraryId);
}
- AntLibFactory libFactory
- = componentLibrary.getFactory(new ExecutionContext(frame));
+ ExecutionContext context
+ = new ExecutionContext(frame, null, Location.UNKNOWN_LOCATION);
+ AntLibFactory libFactory = componentLibrary.getFactory(context);
if (libFactory == null) {
libFactory = new StandardLibFactory();
}
@@ -368,6 +392,109 @@ public class ComponentManager implements ComponentService {
return (ImportInfo)definitions.get(name);
}
+ /**
+ * Create a component from a build model
+ *
+ * @param model the build model representing the component and its
+ * configuration
+ * @return the configured component
+ * @exception ExecutionException if there is a problem creating or
+ * configuring the component
+ */
+ protected Object createComponent(BuildElement model)
+ throws ExecutionException {
+ String componentName = model.getType();
+ return createComponent(componentName, model);
+ }
+
+ /**
+ * Create a component.
+ *
+ * @param componentName the name of the component which is used to
+ * select the object type to be created
+ * @param model the build model of the component. If this is null, the
+ * component is created but not configured.
+ * @return the configured component
+ * @exception ExecutionException if there is a problem creating or
+ * configuring the component
+ */
+ protected Object createComponent(String componentName, BuildElement model)
+ throws ExecutionException {
+
+ ImportInfo definition = getDefinition(componentName);
+ String className = definition.getClassName();
+ ComponentLibrary componentLibrary
+ = definition.getComponentLibrary();
+ String localName = definition.getLocalName();
+ try {
+ ClassLoader componentLoader = componentLibrary.getClassLoader();
+ Class componentClass
+ = Class.forName(className, true, componentLoader);
+ AntLibFactory libFactory = getLibFactory(componentLibrary);
+ Location location = Location.UNKNOWN_LOCATION;
+ if (model != null) {
+ location = model.getLocation();
+ }
+
+ Object component
+ = libFactory.createComponent(componentClass, localName);
+
+ ExecutionComponent execComponent = null;
+ if (definition.getDefinitionType() == AntLibrary.TASKDEF) {
+ if (component instanceof Task) {
+ execComponent = (Task)component;
+ } else {
+ execComponent = new TaskAdapter(componentName, component);
+ }
+ } else if (component instanceof ExecutionComponent) {
+ execComponent = (ExecutionComponent)component;
+ }
+
+ ExecutionContext context
+ = new ExecutionContext(frame, execComponent, location);
+ context.setClassLoader(componentLoader);
+ ClassLoader currentLoader
+ = LoaderUtils.setContextLoader(componentLoader);
+ if (execComponent != null) {
+ execComponent.init(context, componentName);
+ }
+ if (model != null) {
+ configureElement(libFactory, component, model);
+ if (execComponent != null) {
+ execComponent.validateComponent();
+ }
+ }
+ LoaderUtils.setContextLoader(currentLoader);
+ if (execComponent != null) {
+ return execComponent;
+ }
+
+ return component;
+ } catch (ClassNotFoundException e) {
+ throw new ExecutionException("Class " + className
+ + " for component <" + componentName + "> was not found", e,
+ model.getLocation());
+ } catch (NoClassDefFoundError e) {
+ throw new ExecutionException("Could not load a dependent class ("
+ + e.getMessage() + ") for component " + componentName,
+ e, model.getLocation());
+ } catch (InstantiationException e) {
+ throw new ExecutionException("Unable to instantiate component "
+ + "class " + className + " for component <" + componentName
+ + ">", e, model.getLocation());
+ } catch (IllegalAccessException e) {
+ throw new ExecutionException("Unable to access task class "
+ + className + " for component <" + componentName + ">",
+ e, model.getLocation());
+ } catch (ExecutionException e) {
+ e.setLocation(model.getLocation(), false);
+ throw e;
+ } catch (RuntimeException e) {
+ throw new ExecutionException(e.getClass().getName() + ": "
+ + e.getMessage(), e, model.getLocation());
+ }
+ }
+
/**
* Import a single component from the given library
*
@@ -390,6 +517,268 @@ public class ComponentManager implements ComponentService {
definitions.put(label, new ImportInfo(library, libDef));
}
+ /**
+ * Gets the setter for the given class
+ *
+ * @param c the class for which the reflector is desired
+ * @return the reflector
+ */
+ private Setter getSetter(Class c) {
+ if (setters.containsKey(c)) {
+ return (Setter)setters.get(c);
+ }
+ Setter setter = null;
+ if (DeferredTask.class.isAssignableFrom(c)) {
+ setter = new DeferredSetter();
+ } else {
+ ClassIntrospector introspector
+ = new ClassIntrospector(c, getConverters());
+ setter = introspector.getReflector();
+ }
+
+ setters.put(c, setter);
+ return setter;
+ }
+
+ /**
+ * Create an instance of a type given its required class
+ *
+ * @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
+ * @param localName the name of the type within its Ant library
+ * @return an instance of the given class appropriately configured
+ * @exception ExecutionException if there is a problem creating the type
+ * instance
+ */
+ private Object createTypeInstance(Class typeClass, AntLibFactory libFactory,
+ BuildElement model, String localName)
+ throws ExecutionException {
+ try {
+ Object typeInstance
+ = libFactory.createComponent(typeClass, localName);
+
+ if (typeInstance instanceof ExecutionComponent) {
+ ExecutionComponent component = (ExecutionComponent)typeInstance;
+ ExecutionContext context = new ExecutionContext(frame,
+ component, model.getLocation());
+ component.init(context, localName);
+ configureElement(libFactory, typeInstance, model);
+ component.validateComponent();
+ } else {
+ configureElement(libFactory, typeInstance, model);
+ }
+ return typeInstance;
+ } catch (InstantiationException e) {
+ throw new ExecutionException("Unable to instantiate type class "
+ + typeClass.getName() + " for type <" + model.getType() + ">",
+ e, model.getLocation());
+ } catch (IllegalAccessException e) {
+ throw new ExecutionException("Unable to access type class "
+ + typeClass.getName() + " for type <" + model.getType() + ">",
+ e, model.getLocation());
+ } catch (ExecutionException e) {
+ e.setLocation(model.getLocation(), false);
+ throw e;
+ } catch (RuntimeException e) {
+ throw new ExecutionException(e.getClass().getName() + ": "
+ + e.getMessage(), e, model.getLocation());
+ }
+ }
+
+ /**
+ * Create and add a nested element
+ *
+ * @param setter The Setter instance for the container element
+ * @param element the container element in which the nested element will
+ * be created
+ * @param model the model of the nested element
+ * @param factory Ant Library factory associated with the element to
+ * which the attribute is to be added.
+ * @exception ExecutionException if the nested element cannot be created
+ */
+ private void addNestedElement(AntLibFactory factory, Setter setter,
+ Object element, BuildElement model)
+ throws ExecutionException {
+ String nestedElementName = model.getType();
+ Class nestedType = setter.getType(nestedElementName);
+
+ // is there a polymorph indicator - look in Ant aspects
+ String typeName = model.getAspectValue(Constants.ANT_ASPECT, "type");
+ String refId = model.getAspectValue(Constants.ANT_ASPECT, "refid");
+ if (refId != null && typeName != null) {
+ throw new ExecutionException("Only one of " + Constants.ANT_ASPECT
+ + ":type and " + Constants.ANT_ASPECT
+ + ":refid may be specified at a time", model.getLocation());
+ }
+
+ Object typeInstance = null;
+ if (typeName != null) {
+ // the build file has specified the actual type of the element.
+ // we need to look up that type and use it
+ typeInstance = createComponent(typeName, model);
+ } else if (refId != null) {
+ // We have a reference to an existing instance. Need to check if
+ // it is compatible with the type expected by the nested element's
+ // adder method
+ typeInstance = frame.getDataValue(refId);
+ if (model.getAttributeNames().hasNext() ||
+ model.getNestedElements().hasNext() ||
+ model.getText().length() != 0) {
+ throw new ExecutionException("Element <" + nestedElementName
+ + "> is defined by reference and hence may not specify "
+ + "any attributes, nested elements or content",
+ model.getLocation());
+ }
+ if (typeInstance == null) {
+ throw new ExecutionException("The given ant:refid value '"
+ + refId + "' is not defined", model.getLocation());
+ }
+ } else if (nestedType != null) {
+ // We need to create an instance of the class expected by the nested
+ // element's adder method if that is possible
+ if (nestedType.isInterface()) {
+ throw new ExecutionException("No element can be created for "
+ + "nested element <" + nestedElementName + ">. Please "
+ + "provide a value by reference or specify the value type",
+ model.getLocation());
+ }
+ typeInstance = createTypeInstance(nestedType, factory, model, null);
+ } else {
+ throw new ExecutionException("The type of the <"
+ + nestedElementName + "> nested element is not known. "
+ + "Please specify by the type using the \"ant:type\" "
+ + "attribute or provide a reference to an instance with "
+ + "the \"ant:id\" attribute");
+ }
+
+ // is the typeInstance compatible with the type expected
+ // by the element's add method
+ if (!nestedType.isInstance(typeInstance)) {
+ if (refId != null) {
+ throw new ExecutionException("The value specified by refId "
+ + refId + " is not compatible with the <"
+ + nestedElementName + "> nested element",
+ model.getLocation());
+ } else if (typeName != null) {
+ throw new ExecutionException("The type "
+ + typeName + " is not compatible with the <"
+ + nestedElementName + "> nested element",
+ model.getLocation());
+ }
+ }
+ setter.addElement(element, nestedElementName, typeInstance);
+ }
+
+ /**
+ * Create a nested element for the given object according to the model.
+ *
+ * @param setter the Setter instance of the container object
+ * @param element the container object for which a nested element is
+ * required.
+ * @param model the build model for the nestd element
+ * @param factory Ant Library factory associated with the element
+ * creating the nested element
+ * @exception ExecutionException if the nested element cannot be
+ * created.
+ */
+ private void createNestedElement(AntLibFactory factory, Setter setter,
+ Object element, BuildElement model)
+ throws ExecutionException {
+ String nestedElementName = model.getType();
+ try {
+ Object nestedElement
+ = setter.createElement(element, nestedElementName);
+ factory.registerCreatedElement(nestedElement);
+ if (nestedElement instanceof ExecutionComponent) {
+ ExecutionComponent component
+ = (ExecutionComponent)nestedElement;
+ ExecutionContext context = new ExecutionContext(frame,
+ component, model.getLocation());
+ component.init(context, nestedElementName);
+ configureElement(factory, nestedElement, model);
+ component.validateComponent();
+ } else {
+ configureElement(factory, nestedElement, model);
+ }
+ } catch (ExecutionException e) {
+ e.setLocation(model.getLocation(), false);
+ throw e;
+ } catch (RuntimeException e) {
+ throw new ExecutionException(e.getClass().getName() + ": "
+ + e.getMessage(), e, model.getLocation());
+ }
+ }
+
+
+ /**
+ * Configure an element according to the given model.
+ *
+ * @param element the object to be configured
+ * @param model the BuildElement describing the object in the build file
+ * @param factory Ant Library factory associated with the element being
+ * configured
+ * @exception ExecutionException if the element cannot be configured
+ */
+ private void configureElement(AntLibFactory factory, Object element,
+ BuildElement model)
+ throws ExecutionException {
+ Setter setter = getSetter(element.getClass());
+ // start by setting the attributes of this element
+ for (Iterator i = model.getAttributeNames(); i.hasNext(); ) {
+ String attributeName = (String)i.next();
+ String attributeValue = model.getAttributeValue(attributeName);
+ if (!setter.supportsAttribute(attributeName)) {
+ throw new ExecutionException(model.getType()
+ + " does not support the \"" + attributeName
+ + "\" attribute", model.getLocation());
+ }
+ setter.setAttribute(element, attributeName,
+ frame.replacePropertyRefs(attributeValue));
+ }
+
+ String modelText = model.getText().trim();
+ if (modelText.length() != 0) {
+ if (!setter.supportsText()) {
+ throw new ExecutionException(model.getType()
+ + " does not support content", model.getLocation());
+ }
+ setter.addText(element,
+ frame.replacePropertyRefs(modelText));
+ }
+
+ // now do the nested elements
+ for (Iterator i = model.getNestedElements(); i.hasNext(); ) {
+ BuildElement nestedElementModel = (BuildElement)i.next();
+ String nestedElementName = nestedElementModel.getType();
+ ImportInfo info = getDefinition(nestedElementName);
+ if (element instanceof TaskContainer
+ && info != null
+ && info.getDefinitionType() == AntLibrary.TASKDEF
+ && !setter.supportsNestedElement(nestedElementName)) {
+ // it is a nested task
+ Task nestedTask
+ = (Task)createComponent(nestedElementModel);
+ TaskContainer container = (TaskContainer)element;
+ container.addTask(nestedTask);
+ } else {
+ if (setter.supportsNestedAdder(nestedElementName)) {
+ addNestedElement(factory, setter, element,
+ nestedElementModel);
+ } else if (setter.supportsNestedCreator(nestedElementName)) {
+ createNestedElement(factory, setter, element,
+ nestedElementModel);
+ } else {
+ throw new ExecutionException(model.getType()
+ + " does not support the \"" + nestedElementName
+ + "\" nested element",
+ nestedElementModel.getLocation());
+ }
+ }
+ }
+ }
+
/**
* Define a new component
*
@@ -445,8 +834,8 @@ public class ComponentManager implements ComponentService {
}
Converter converter
= libFactory.createConverter(converterClass);
- ExecutionContext context
- = new ExecutionContext(frame);
+ ExecutionContext context = new ExecutionContext(frame,
+ null, Location.UNKNOWN_LOCATION);
converter.init(context);
Class[] converterTypes = converter.getTypes();
for (int j = 0; j < converterTypes.length; ++j) {
@@ -475,6 +864,5 @@ public class ComponentManager implements ComponentService {
+ className, e);
}
}
-
}
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/Constants.java
old mode 100755
new mode 100644
similarity index 55%
rename from proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
rename to proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java
index d5a56f085..a48c4994c
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java
@@ -52,88 +52,19 @@
* .
*/
package org.apache.ant.antcore.execution;
-import org.apache.ant.common.antlib.Task;
-import org.apache.ant.common.model.ModelElement;
-import org.apache.ant.common.util.ExecutionException;
+
/**
- * This is the core's implementation of the AntContext for Tasks.
+ * Core constants
*
* @author Conor MacNeill
- * @created 17 January 2002
+ * @created 20 February 2002
*/
-public class TaskContext extends ExecutionContext {
-
- /** The task being managed by this context */
- private Task task;
-
- /**
- * the loader used to load this task. Note that this is not necessarily
- * the loader which is used to load the Task class as loading may have
- * been delegated to a parent loader.
- */
- private ClassLoader loader;
-
- /**
- * Initilaise this context's environment
- *
- * @param frame the frame containing this context
- */
- public TaskContext(Frame frame) {
- super(frame);
- }
-
- /**
- * Get the task associated with this context
- *
- * @return the task instance
- */
- protected Task getTask() {
- return task;
- }
-
- /**
- * Gets the loader for this task
- *
- * @return the task's loader
- */
- protected ClassLoader getLoader() {
- return loader;
- }
-
- /**
- * Associate a task with this context
- *
- * @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
- */
- protected void init(ClassLoader loader, Task task,
- ModelElement modelElement) throws ExecutionException {
- this.task = task;
- this.loader = loader;
- setModelElement(modelElement);
- task.init(this);
- }
+public abstract class Constants {
+ /** The prefix for library ids that are automatically imported */
+ public static final String ANT_LIB_PREFIX = "ant.";
- /**
- * execute this context's task
- *
- * @exception ExecutionException if there is a problem executing the
- * task
- */
- protected void execute() throws ExecutionException {
- task.execute();
- }
+ /** The Ant aspect used to identify Ant metadata */
+ public static final String ANT_ASPECT = "ant";
- /**
- * Destroy this context. The context can be reused for another task
- * after this one
- */
- protected void destroy() {
- task.destroy();
- task = null;
- loader = null;
- }
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
index a81aad2c7..fa3c670d7 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
@@ -58,13 +58,16 @@ import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.modelparser.XMLProjectParser;
import org.apache.ant.antcore.xml.XMLParseException;
+import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitUtils;
+import org.apache.ant.init.LoaderUtils;
/**
- *This is the core's implementation of the Execution Service.
+ * This is the core's implementation of the Execution Service.
*
* @author Conor MacNeill
* @created 8 February 2002
@@ -132,5 +135,37 @@ public class CoreExecService implements ExecService {
runBuild(frame.getProject(), properties, targets);
}
+ /**
+ * Execute a task. The task should have already been initialised by
+ * the core. This is checked
+ *
+ * @param task the task to be executed
+ * @exception ExecutionException if there is an execution problem
+ */
+ public void executeTask(Task task) throws ExecutionException {
+ AntContext context = task.getAntContext();
+ if (!(context instanceof ExecutionContext)) {
+ throw new ExecutionException("The Task was not configured with an"
+ + " appropriate context");
+ }
+ ExecutionContext execContext = (ExecutionContext)context;
+
+ frame.getEventSupport().fireTaskStarted(task);
+ Throwable failureCause = null;
+ try {
+ ClassLoader currentLoader
+ = LoaderUtils.setContextLoader(execContext.getLoader());
+ task.execute();
+ LoaderUtils.setContextLoader(currentLoader);
+ } catch (Throwable e) {
+ ExecutionException ee =
+ new ExecutionException(e.getClass().getName() + ": "
+ + e.getMessage(), e);
+ failureCause = ee;
+ throw ee;
+ } finally {
+ frame.getEventSupport().fireTaskFinished(task, failureCause);
+ }
+ }
}
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 1ddf88c4b..1babfbfd5 100755
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java
@@ -54,8 +54,9 @@
package org.apache.ant.antcore.execution;
import java.io.File;
import org.apache.ant.common.antlib.AntContext;
-import org.apache.ant.common.model.ModelElement;
+import org.apache.ant.common.antlib.ExecutionComponent;
import org.apache.ant.common.util.ExecutionException;
+import org.apache.ant.common.util.Location;
/**
* This is the core's implementation of the AntContext for all core objects.
@@ -71,26 +72,32 @@ public class ExecutionContext implements AntContext {
/** the event support instance used to manage build events */
private BuildEventSupport eventSupport;
- /** the model in the build model with which this context is associated */
- private ModelElement modelElement;
+ /** The location of the object associated with this context */
+ private Location location;
+
+ /** the execution component associated with the context, if any */
+ private ExecutionComponent component;
+
+ /**
+ * the loader used to load this context. Note that this is not
+ * necessarily the loader which is used to load the component as loading
+ * may have been delegated to a parent loader.
+ */
+ private ClassLoader loader;
/**
* Initilaise this context's environment
*
* @param frame the frame containing this context
+ * @param component the component associated with this context - may be null
+ * @param location the location associated with the component
*/
- protected ExecutionContext(Frame frame) {
+ protected ExecutionContext(Frame frame, ExecutionComponent component,
+ Location location) {
this.frame = frame;
this.eventSupport = frame.getEventSupport();
- }
-
- /**
- * Set the model element associated with this context
- *
- * @param modelElement the model element associated with this context
- */
- protected void setModelElement(ModelElement modelElement) {
- this.modelElement = modelElement;
+ this.location = location;
+ this.component = component;
}
/**
@@ -107,19 +114,6 @@ public class ExecutionContext implements AntContext {
return frame.getCoreService(serviceInterfaceClass);
}
- /**
- * Get the model element associated with this context. If the context is
- * not associated with any particular model element, the project model
- * is returned.
- *
- * @return the model element.
- */
- public ModelElement getModelElement() {
- if (modelElement == null) {
- return frame.getProject();
- }
- return modelElement;
- }
/**
* Get the base directory for this execution of this frame
@@ -130,6 +124,15 @@ public class ExecutionContext implements AntContext {
return frame.getBaseDir();
}
+ /**
+ * Gets the location associated with the ExecutionContext
+ *
+ * @return the location in the build model associated with this context.
+ */
+ public Location getLocation() {
+ return location;
+ }
+
/**
* Log a message as a build event
*
@@ -137,7 +140,7 @@ public class ExecutionContext implements AntContext {
* @param level the priority level of the message
*/
public void log(String message, int level) {
- Object source = modelElement;
+ Object source = component;
if (source == null) {
source = frame.getProject();
if (source == null) {
@@ -146,5 +149,32 @@ public class ExecutionContext implements AntContext {
}
eventSupport.fireMessageLogged(source, message, level);
}
+
+ /**
+ * Sets the classLoader of the ExecutionContext
+ *
+ * @param loader the new classLoader value
+ */
+ protected void setClassLoader(ClassLoader loader) {
+ this.loader = loader;
+ }
+
+ /**
+ * Gets the loader for this task
+ *
+ * @return the task's loader
+ */
+ protected ClassLoader getLoader() {
+ return loader;
+ }
+
+ /**
+ * Gets the executionComponent of the ExecutionContext
+ *
+ * @return the executionComponent value
+ */
+ protected ExecutionComponent getExecutionComponent() {
+ return component;
+ }
}
diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
index 64284a4fe..dd0b7e683 100644
--- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
+++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
@@ -59,14 +59,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
-import org.apache.ant.antcore.antlib.AntLibrary;
-import org.apache.ant.antcore.antlib.ComponentLibrary;
import org.apache.ant.antcore.config.AntConfig;
-import org.apache.ant.common.antlib.AntLibFactory;
-import org.apache.ant.common.antlib.DeferredTask;
-import org.apache.ant.common.antlib.ExecutionComponent;
import org.apache.ant.common.antlib.Task;
-import org.apache.ant.common.antlib.TaskContainer;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.event.MessageLevel;
import org.apache.ant.common.model.BuildElement;
@@ -93,9 +87,6 @@ import org.apache.ant.init.InitConfig;
* @created 14 January 2002
*/
public class Frame {
- /** The Ant aspect used to identify Ant metadata */
- public static final String ANT_ASPECT = "ant";
-
/** the base dir of the project */
private File baseDir;
@@ -105,9 +96,6 @@ public class Frame {
/** The referenced frames corresponding to the referenced projects */
private Map referencedFrames = new HashMap();
- /** Reflector objects used to configure Tasks from the Task models. */
- private Map setters = new HashMap();
-
/**
* The context of this execution. This contains all data object's
* created by tasks that have been executed
@@ -155,6 +143,11 @@ public class Frame {
*/
private ComponentManager componentManager;
+ /**
+ * The core's execution Service
+ */
+ private CoreExecService execService;
+
/**
* Create an Execution Frame for the given project
*
@@ -172,20 +165,6 @@ public class Frame {
this.initConfig = initConfig;
}
- /**
- * Set the context loader of the current thread and returns the existing
- * classloader
- *
- * @param newLoader the new context loader
- * @return the old context loader
- */
- private static ClassLoader setContextLoader(ClassLoader newLoader) {
- Thread thread = Thread.currentThread();
- ClassLoader currentLoader = thread.getContextClassLoader();
- thread.setContextClassLoader(newLoader);
- return currentLoader;
- }
-
/**
* Sets the Project of the Frame
*
@@ -210,6 +189,18 @@ public class Frame {
setMagicProperties();
}
+ /**
+ * 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 {
+ return dataService.replacePropertyRefs(value);
+ }
+
/**
* Set a value in this frame or any of its imported frames.
*
@@ -625,48 +616,29 @@ public class Frame {
protected void executeTasks(Iterator taskIterator)
throws ExecutionException {
while (taskIterator.hasNext()) {
- Throwable failureCause = null;
BuildElement model = (BuildElement)taskIterator.next();
// what sort of element is this.
- ImportInfo importInfo
- = componentManager.getDefinition(model.getType());
- if (importInfo == null) {
- throw new ExecutionException("There is no definition for the <"
- + model.getType() + "> element", model.getLocation());
- }
-
try {
- if (importInfo.getDefinitionType() == AntLibrary.TASKDEF) {
- TaskContext taskContext = configureTask(model);
- eventSupport.fireTaskStarted(model);
-
- ClassLoader currentLoader
- = setContextLoader(taskContext.getLoader());
- taskContext.execute();
- setContextLoader(currentLoader);
- taskContext.destroy();
+ Object component = componentManager.createComponent(model);
+ if (component instanceof Task) {
+ execService.executeTask((Task)component);
} else {
- // typedef
- String typeId = model.getAspectValue(ANT_ASPECT, "id");
- Object typeInstance = configureType(model.getType(), model);
+ String typeId
+ = model.getAspectValue(Constants.ANT_ASPECT, "id");
if (typeId != null) {
- setDataValue(typeId, typeInstance, true);
+ setDataValue(typeId, component, true);
}
}
} catch (AntException te) {
ExecutionException e
= new ExecutionException(te, te.getLocation());
e.setLocation(model.getLocation(), false);
- failureCause = e;
throw e;
} catch (RuntimeException e) {
ExecutionException ee =
new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e, model.getLocation());
- failureCause = ee;
throw ee;
- } finally {
- eventSupport.fireTaskFinished(model, failureCause);
}
}
@@ -737,30 +709,6 @@ public class Frame {
executeTasks(taskIterator);
}
-
- /**
- * Gets the setter for the given class
- *
- * @param c the class for which the reflector is desired
- * @return the reflector
- */
- private Setter getSetter(Class c) {
- if (setters.containsKey(c)) {
- return (Setter)setters.get(c);
- }
- Setter setter = null;
- if (DeferredTask.class.isAssignableFrom(c)) {
- setter = new DeferredSetter();
- } else {
- ClassIntrospector introspector
- = new ClassIntrospector(c, componentManager.getConverters());
- setter = introspector.getReflector();
- }
-
- setters.put(c, setter);
- return setter;
- }
-
/**
* Determine the base directory for each frame in the frame hierarchy
*
@@ -806,383 +754,13 @@ public class Frame {
config.isRemoteLibAllowed(), config.getLibraryPathsMap());
dataService = new CoreDataService(this,
config.isUnsetPropertiesAllowed());
-
+ execService = new CoreExecService(this);
+
services.put(FileService.class, fileService);
services.put(ComponentService.class, componentManager);
services.put(DataService.class, dataService);
services.put(EventService.class, new CoreEventService(this));
- services.put(ExecService.class, new CoreExecService(this));
- }
-
- /**
- * Configure an element according to the given model.
- *
- * @param element the object to be configured
- * @param model the BuildElement describing the object in the build file
- * @param factory Ant Library factory associated with the element being
- * configured
- * @exception ExecutionException if the element cannot be configured
- */
- private void configureElement(AntLibFactory factory, Object element,
- BuildElement model)
- throws ExecutionException {
-
- Setter setter = getSetter(element.getClass());
-
- // start by setting the attributes of this element
- for (Iterator i = model.getAttributeNames(); i.hasNext(); ) {
- String attributeName = (String)i.next();
- String attributeValue = model.getAttributeValue(attributeName);
- if (!setter.supportsAttribute(attributeName)) {
- throw new ExecutionException(model.getType()
- + " does not support the \"" + attributeName
- + "\" attribute", model.getLocation());
- }
- setter.setAttribute(element, attributeName,
- dataService.replacePropertyRefs(attributeValue));
- }
- String modelText = model.getText().trim();
- if (modelText.length() != 0) {
- if (!setter.supportsText()) {
- throw new ExecutionException(model.getType()
- + " does not support content", model.getLocation());
- }
- setter.addText(element,
- dataService.replacePropertyRefs(modelText));
- }
-
- // now do the nested elements
- for (Iterator i = model.getNestedElements(); i.hasNext(); ) {
- BuildElement nestedElementModel = (BuildElement)i.next();
- String nestedElementName = nestedElementModel.getType();
-
- ImportInfo info = componentManager.getDefinition(nestedElementName);
- if (element instanceof TaskContainer
- && info != null
- && info.getDefinitionType() == AntLibrary.TASKDEF
- && !setter.supportsNestedElement(nestedElementName)) {
- // it is a nested task
- TaskContext nestedContext
- = configureTask(nestedElementModel);
- TaskContainer container = (TaskContainer)element;
- // XXX what should we be adding - need to understand container
- // method of executing tasks
- container.addTask(nestedContext.getTask());
- } else {
- if (setter.supportsNestedAdder(nestedElementName)) {
- addNestedElement(factory, setter, element,
- nestedElementModel);
- } else if (setter.supportsNestedCreator(nestedElementName)) {
- createNestedElement(factory, setter, 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 setter the Setter instance of the container object
- * @param element the container object for which a nested element is
- * required.
- * @param model the build model for the nestd element
- * @param factory Ant Library factory associated with the element
- * creating the nested element
- * @exception ExecutionException if the nested element cannot be
- * created.
- */
- private void createNestedElement(AntLibFactory factory, Setter setter,
- Object element, BuildElement model)
- throws ExecutionException {
- String nestedElementName = model.getType();
- try {
- Object nestedElement
- = setter.createElement(element, nestedElementName);
- factory.registerCreatedElement(nestedElement);
- if (nestedElement instanceof ExecutionComponent) {
- ExecutionComponent component
- = (ExecutionComponent)nestedElement;
- ExecutionContext context
- = new ExecutionContext(this);
- context.setModelElement(model);
- component.init(context);
- configureElement(factory, nestedElement, model);
- component.validateComponent();
- } else {
- configureElement(factory, nestedElement, model);
- }
- } catch (ExecutionException e) {
- e.setLocation(model.getLocation(), false);
- throw e;
- } catch (RuntimeException e) {
- throw new ExecutionException(e.getClass().getName() + ": "
- + e.getMessage(), e, model.getLocation());
- }
- }
-
-
- /**
- * Create and add a nested element
- *
- * @param setter The Setter instance for the container element
- * @param element the container element in which the nested element will
- * be created
- * @param model the model of the nested element
- * @param factory Ant Library factory associated with the element to
- * which the attribute is to be added.
- * @exception ExecutionException if the nested element cannot be created
- */
- private void addNestedElement(AntLibFactory factory, Setter setter,
- Object element, BuildElement model)
- throws ExecutionException {
-
- String nestedElementName = model.getType();
- Class nestedType = setter.getType(nestedElementName);
-
- // is there a polymorph indicator - look in Ant aspects
- String typeName = model.getAspectValue(ANT_ASPECT, "type");
- String refId = model.getAspectValue(ANT_ASPECT, "refid");
- if (refId != null && typeName != null) {
- throw new ExecutionException("Only one of " + ANT_ASPECT
- + ":type and " + ANT_ASPECT
- + ":refid may be specified at a time", model.getLocation());
- }
-
- Object typeInstance = null;
- if (typeName != null) {
- // the build file has specified the actual type of the element.
- // we need to look up that type and use it
- typeInstance = configureType(typeName, model);
- } else if (refId != null) {
- // We have a reference to an existing instance. Need to check if
- // it is compatible with the type expected by the nested element's
- // adder method
- typeInstance = getDataValue(refId);
- if (model.getAttributeNames().hasNext() ||
- model.getNestedElements().hasNext() ||
- model.getText().length() != 0) {
- throw new ExecutionException("Element <" + nestedElementName
- + "> is defined by reference and hence may not specify "
- + "any attributes, nested elements or content",
- model.getLocation());
- }
- if (typeInstance == null) {
- throw new ExecutionException("The given ant:refid value '"
- + refId + "' is not defined", model.getLocation());
- }
- } else if (nestedType != null) {
- // We need to create an instance of the class expected by the nested
- // element's adder method if that is possible
- if (nestedType.isInterface()) {
- throw new ExecutionException("No element can be created for "
- + "nested element <" + nestedElementName + ">. Please "
- + "provide a value by reference or specify the value type",
- model.getLocation());
- }
-
- typeInstance = createTypeInstance(nestedType, factory, model, null);
- } else {
- throw new ExecutionException("The type of the <"
- + nestedElementName + "> nested element is not known. "
- + "Please specify by the type using the \"ant:type\" "
- + "attribute or provide a reference to an instance with "
- + "the \"ant:id\" attribute");
- }
-
- // is the typeInstance compatible with the type expected
- // by the element's add method
- if (!nestedType.isInstance(typeInstance)) {
- if (refId != null) {
- throw new ExecutionException("The value specified by refId "
- + refId + " is not compatible with the <"
- + nestedElementName + "> nested element",
- model.getLocation());
- } else if (typeName != null) {
- throw new ExecutionException("The type "
- + typeName + " is not compatible with the <"
- + nestedElementName + "> nested element",
- model.getLocation());
- }
- }
- setter.addElement(element, nestedElementName, typeInstance);
- }
-
-
- /**
- * Create a Task and configure it according to the given model.
- *
- * @param model the model for the task from the build file
- * @return an execution context for managing the task
- * @exception ExecutionException if there is a problem configuring the
- * task
- */
- private TaskContext configureTask(BuildElement model)
- throws ExecutionException {
-
- String taskType = model.getType();
- ImportInfo taskDefInfo = componentManager.getDefinition(taskType);
- if (taskDefInfo == null
- || taskDefInfo.getDefinitionType() != AntLibrary.TASKDEF) {
- throw new ExecutionException("There is no defintion for a "
- + "task of type <" + taskType + ">", model.getLocation());
- }
-
- String className = taskDefInfo.getClassName();
- ComponentLibrary componentLibrary
- = taskDefInfo.getComponentLibrary();
- String localName = taskDefInfo.getLocalName();
-
- try {
- ClassLoader taskClassLoader = componentLibrary.getClassLoader();
- Class elementClass
- = Class.forName(className, true, taskClassLoader);
- AntLibFactory libFactory
- = componentManager.getLibFactory(componentLibrary);
- Object element
- = libFactory.createTaskInstance(elementClass, localName);
-
- Task task = null;
- if (element instanceof Task) {
- // create a Task context for the Task
- task = (Task)element;
- } else {
- task = new TaskAdapter(taskType, element);
- }
-
- // set the context loader while configuring the element
- ClassLoader currentLoader = setContextLoader(taskClassLoader);
- TaskContext taskContext = new TaskContext(this);
- taskContext.init(taskClassLoader, task, model);
- configureElement(libFactory, element, model);
- task.validateComponent();
- setContextLoader(currentLoader);
- return taskContext;
- } catch (ClassNotFoundException e) {
- throw new ExecutionException("Class " + className
- + " for task <" + taskType + "> was not found", e,
- model.getLocation());
- } catch (NoClassDefFoundError e) {
- throw new ExecutionException("Could not load a dependent class ("
- + e.getMessage() + ") for task " + taskType,
- e, model.getLocation());
- } catch (InstantiationException e) {
- throw new ExecutionException("Unable to instantiate task class "
- + className + " for task <" + taskType + ">",
- e, model.getLocation());
- } catch (IllegalAccessException e) {
- throw new ExecutionException("Unable to access task class "
- + className + " for task <" + taskType + ">",
- e, model.getLocation());
- } catch (ExecutionException e) {
- e.setLocation(model.getLocation(), false);
- throw e;
- } catch (RuntimeException e) {
- throw new ExecutionException(e.getClass().getName() + ": "
- + e.getMessage(), e, model.getLocation());
- }
- }
-
-
- /**
- * 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
- * caller to provide a polymorphic type for the type model
- *
- * @param typeName the name of the type which should be created
- * @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
- */
- private Object configureType(String typeName, BuildElement model)
- throws ExecutionException {
- ImportInfo typeDefInfo = componentManager.getDefinition(typeName);
- if (typeDefInfo == null
- || typeDefInfo.getDefinitionType() != AntLibrary.TYPEDEF) {
- throw new ExecutionException("There is no defintion for a "
- + "type <" + typeName + ">", model.getLocation());
- }
-
- String className = typeDefInfo.getClassName();
- ComponentLibrary componentLibrary
- = typeDefInfo.getComponentLibrary();
- String localName = typeDefInfo.getLocalName();
-
- try {
- ClassLoader typeClassLoader = componentLibrary.getClassLoader();
- Class typeClass
- = Class.forName(className, true, typeClassLoader);
-
- ClassLoader currentLoader = setContextLoader(typeClassLoader);
- AntLibFactory libFactory
- = componentManager.getLibFactory(componentLibrary);
- Object typeInstance
- = createTypeInstance(typeClass, libFactory, model, localName);
- setContextLoader(currentLoader);
-
- return typeInstance;
- } catch (ClassNotFoundException e) {
- throw new ExecutionException("Class " + className
- + " for type <" + typeName + "> was not found", e,
- model.getLocation());
- } catch (NoClassDefFoundError e) {
- throw new ExecutionException("Could not load a dependent class ("
- + e.getMessage() + ") for type " + typeName);
- }
- }
-
- /**
- * Create an instance of a type given its required class
- *
- * @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
- * @param localName the name of the type within its Ant library
- * @return an instance of the given class appropriately configured
- * @exception ExecutionException if there is a problem creating the type
- * instance
- */
- private Object createTypeInstance(Class typeClass, AntLibFactory libFactory,
- BuildElement model, String localName)
- throws ExecutionException {
- try {
- Object typeInstance
- = libFactory.createTypeInstance(typeClass, localName);
-
- if (typeInstance instanceof ExecutionComponent) {
- ExecutionComponent component = (ExecutionComponent)typeInstance;
- ExecutionContext context
- = new ExecutionContext(this);
- context.setModelElement(model);
- component.init(context);
- configureElement(libFactory, typeInstance, model);
- component.validateComponent();
- } else {
- configureElement(libFactory, typeInstance, model);
- }
- return typeInstance;
- } catch (InstantiationException e) {
- throw new ExecutionException("Unable to instantiate type class "
- + typeClass.getName() + " for type <" + model.getType() + ">",
- e, model.getLocation());
- } catch (IllegalAccessException e) {
- throw new ExecutionException("Unable to access type class "
- + typeClass.getName() + " for type <" + model.getType() + ">",
- e, model.getLocation());
- } catch (ExecutionException e) {
- e.setLocation(model.getLocation(), false);
- throw e;
- } catch (RuntimeException e) {
- throw new ExecutionException(e.getClass().getName() + ": "
- + e.getMessage(), e, model.getLocation());
- }
+ services.put(ExecService.class, execService);
}
}
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java
index c521b7412..3d3167faf 100644
--- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java
@@ -102,65 +102,48 @@ public class Ant1Factory extends StandardLibFactory {
/**
- * Create an instance of the requested type class
+ * Create an instance of the given component class
*
- * @param typeClass the class from which an instance is required
- * @param localName the name of the type within its library
- * @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
+ * @param componentClass the class for which an instance is required
+ * @param localName the name within the library under which the task is
+ * defined
+ * @return an instance of the required class
+ * @exception InstantiationException if the class cannot be instantiated
+ * @exception IllegalAccessException if the instance cannot be accessed
+ * @exception ExecutionException if there is a problem creating the task
*/
- public Object createTypeInstance(Class typeClass, String localName)
+ public Object createComponent(Class componentClass, String localName)
throws InstantiationException, IllegalAccessException,
ExecutionException {
try {
- java.lang.reflect.Constructor ctor = null;
+ java.lang.reflect.Constructor constructor = null;
// DataType can have a "no arg" constructor or take a single
// Project argument.
- Object o = null;
+ Object component = null;
try {
- ctor = typeClass.getConstructor(new Class[0]);
- o = ctor.newInstance(new Object[0]);
+ constructor = componentClass.getConstructor(new Class[0]);
+ component = constructor.newInstance(new Object[0]);
} catch (NoSuchMethodException nse) {
- ctor = typeClass.getConstructor(new Class[]{Project.class});
- o = ctor.newInstance(new Object[]{project});
+ constructor
+ = componentClass.getConstructor(new Class[]{Project.class});
+ component = constructor.newInstance(new Object[]{project});
}
- if (o instanceof ProjectComponent) {
- ((ProjectComponent)o).setProject(project);
+ if (component instanceof ProjectComponent) {
+ ((ProjectComponent)component).setProject(project);
}
- return o;
+ return component;
} catch (java.lang.reflect.InvocationTargetException ite) {
Throwable t = ite.getTargetException();
- String msg = "Could not create datatype of type: "
- + typeClass.getName() + " due to " + t;
+ String msg = "Could not create component of type: "
+ + componentClass.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);
+ + "constructor for component " + componentClass.getName(), e);
}
}
- /**
- * Create an instance of the requested task class
- *
- * @param taskClass the class from which an instance is required
- * @param localName the name of the task within its library
- * @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, String localName)
- throws InstantiationException, IllegalAccessException {
- Object instance = taskClass.newInstance();
- if (instance instanceof ProjectComponent) {
- ((ProjectComponent)instance).setProject(project);
- }
-
- return instance;
- }
-
/**
* Create a converter.
*
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
index 8362b37b9..a45c31abb 100644
--- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
@@ -474,7 +474,7 @@ public class Project implements org.apache.ant.common.event.BuildListener {
public void targetStarted(org.apache.ant.common.event.BuildEvent event) {
Target newTarget = new Target(this);
org.apache.ant.common.model.Target realTarget =
- (org.apache.ant.common.model.Target)event.getModelElement();
+ (org.apache.ant.common.model.Target)event.getSource();
newTarget.setName(realTarget.getName());
targetStack.push(newTarget);
fireTargetStarted(newTarget);
@@ -487,7 +487,7 @@ public class Project implements org.apache.ant.common.event.BuildListener {
*/
public void targetFinished(org.apache.ant.common.event.BuildEvent event) {
org.apache.ant.common.model.Target realTarget =
- (org.apache.ant.common.model.Target)event.getModelElement();
+ (org.apache.ant.common.model.Target)event.getSource();
Target currentTarget = (Target)targetStack.pop();
fireTargetFinished(currentTarget, event.getCause());
currentTarget = null;
@@ -881,7 +881,7 @@ public class Project implements org.apache.ant.common.event.BuildListener {
try {
task = (Task)c.newInstance();
task.setProject(this);
- task.init(context);
+ task.init(context, taskType);
return task;
} catch (Throwable e) {
throw new BuildException(e);
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
index 2accd420e..759fa5367 100644
--- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
@@ -69,6 +69,8 @@ public abstract class ProjectComponent {
protected Location location;
/** The core context for this component */
private AntContext context;
+ /** The type of the component bneing created */
+ private String componentType;
/**
* Sets the project of the ProjectComponent
@@ -108,16 +110,39 @@ public abstract class ProjectComponent {
return location;
}
+ /**
+ * Gets the componentType of the ProjectComponent
+ *
+ * @return the componentType value
+ */
+ public String getComponentType() {
+ return componentType;
+ }
+
+
+ /**
+ * Get the context associated with this component
+ *
+ * @return the AntContext
+ */
+ public AntContext getAntContext() {
+ return context;
+ }
+
/**
* Initialise this component
*
* @param context the core context for this component
+ * @param componentType the component type of this component
* @exception ExecutionException if the component cannot be initialized
*/
- public void init(AntContext context) throws ExecutionException {
+ public void init(AntContext context, String componentType)
+ throws ExecutionException {
this.context = context;
+ this.componentType = componentType;
+
org.apache.ant.common.util.Location contextLocation
- = context.getModelElement().getLocation();
+ = context.getLocation();
if (contextLocation
== org.apache.ant.common.util.Location.UNKNOWN_LOCATION) {
@@ -129,11 +154,6 @@ public abstract class ProjectComponent {
}
}
- /** Destroy this component */
- public void destroy() {
- // nothing to do
- }
-
/**
* Log a message as a build event
*
@@ -154,15 +174,5 @@ public abstract class ProjectComponent {
public void log(String message) {
log(message, Project.MSG_INFO);
}
-
-
- /**
- * Get the context associated with this component
- *
- * @return the AntContext
- */
- protected AntContext getContext() {
- return context;
- }
}
diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
index 70ceace6c..1b036962e 100644
--- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
+++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
@@ -54,8 +54,8 @@
package org.apache.tools.ant;
import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
-import org.apache.ant.common.model.BuildElement;
/**
* Ant1 Task facade
@@ -74,22 +74,6 @@ public abstract class Task extends ProjectComponent
/** The description of this task */
protected String description = null;
- /**
- * Initialise this component
- *
- * @param context the core context for this component
- * @exception ExecutionException if the component cannot be initialized
- */
- public void init(AntContext context) throws ExecutionException {
- super.init(context);
-
- if (context.getModelElement() instanceof BuildElement) {
- BuildElement buildElement = (BuildElement)context.getModelElement();
- taskType = buildElement.getType();
- taskName = taskType;
- }
- }
-
/**
* Set the name to use in logging messages.
*
@@ -147,12 +131,39 @@ public abstract class Task extends ProjectComponent
return description;
}
+ /**
+ * Initialise this component
+ *
+ * @param context the core context for this component
+ * @param componentType the component type of this component
+ * @exception ExecutionException if the component cannot be initialized
+ */
+ public void init(AntContext context, String componentType)
+ throws ExecutionException {
+ super.init(context, componentType);
+
+ taskType = componentType;
+ taskName = componentType;
+ }
+
/** Validate this component */
public void validateComponent() {
// no default validation for Ant1 tasks
}
+ /** Execute this task sending the appropriate build events */
+ public final void perform() {
+ try {
+ AntContext context = getAntContext();
+ ExecService execService
+ = (ExecService)context.getCoreService(ExecService.class);
+ execService.executeTask(this);
+ } catch (ExecutionException e) {
+ throw new BuildException(e);
+ }
+ }
+
/**
* Handle output captured for this task
*
diff --git a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java
index 5efda01ff..143362652 100644
--- a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java
+++ b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java
@@ -122,7 +122,7 @@ public class ScriptBase extends AbstractTask implements DeferredTask {
try {
BSFManager manager = new BSFManager();
manager.declareBean("self", this, getClass());
- manager.declareBean("context", getContext(), AntContext.class);
+ manager.declareBean("context", getAntContext(), AntContext.class);
// execute the script
BSFEngine engine = manager.loadScriptingEngine(language);
diff --git a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java
index 53d3c0ad6..7e8f92b8f 100644
--- a/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java
+++ b/proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java
@@ -139,9 +139,9 @@ public class ScriptFactory extends StandardLibFactory {
}
/**
- * Create an instance of the given task class
+ * Create an instance of the given component class
*
- * @param taskClass the class for which an instance is required
+ * @param componentClass the class for which an instance is required
* @param localName the name within the library undeer which the task is
* defined
* @return an instance of the required class
@@ -149,20 +149,20 @@ public class ScriptFactory extends StandardLibFactory {
* @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the task
*/
- public Object createTaskInstance(Class taskClass, String localName)
+ public Object createComponent(Class componentClass, String localName)
throws InstantiationException, IllegalAccessException,
ExecutionException {
- Object task = super.createTaskInstance(taskClass, localName);
+ Object component = super.createComponent(componentClass, localName);
- if (task instanceof ScriptDef) {
- ScriptDef scriptDef = (ScriptDef)task;
+ if (component instanceof ScriptDef) {
+ ScriptDef scriptDef = (ScriptDef)component;
scriptDef.setFactory(this);
- } else if (task instanceof ScriptBase) {
- ScriptBase scriptBase = (ScriptBase)task;
+ } else if (component instanceof ScriptBase) {
+ ScriptBase scriptBase = (ScriptBase)component;
scriptBase.setFactory(this);
scriptBase.setScriptName(localName);
}
- return task;
+ return component;
}
/**
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
index 3c55c0d0c..73f9a48ba 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
@@ -105,7 +105,7 @@ public class Ant extends AntBase {
*/
public void execute() throws ExecutionException {
if (baseDir == null) {
- baseDir = getContext().getBaseDir();
+ baseDir = getAntContext().getBaseDir();
}
if (antFile == null) {
antFile = new File(baseDir, "build.ant");
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
index 3a892ea6c..915283a70 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
@@ -253,10 +253,13 @@ public abstract class AntBase extends AbstractTask {
* Initialise this task
*
* @param context core's context
+ * @param componentType the component type of this component (i.e its
+ * defined name in the build file)
* @exception ExecutionException if we can't access the data service
*/
- public void init(AntContext context) throws ExecutionException {
- super.init(context);
+ public void init(AntContext context, String componentType)
+ throws ExecutionException {
+ super.init(context, componentType);
dataService = (DataService)getCoreService(DataService.class);
}
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
index ce47eb21b..b357d2263 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
@@ -70,7 +70,7 @@ public class AntCall extends AntBase {
*/
public void execute() throws ExecutionException {
setProperty(MagicProperties.BASEDIR,
- getContext().getBaseDir().getAbsolutePath());
+ getAntContext().getBaseDir().getAbsolutePath());
ExecService execService
= (ExecService)getCoreService(ExecService.class);
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java
index fa1803fc5..86946da4c 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java
@@ -143,7 +143,7 @@ public class Import extends AbstractTask {
* @exception ExecutionException if the components cannot be imported
*/
public void execute() throws ExecutionException {
- AntContext context = getContext();
+ AntContext context = getAntContext();
ComponentService componentService = (ComponentService)
context.getCoreService(ComponentService.class);
if (ref != null) {
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java
index c25703344..23c6f827d 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java
@@ -150,7 +150,7 @@ public class LibPath extends AbstractTask {
* the library
*/
public void execute() throws ExecutionException {
- AntContext context = getContext();
+ AntContext context = getAntContext();
ComponentService componentService = (ComponentService)
context.getCoreService(ComponentService.class);
componentService.addLibPath(libraryId, url);
diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java
index 061f4e70c..c8fd7c9fe 100644
--- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java
+++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java
@@ -148,7 +148,7 @@ public class LoadLib extends AbstractTask {
* loaded.
*/
public void execute() throws ExecutionException {
- AntContext context = getContext();
+ AntContext context = getAntContext();
ComponentService componentService = (ComponentService)
context.getCoreService(ComponentService.class);
componentService.loadLib(url.toString(), importAll);
diff --git a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java
index 530c7fdb8..09c1a8d6f 100644
--- a/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java
+++ b/proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java
@@ -138,6 +138,7 @@ public class Builder {
files.add(new File(TASKDEFS_ROOT, "LogStreamHandler.java"));
files.add(new File(TASKDEFS_ROOT, "LogOutputStream.java"));
files.add(new File(TASKDEFS_ROOT, "condition/Os.java"));
+ files.add(new File(TASKDEFS_ROOT, "condition/Contains.java"));
files.add(new File(TASKDEFS_ROOT, "condition/Condition.java"));
files.add(new File(TASKDEFS_ROOT, "Available.java"));
files.add(new File(TASKDEFS_ROOT, "Mkdir.java"));
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 55e9304d9..7e4164b78 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
@@ -54,50 +54,73 @@
package org.apache.ant.cli;
import java.io.PrintStream;
-import org.apache.ant.common.model.BuildElement;
-import org.apache.ant.common.model.Target;
+import org.apache.ant.common.antlib.ExecutionComponent;
+import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.event.BuildEvent;
+import org.apache.ant.common.event.MessageLevel;
+import org.apache.ant.common.model.Target;
import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.Location;
-import org.apache.ant.common.event.MessageLevel;
/**
- * Writes build event to a PrintStream. Currently, it only writes which
- * targets are being executed, and any messages that get logged.
+ * Writes build event to a PrintStream. Currently, it only writes which
+ * targets are being executed, and any messages that get logged.
*
- * @author Conor MacNeill
- * @created 15 January 2002
+ * @author Conor MacNeill
+ * @created 15 January 2002
*/
public class DefaultLogger implements BuildLogger {
- /** The stream where output should be written */
+ /** Standard field separator */
+ private static String lSep = System.getProperty("line.separator");
+ /** spacing to allow for task tags */
+ private static final int LEFT_COLUMN_SIZE = 12;
+
+ /** The stream where output should be written */
private PrintStream out;
- /** The stream to where errors should be written */
+ /** The stream to where errors should be written */
private PrintStream err;
- /** The level of messages which should be let through */
+ /** The level of messages which should be let through */
private int messageOutputLevel = MessageLevel.MSG_ERR;
- /** Controls whether adornments are added */
+ /** Controls whether adornments are added */
private boolean emacsMode = false;
- /** The time at which the build started */
+ /** The time at which the build started */
private long startTime = System.currentTimeMillis();
- /** Standard field separator */
- private static String lSep = System.getProperty("line.separator");
- /** spacing to allow for task tags */
- private static final int LEFT_COLUMN_SIZE = 12;
+ /**
+ * Format the time into something readable
+ *
+ * @param millis Java millis value
+ * @return the formatted time
+ */
+ protected static String formatTime(long millis) {
+ long seconds = millis / 1000;
+ long minutes = seconds / 60;
+
+ if (minutes > 0) {
+ return Long.toString(minutes) + " minute"
+ + (minutes == 1 ? " " : "s ")
+ + Long.toString(seconds % 60) + " second"
+ + (seconds % 60 == 1 ? "" : "s");
+ } else {
+ return Long.toString(seconds) + " second"
+ + (seconds % 60 == 1 ? "" : "s");
+ }
+
+ }
/**
- * Set the messageOutputLevel this logger is to respond to. Only
- * messages with a message level lower than or equal to the given level
- * are output to the log.
+ * Set the messageOutputLevel this logger is to respond to. Only
+ * messages with a message level lower than or equal to the given level
+ * are output to the log.
*
- * Constants for the message levels are in Project.java. The order of
- * the levels, from least to most verbose, is MSG_ERR, MSG_WARN,
- * MSG_INFO, MSG_VERBOSE, MSG_DEBUG. The default message level for
- * DefaultLogger is Project.MSG_ERR.
+ * Constants for the message levels are in Project.java. The order of
+ * the levels, from least to most verbose, is MSG_ERR, MSG_WARN,
+ * MSG_INFO, MSG_VERBOSE, MSG_DEBUG. The default message level for
+ * DefaultLogger is Project.MSG_ERR.
*
- * @param level the logging level for the logger.
+ * @param level the logging level for the logger.
*/
public void setMessageOutputLevel(int level) {
this.messageOutputLevel = level;
@@ -105,28 +128,27 @@ public class DefaultLogger implements BuildLogger {
/**
- * Set the output stream to which this logger is to send its output.
+ * Set the output stream to which this logger is to send its output.
*
- * @param output the output stream for the logger.
+ * @param output the output stream for the logger.
*/
public void setOutputPrintStream(PrintStream output) {
this.out = output;
}
/**
- * Set the output stream to which this logger is to send error
- * messages.
+ * Set the output stream to which this logger is to send error messages.
*
- * @param err the error stream for the logger.
+ * @param err the error stream for the logger.
*/
public void setErrorPrintStream(PrintStream err) {
this.err = err;
}
/**
- * Set this logger to produce emacs (and other editor) friendly output.
+ * Set this logger to produce emacs (and other editor) friendly output.
*
- * @param emacsMode true if output is to be unadorned so that emacs and
+ * @param emacsMode true if output is to be unadorned so that emacs and
* other editors can parse files names, etc.
*/
public void setEmacsMode(boolean emacsMode) {
@@ -134,9 +156,9 @@ public class DefaultLogger implements BuildLogger {
}
/**
- * Report an exception
+ * Report an exception
*
- * @param t The exception to be reported.
+ * @param t The exception to be reported.
*/
public void reportException(Throwable t) {
if (t instanceof AntException) {
@@ -161,18 +183,18 @@ public class DefaultLogger implements BuildLogger {
}
/**
- * Description of the Method
+ * Description of the Method
*
- * @param event Description of Parameter
+ * @param event Description of Parameter
*/
public void buildStarted(BuildEvent event) {
startTime = System.currentTimeMillis();
}
/**
- * Description of the Method
+ * Description of the Method
*
- * @param event Description of Parameter
+ * @param event Description of Parameter
*/
public void buildFinished(BuildEvent event) {
Throwable cause = event.getCause();
@@ -190,9 +212,9 @@ public class DefaultLogger implements BuildLogger {
}
/**
- * Description of the Method
+ * Description of the Method
*
- * @param event Description of Parameter
+ * @param event Description of Parameter
*/
public void targetStarted(BuildEvent event) {
if (MessageLevel.MSG_INFO <= messageOutputLevel) {
@@ -202,33 +224,33 @@ public class DefaultLogger implements BuildLogger {
}
/**
- * Description of the Method
+ * Description of the Method
*
- * @param event Description of Parameter
+ * @param event Description of Parameter
*/
public void targetFinished(BuildEvent event) {
}
/**
- * Description of the Method
+ * Description of the Method
*
- * @param event Description of Parameter
+ * @param event Description of Parameter
*/
public void taskStarted(BuildEvent event) {
}
/**
- * Description of the Method
+ * Description of the Method
*
- * @param event Description of Parameter
+ * @param event Description of Parameter
*/
public void taskFinished(BuildEvent event) {
}
/**
- * Description of the Method
+ * Description of the Method
*
- * @param event Description of Parameter
+ * @param event Description of Parameter
*/
public void messageLogged(BuildEvent event) {
PrintStream logTo
@@ -236,20 +258,26 @@ public class DefaultLogger implements BuildLogger {
// Filter out messages based on priority
if (event.getPriority() <= messageOutputLevel) {
-
- if (event.getModelElement() instanceof BuildElement) {
- // Print out the name of the task if we're in one
- BuildElement buildElement
- = (BuildElement)event.getModelElement();
- String name = buildElement.getType();
+ String name = null;
+ Object source = event.getSource();
+ if (source instanceof Task) {
+ name = ((Task)source).getTaskName();
+ }
+
+ if (name == null && source instanceof ExecutionComponent) {
+ name = ((ExecutionComponent)source).getComponentType();
+ }
+
+ if (name != null) {
+ // Print out the name of the task if we're in one
if (!emacsMode) {
- String msg = "[" + name + "] ";
- int indentSize = LEFT_COLUMN_SIZE - msg.length();
+ String tag = "[" + name + "] ";
+ int indentSize = LEFT_COLUMN_SIZE - tag.length();
for (int i = 0; i < indentSize; i++) {
logTo.print(" ");
}
- logTo.print(msg);
+ logTo.print(tag);
}
}
@@ -257,27 +285,5 @@ public class DefaultLogger implements BuildLogger {
logTo.println(event.getMessage());
}
}
-
- /**
- * Format the time into something readable
- *
- * @param millis Java millis value
- * @return the formatted time
- */
- protected static String formatTime(long millis) {
- long seconds = millis / 1000;
- long minutes = seconds / 60;
-
- if (minutes > 0) {
- return Long.toString(minutes) + " minute"
- + (minutes == 1 ? " " : "s ")
- + Long.toString(seconds % 60) + " second"
- + (seconds % 60 == 1 ? "" : "s");
- } else {
- return Long.toString(seconds) + " second"
- + (seconds % 60 == 1 ? "" : "s");
- }
-
- }
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java
index 7ce50cf3b..8ce2a8122 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java
@@ -65,15 +65,43 @@ public abstract class AbstractComponent implements ExecutionComponent {
/** The components's context */
private AntContext context;
+ /**
+ * the type of the component. The type is the name of the component in
+ * the build file. This may be different from the name under which this
+ * componenent is known in its library due to aliasing
+ */
+ private String componentType;
+
+ /**
+ * Get this component's context
+ *
+ * @return the component context
+ */
+ public AntContext getAntContext() {
+ return context;
+ }
+
+ /**
+ * Gets the componentType of the AbstractComponent
+ *
+ * @return the componentType value
+ */
+ public String getComponentType() {
+ return componentType;
+ }
+
/**
* Initialise the component. The component may use the AntContext to
* request services from the Ant core.
*
* @param context the component's context
+ * @param componentType the type of the component
* @exception ExecutionException if initialisation fails
*/
- public void init(AntContext context) throws ExecutionException {
+ public void init(AntContext context, String componentType)
+ throws ExecutionException {
this.context = context;
+ this.componentType = componentType;
}
/**
@@ -87,15 +115,6 @@ public abstract class AbstractComponent implements ExecutionComponent {
// no validation by default
}
- /**
- * Get this component's context
- *
- * @return the component context
- */
- protected AntContext getContext() {
- return context;
- }
-
/**
* Short cut to get a core service instance
*
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
index eb1449f21..6cccaa9ba 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
@@ -60,9 +60,26 @@ package org.apache.ant.common.antlib;
* @created 16 January 2002
*/
public abstract class AbstractTask extends AbstractComponent implements Task {
- /** Task is about to be cleaned up */
- public void destroy() {
- // do nothing here
+ /** The name of this task. */
+ private String taskName;
+
+ /**
+ * Sets the taskName of the AbstractTask
+ *
+ * @param taskName the new taskName value
+ */
+ public final void setTaskName(String taskName) {
+ this.taskName = taskName;
+ }
+
+ /**
+ * Gets the taskName of the AbstractTask
+ *
+ * @return the taskName value
+ */
+ public final String getTaskName() {
+ return taskName;
}
+
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
index b16f36e1b..1f4ac3525 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
@@ -53,9 +53,8 @@
*/
package org.apache.ant.common.antlib;
import java.io.File;
-import org.apache.ant.common.model.ModelElement;
-
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
@@ -95,10 +94,10 @@ public interface AntContext {
File getBaseDir();
/**
- * Get the model element associated with this context
+ * Gets the location associated witj the AntContext
*
- * @return the modelElement associated with this context
+ * @return the location
*/
- ModelElement getModelElement();
+ Location getLocation();
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java
index ce6736c62..95461273f 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java
@@ -64,21 +64,6 @@ import org.apache.ant.common.util.ExecutionException;
* @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
- * @param localName the name within the library under which the type is
- * defined
- * @return an instance of the required class
- * @exception InstantiationException if the class cannot be instantiated
- * @exception IllegalAccessException if the instance cannot be accessed
- * @exception ExecutionException if there is a problem creating the type
- */
- Object createTypeInstance(Class typeClass, String localName)
- throws InstantiationException, IllegalAccessException,
- ExecutionException;
-
/**
* Initialise the factory
*
@@ -88,9 +73,9 @@ public interface AntLibFactory {
void init(AntContext context) throws ExecutionException;
/**
- * Create an instance of the given task class
+ * Create an instance of the given component class
*
- * @param taskClass the class for which an instance is required
+ * @param componentClass the class for which an instance is required
* @param localName the name within the library under which the task is
* defined
* @return an instance of the required class
@@ -98,7 +83,7 @@ public interface AntLibFactory {
* @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the task
*/
- Object createTaskInstance(Class taskClass, String localName)
+ Object createComponent(Class componentClass, String localName)
throws InstantiationException, IllegalAccessException,
ExecutionException;
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
index ba524a23d..a1dcd820d 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
@@ -67,17 +67,34 @@ public interface ExecutionComponent {
* services from the Ant core.
*
* @param context the Task's context
+ * @param componentType the type of the component
* @exception ExecutionException if the component cannot be initialised
*/
- void init(AntContext context) throws ExecutionException;
+ void init(AntContext context, String componentType)
+ throws ExecutionException;
/**
* Validate the component. This is called after the element has been
* configured from its build model. The element may perform validation
* of its configuration
*
- * @exception ExecutionException if the component is not validly configured
+ * @exception ExecutionException if the component is not validly
+ * configured
*/
void validateComponent() throws ExecutionException;
+
+ /**
+ * Get the AntContext associated with this component
+ *
+ * @return the component's context
+ */
+ AntContext getAntContext();
+
+ /**
+ * Get the type of the component in the build file
+ *
+ * @return the type of the component
+ */
+ String getComponentType();
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
index 8f86faaff..c37a0b7e7 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
@@ -66,9 +66,9 @@ public class StandardLibFactory implements AntLibFactory {
private AntContext context;
/**
- * Create an instance of the given task class
+ * Create an instance of the given component class
*
- * @param taskClass the class for which an instance is required
+ * @param componentClass the class for which an instance is required
* @param localName the name within the library under which the task is
* defined
* @return an instance of the required class
@@ -76,27 +76,10 @@ public class StandardLibFactory implements AntLibFactory {
* @exception IllegalAccessException if the instance cannot be accessed
* @exception ExecutionException if there is a problem creating the task
*/
- public Object createTaskInstance(Class taskClass, String localName)
+ public Object createComponent(Class componentClass, String localName)
throws InstantiationException, IllegalAccessException,
ExecutionException {
- return taskClass.newInstance();
- }
-
- /**
- * Create an instance of the given type class
- *
- * @param typeClass the class for which an instance is required
- * @param localName the name within the library under which the type is
- * defined, if any.
- * @return an instance of the required class
- * @exception InstantiationException if the class cannot be instantiated
- * @exception IllegalAccessException if the instance cannot be accessed
- * @exception ExecutionException if there is a problem creating the type
- */
- public Object createTypeInstance(Class typeClass, String localName)
- throws InstantiationException, IllegalAccessException,
- ExecutionException {
- return typeClass.newInstance();
+ return componentClass.newInstance();
}
/**
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java
index a3f8a3af5..da16f1dd5 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java
@@ -68,7 +68,18 @@ public interface Task extends ExecutionComponent {
*/
void execute() throws ExecutionException;
- /** Task is about to be cleaned up */
- void destroy();
+ /**
+ * Sets the taskName of the Task
+ *
+ * @param name the new taskName value
+ */
+ void setTaskName(String name);
+
+ /**
+ * Gets the taskName of the Task
+ *
+ * @return the taskName value
+ */
+ String getTaskName();
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
index 4785b6609..9d492f710 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
@@ -54,7 +54,6 @@
package org.apache.ant.common.event;
import java.util.EventObject;
-import org.apache.ant.common.model.ModelElement;
/**
* A BuildEvent indicates the occurence of a significant event in the build.
@@ -170,18 +169,5 @@ public class BuildEvent extends EventObject {
return cause;
}
- /**
- * Gets the modelElement of the BuildEvent
- *
- * @return the model element this event is associated with
- */
- public ModelElement getModelElement() {
- Object source = getSource();
- if (source instanceof ModelElement) {
- return (ModelElement)getSource();
- }
-
- return null;
- }
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
index 6fdc7bcaf..ad2a223bb 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
@@ -158,5 +158,18 @@ public interface ComponentService {
*/
void importFrameComponent(String relativeName, String alias)
throws ExecutionException;
+
+ /**
+ * Create a component. The component will have a context but will not be
+ * configured. It should be configured using the appropriate set methods
+ * and then validated before being used.
+ *
+ * @param componentName the name of the component
+ * @return the created component. The return type of this method depends
+ * on the component type.
+ * @exception ExecutionException if the component cannot be created
+ */
+ Object createComponent(String componentName) throws ExecutionException;
+
}
diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
index 6e31723ee..fcdf28ed2 100644
--- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
+++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
@@ -55,6 +55,7 @@ package org.apache.ant.common.service;
import java.io.File;
import java.util.List;
import java.util.Map;
+import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.util.ExecutionException;
@@ -97,5 +98,13 @@ public interface ExecService {
void callTarget(Map properties, List targets)
throws ExecutionException;
+ /**
+ * execute a task. The task should have already been initialised by
+ * the core
+ *
+ * @param task the task to be executed.
+ * @exception ExecutionException if there is a problem in execution.
+ */
+ void executeTask(Task task) throws ExecutionException;
}
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 fd551e885..bf3f57079 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
@@ -267,5 +267,20 @@ public class LoaderUtils {
}
return urls;
}
+
+ /**
+ * Set the context loader of the current thread and returns the existing
+ * classloader
+ *
+ * @param newLoader the new context loader
+ * @return the old context loader
+ */
+ public static ClassLoader setContextLoader(ClassLoader newLoader) {
+ Thread thread = Thread.currentThread();
+ ClassLoader currentLoader = thread.getContextClassLoader();
+ thread.setContextClassLoader(newLoader);
+ return currentLoader;
+ }
+
}