Browse Source

Refactor configuration out of Frame into Component Manager

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271453 13f79535-47bb-0310-9956-ffa450edef68
master
Conor MacNeill 23 years ago
parent
commit
bf844382c8
35 changed files with 857 additions and 875 deletions
  1. +1
    -1
      proposal/mutant/bootstrap.sh
  2. +2
    -2
      proposal/mutant/build.sh
  3. +2
    -2
      proposal/mutant/build/ant1compat.xml
  4. +0
    -49
      proposal/mutant/docs.xml
  5. +7
    -6
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java
  6. +404
    -16
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
  7. +8
    -77
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java
  8. +36
    -1
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
  9. +57
    -27
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java
  10. +26
    -448
      proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
  11. +22
    -39
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java
  12. +3
    -3
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
  13. +27
    -17
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java
  14. +28
    -17
      proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java
  15. +1
    -1
      proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java
  16. +9
    -9
      proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java
  17. +1
    -1
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java
  18. +5
    -2
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java
  19. +1
    -1
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java
  20. +1
    -1
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java
  21. +1
    -1
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java
  22. +1
    -1
      proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java
  23. +1
    -0
      proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java
  24. +84
    -78
      proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java
  25. +29
    -10
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java
  26. +20
    -3
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java
  27. +4
    -5
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java
  28. +3
    -18
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java
  29. +19
    -2
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java
  30. +4
    -21
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java
  31. +13
    -2
      proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java
  32. +0
    -14
      proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
  33. +13
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
  34. +9
    -0
      proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
  35. +15
    -0
      proposal/mutant/src/java/init/org/apache/ant/init/LoaderUtils.java

+ 1
- 1
proposal/mutant/bootstrap.sh View File

@@ -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

+ 2
- 2
proposal/mutant/build.sh View File

@@ -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 $@

+ 2
- 2
proposal/mutant/build/ant1compat.xml View File

@@ -28,8 +28,8 @@
<exclude name="org/apache/tools/ant/taskdefs/RecorderEntry.java"/>
<exclude name="org/apache/tools/ant/taskdefs/optional/Native2Ascii.java"/>
<exclude name="org/apache/tools/ant/taskdefs/optional/Javah.java"/>
<exclude name="org/apache/tools/ant/taskdefs/Parallel.java"/>
<exclude name="org/apache/tools/ant/taskdefs/Sequential.java"/>
<!-- <exclude name="org/apache/tools/ant/taskdefs/Parallel.java"/> -->
<!-- <exclude name="org/apache/tools/ant/taskdefs/Sequential.java"/> -->
<exclude name="org/apache/tools/ant/taskdefs/optional/jdepend/*.java"/>
</patternset>


+ 0
- 49
proposal/mutant/docs.xml View File

@@ -1,49 +0,0 @@
<project name="build-site" default="docs" basedir=".">

<!-- Initialization properties -->
<property name="project.name" value="mutant"/>
<property name="docs.src" location="xdocs"/>
<property name="docs.dest" location="docs"/>
<property name="project.file" value="stylesheets/project.xml" />
<property name="site.dir" location="../../../jakarta-site2" />
<property name="templ.path" location="xdocs/stylesheets" />
<property name="velocity.props" location="${docs.src}/velocity.properties" />

<path id="anakia.classpath">
<fileset dir="${site.dir}/lib">
<include name="*.jar"/>
</fileset>
</path>

<target name="prepare">
<available classname="org.apache.velocity.anakia.AnakiaTask"
property="AnakiaTask.present">
<classpath refid="anakia.classpath"/>
</available>
</target>

<target depends="prepare" name="prepare-error" unless="AnakiaTask.present">
<echo>
AnakiaTask is not present! Please check to make sure that
velocity.jar is in your classpath.
</echo>
</target>

<target name="docs" depends="prepare-error" if="AnakiaTask.present">
<taskdef name="anakia" classname="org.apache.velocity.anakia.AnakiaTask">
<classpath refid="anakia.classpath"/>
</taskdef>
<anakia basedir="${docs.src}" destdir="${docs.dest}/"
extension=".html" style="./site.vsl"
projectFile="${project.file}"
excludes="**/stylesheets/** faq.xml"
includes="**/*.xml"
lastModifiedCheck="true"
templatePath="${templ.path}"
velocityPropertiesFile="${velocity.props}">
</anakia>
</target>
<target name="all" depends="docs"/>
</project>

+ 7
- 6
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java View File

@@ -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();


+ 404
- 16
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java View File

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

}


proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java → proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java View File

@@ -52,88 +52,19 @@
* <http://www.apache.org/>.
*/
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 <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @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;
}
}


+ 36
- 1
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java View File

@@ -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 <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @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);
}
}
}


+ 57
- 27
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java View File

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


+ 26
- 448
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java View File

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


+ 22
- 39
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java View File

@@ -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.
*


+ 3
- 3
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java View File

@@ -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);


+ 27
- 17
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/ProjectComponent.java View File

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


+ 28
- 17
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Task.java View File

@@ -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
*


+ 1
- 1
proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptBase.java View File

@@ -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);


+ 9
- 9
proposal/mutant/src/java/antlibs/script/org/apache/ant/antlib/script/ScriptFactory.java View File

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

/**


+ 1
- 1
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java View File

@@ -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");


+ 5
- 2
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java View File

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



+ 1
- 1
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java View File

@@ -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);



+ 1
- 1
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Import.java View File

@@ -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) {


+ 1
- 1
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LibPath.java View File

@@ -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);


+ 1
- 1
proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/LoadLib.java View File

@@ -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);


+ 1
- 0
proposal/mutant/src/java/bootstrap/org/apache/ant/builder/Builder.java View File

@@ -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"));


+ 84
- 78
proposal/mutant/src/java/cli/org/apache/ant/cli/DefaultLogger.java View File

@@ -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 <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @created 15 January 2002
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a>
* @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. <P>
* 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. <P>
*
* 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");
}

}
}


+ 29
- 10
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractComponent.java View File

@@ -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
*


+ 20
- 3
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractTask.java View File

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

}


+ 4
- 5
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntContext.java View File

@@ -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();
}


+ 3
- 18
proposal/mutant/src/java/common/org/apache/ant/common/antlib/AntLibFactory.java View File

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



+ 19
- 2
proposal/mutant/src/java/common/org/apache/ant/common/antlib/ExecutionComponent.java View File

@@ -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();
}


+ 4
- 21
proposal/mutant/src/java/common/org/apache/ant/common/antlib/StandardLibFactory.java View File

@@ -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();
}

/**


+ 13
- 2
proposal/mutant/src/java/common/org/apache/ant/common/antlib/Task.java View File

@@ -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();
}


+ 0
- 14
proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java View File

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


+ 13
- 0
proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java View File

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

}


+ 9
- 0
proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java View File

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


+ 15
- 0
proposal/mutant/src/java/init/org/apache/ant/init/LoaderUtils.java View File

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

}


Loading…
Cancel
Save