git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271453 13f79535-47bb-0310-9956-ffa450edef68master
@@ -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 $* | 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 | # Use the full build as the build used by the build script | ||||
cp -r dist/* bootstrap | |||||
cp -r dist/lib bootstrap |
@@ -1,6 +1,6 @@ | |||||
#!/bin/sh | |||||
#!/bin/sh -x | |||||
# Copyright (c) 2000-2001 The Apache Software Foundation. All rights | # Copyright (c) 2000-2001 The Apache Software Foundation. All rights | ||||
# reserved. | # 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 $@ |
@@ -28,8 +28,8 @@ | |||||
<exclude name="org/apache/tools/ant/taskdefs/RecorderEntry.java"/> | <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/Native2Ascii.java"/> | ||||
<exclude name="org/apache/tools/ant/taskdefs/optional/Javah.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"/> | <exclude name="org/apache/tools/ant/taskdefs/optional/jdepend/*.java"/> | ||||
</patternset> | </patternset> | ||||
@@ -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> |
@@ -59,6 +59,7 @@ import java.util.List; | |||||
import org.apache.ant.common.model.ModelElement; | import org.apache.ant.common.model.ModelElement; | ||||
import org.apache.ant.common.event.BuildListener; | import org.apache.ant.common.event.BuildListener; | ||||
import org.apache.ant.common.event.BuildEvent; | 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 | * BuildEventSupport is used by classes which which to send build events to | ||||
@@ -162,10 +163,10 @@ public class BuildEventSupport { | |||||
/** | /** | ||||
* fire a task started event | * 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(); ) { | for (Iterator i = listeners.iterator(); i.hasNext(); ) { | ||||
BuildListener listener = (BuildListener)i.next(); | BuildListener listener = (BuildListener)i.next(); | ||||
listener.taskStarted(event); | listener.taskStarted(event); | ||||
@@ -175,12 +176,12 @@ public class BuildEventSupport { | |||||
/** | /** | ||||
* fire a task finished event | * 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 | * @param cause an exception if there was a failure in the task | ||||
*/ | */ | ||||
public void fireTaskFinished(ModelElement element, | |||||
public void fireTaskFinished(Task task, | |||||
Throwable cause) { | Throwable cause) { | ||||
BuildEvent event = new BuildEvent(element, BuildEvent.TASK_FINISHED, | |||||
BuildEvent event = new BuildEvent(task, BuildEvent.TASK_FINISHED, | |||||
cause); | cause); | ||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | for (Iterator i = listeners.iterator(); i.hasNext(); ) { | ||||
BuildListener listener = (BuildListener)i.next(); | BuildListener listener = (BuildListener)i.next(); | ||||
@@ -68,10 +68,17 @@ import org.apache.ant.antcore.antlib.ComponentLibrary; | |||||
import org.apache.ant.antcore.antlib.DynamicLibrary; | import org.apache.ant.antcore.antlib.DynamicLibrary; | ||||
import org.apache.ant.common.antlib.AntLibFactory; | import org.apache.ant.common.antlib.AntLibFactory; | ||||
import org.apache.ant.common.antlib.Converter; | 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.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.event.MessageLevel; | ||||
import org.apache.ant.common.model.BuildElement; | |||||
import org.apache.ant.common.service.ComponentService; | import org.apache.ant.common.service.ComponentService; | ||||
import org.apache.ant.common.util.ExecutionException; | 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 | * 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 | * @created 27 January 2002 | ||||
*/ | */ | ||||
public class ComponentManager implements ComponentService { | 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 | * Type converters for this frame. Converters are used when configuring | ||||
* Tasks to handle special type conversions. | * Tasks to handle special type conversions. | ||||
@@ -120,6 +124,10 @@ public class ComponentManager implements ComponentService { | |||||
*/ | */ | ||||
private Map libPathsMap; | private Map libPathsMap; | ||||
/** Reflector objects used to configure Tasks from the Task models. */ | |||||
private Map setters = new HashMap(); | |||||
/** | /** | ||||
* Constructor | * Constructor | ||||
* | * | ||||
@@ -279,26 +287,41 @@ public class ComponentManager implements ComponentService { | |||||
*/ | */ | ||||
public void importFrameComponent(String relativeName, String alias) | public void importFrameComponent(String relativeName, String alias) | ||||
throws ExecutionException { | throws ExecutionException { | ||||
ImportInfo definition | |||||
= frame.getReferencedDefinition(relativeName); | |||||
ImportInfo definition | |||||
= frame.getReferencedDefinition(relativeName); | |||||
if (definition == null) { | 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; | String label = alias; | ||||
if (label == null) { | if (label == null) { | ||||
label = frame.getNameInFrame(relativeName); | 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.getComponentLibrary().getLibraryId() + "\", class: " | ||||
+ definition.getClassName(), MessageLevel.MSG_DEBUG); | + definition.getClassName(), MessageLevel.MSG_DEBUG); | ||||
definitions.put(label, definition); | 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 | * Set the standard libraries (i.e. those which are independent of the | ||||
* build files) to be used in this component manager | * 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 | // go through the libraries and import all standard ant libraries | ||||
for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) { | for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) { | ||||
String libraryId = (String)i.next(); | String libraryId = (String)i.next(); | ||||
if (libraryId.startsWith(ANT_LIB_PREFIX)) { | |||||
if (libraryId.startsWith(Constants.ANT_LIB_PREFIX)) { | |||||
// standard library - import whole library | // standard library - import whole library | ||||
importLibrary(libraryId); | importLibrary(libraryId); | ||||
} | } | ||||
@@ -348,8 +371,9 @@ public class ComponentManager implements ComponentService { | |||||
if (libFactories.containsKey(libraryId)) { | if (libFactories.containsKey(libraryId)) { | ||||
return (AntLibFactory)libFactories.get(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) { | if (libFactory == null) { | ||||
libFactory = new StandardLibFactory(); | libFactory = new StandardLibFactory(); | ||||
} | } | ||||
@@ -368,6 +392,109 @@ public class ComponentManager implements ComponentService { | |||||
return (ImportInfo)definitions.get(name); | 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 | * Import a single component from the given library | ||||
* | * | ||||
@@ -390,6 +517,268 @@ public class ComponentManager implements ComponentService { | |||||
definitions.put(label, new ImportInfo(library, libDef)); | 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 | * Define a new component | ||||
* | * | ||||
@@ -445,8 +834,8 @@ public class ComponentManager implements ComponentService { | |||||
} | } | ||||
Converter converter | Converter converter | ||||
= libFactory.createConverter(converterClass); | = libFactory.createConverter(converterClass); | ||||
ExecutionContext context | |||||
= new ExecutionContext(frame); | |||||
ExecutionContext context = new ExecutionContext(frame, | |||||
null, Location.UNKNOWN_LOCATION); | |||||
converter.init(context); | converter.init(context); | ||||
Class[] converterTypes = converter.getTypes(); | Class[] converterTypes = converter.getTypes(); | ||||
for (int j = 0; j < converterTypes.length; ++j) { | for (int j = 0; j < converterTypes.length; ++j) { | ||||
@@ -475,6 +864,5 @@ public class ComponentManager implements ComponentService { | |||||
+ className, e); | + className, e); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -52,88 +52,19 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.execution; | 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> | * @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; | |||||
} | |||||
} | } | ||||
@@ -58,13 +58,16 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import org.apache.ant.antcore.modelparser.XMLProjectParser; | import org.apache.ant.antcore.modelparser.XMLProjectParser; | ||||
import org.apache.ant.antcore.xml.XMLParseException; | 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.model.Project; | ||||
import org.apache.ant.common.service.ExecService; | import org.apache.ant.common.service.ExecService; | ||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
import org.apache.ant.init.InitUtils; | 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> | * @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | ||||
* @created 8 February 2002 | * @created 8 February 2002 | ||||
@@ -132,5 +135,37 @@ public class CoreExecService implements ExecService { | |||||
runBuild(frame.getProject(), properties, targets); | 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); | |||||
} | |||||
} | |||||
} | } | ||||
@@ -54,8 +54,9 @@ | |||||
package org.apache.ant.antcore.execution; | package org.apache.ant.antcore.execution; | ||||
import java.io.File; | import java.io.File; | ||||
import org.apache.ant.common.antlib.AntContext; | 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.ExecutionException; | ||||
import org.apache.ant.common.util.Location; | |||||
/** | /** | ||||
* This is the core's implementation of the AntContext for all core objects. | * 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 */ | /** the event support instance used to manage build events */ | ||||
private BuildEventSupport eventSupport; | 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 | * Initilaise this context's environment | ||||
* | * | ||||
* @param frame the frame containing this context | * @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.frame = frame; | ||||
this.eventSupport = frame.getEventSupport(); | 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); | 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 | * Get the base directory for this execution of this frame | ||||
@@ -130,6 +124,15 @@ public class ExecutionContext implements AntContext { | |||||
return frame.getBaseDir(); | 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 | * Log a message as a build event | ||||
* | * | ||||
@@ -137,7 +140,7 @@ public class ExecutionContext implements AntContext { | |||||
* @param level the priority level of the message | * @param level the priority level of the message | ||||
*/ | */ | ||||
public void log(String message, int level) { | public void log(String message, int level) { | ||||
Object source = modelElement; | |||||
Object source = component; | |||||
if (source == null) { | if (source == null) { | ||||
source = frame.getProject(); | source = frame.getProject(); | ||||
if (source == null) { | if (source == null) { | ||||
@@ -146,5 +149,32 @@ public class ExecutionContext implements AntContext { | |||||
} | } | ||||
eventSupport.fireMessageLogged(source, message, level); | 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; | |||||
} | |||||
} | } | ||||
@@ -59,14 +59,8 @@ import java.util.Iterator; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.StringTokenizer; | 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.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.Task; | ||||
import org.apache.ant.common.antlib.TaskContainer; | |||||
import org.apache.ant.common.event.BuildListener; | import org.apache.ant.common.event.BuildListener; | ||||
import org.apache.ant.common.event.MessageLevel; | import org.apache.ant.common.event.MessageLevel; | ||||
import org.apache.ant.common.model.BuildElement; | import org.apache.ant.common.model.BuildElement; | ||||
@@ -93,9 +87,6 @@ import org.apache.ant.init.InitConfig; | |||||
* @created 14 January 2002 | * @created 14 January 2002 | ||||
*/ | */ | ||||
public class Frame { | public class Frame { | ||||
/** The Ant aspect used to identify Ant metadata */ | |||||
public static final String ANT_ASPECT = "ant"; | |||||
/** the base dir of the project */ | /** the base dir of the project */ | ||||
private File baseDir; | private File baseDir; | ||||
@@ -105,9 +96,6 @@ public class Frame { | |||||
/** The referenced frames corresponding to the referenced projects */ | /** The referenced frames corresponding to the referenced projects */ | ||||
private Map referencedFrames = new HashMap(); | 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 | * The context of this execution. This contains all data object's | ||||
* created by tasks that have been executed | * created by tasks that have been executed | ||||
@@ -155,6 +143,11 @@ public class Frame { | |||||
*/ | */ | ||||
private ComponentManager componentManager; | private ComponentManager componentManager; | ||||
/** | |||||
* The core's execution Service | |||||
*/ | |||||
private CoreExecService execService; | |||||
/** | /** | ||||
* Create an Execution Frame for the given project | * Create an Execution Frame for the given project | ||||
* | * | ||||
@@ -172,20 +165,6 @@ public class Frame { | |||||
this.initConfig = initConfig; | 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 | * Sets the Project of the Frame | ||||
* | * | ||||
@@ -210,6 +189,18 @@ public class Frame { | |||||
setMagicProperties(); | 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. | * Set a value in this frame or any of its imported frames. | ||||
* | * | ||||
@@ -625,48 +616,29 @@ public class Frame { | |||||
protected void executeTasks(Iterator taskIterator) | protected void executeTasks(Iterator taskIterator) | ||||
throws ExecutionException { | throws ExecutionException { | ||||
while (taskIterator.hasNext()) { | while (taskIterator.hasNext()) { | ||||
Throwable failureCause = null; | |||||
BuildElement model = (BuildElement)taskIterator.next(); | BuildElement model = (BuildElement)taskIterator.next(); | ||||
// what sort of element is this. | // 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 { | 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 { | } 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) { | if (typeId != null) { | ||||
setDataValue(typeId, typeInstance, true); | |||||
setDataValue(typeId, component, true); | |||||
} | } | ||||
} | } | ||||
} catch (AntException te) { | } catch (AntException te) { | ||||
ExecutionException e | ExecutionException e | ||||
= new ExecutionException(te, te.getLocation()); | = new ExecutionException(te, te.getLocation()); | ||||
e.setLocation(model.getLocation(), false); | e.setLocation(model.getLocation(), false); | ||||
failureCause = e; | |||||
throw e; | throw e; | ||||
} catch (RuntimeException e) { | } catch (RuntimeException e) { | ||||
ExecutionException ee = | ExecutionException ee = | ||||
new ExecutionException(e.getClass().getName() + ": " | new ExecutionException(e.getClass().getName() + ": " | ||||
+ e.getMessage(), e, model.getLocation()); | + e.getMessage(), e, model.getLocation()); | ||||
failureCause = ee; | |||||
throw ee; | throw ee; | ||||
} finally { | |||||
eventSupport.fireTaskFinished(model, failureCause); | |||||
} | } | ||||
} | } | ||||
@@ -737,30 +709,6 @@ public class Frame { | |||||
executeTasks(taskIterator); | 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 | * Determine the base directory for each frame in the frame hierarchy | ||||
* | * | ||||
@@ -806,383 +754,13 @@ public class Frame { | |||||
config.isRemoteLibAllowed(), config.getLibraryPathsMap()); | config.isRemoteLibAllowed(), config.getLibraryPathsMap()); | ||||
dataService = new CoreDataService(this, | dataService = new CoreDataService(this, | ||||
config.isUnsetPropertiesAllowed()); | config.isUnsetPropertiesAllowed()); | ||||
execService = new CoreExecService(this); | |||||
services.put(FileService.class, fileService); | services.put(FileService.class, fileService); | ||||
services.put(ComponentService.class, componentManager); | services.put(ComponentService.class, componentManager); | ||||
services.put(DataService.class, dataService); | services.put(DataService.class, dataService); | ||||
services.put(EventService.class, new CoreEventService(this)); | services.put(EventService.class, new CoreEventService(this)); | ||||
services.put(ExecService.class, new CoreExecService(this)); | |||||
} | |||||
/** | |||||
* 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); | |||||
} | } | ||||
} | } | ||||
@@ -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, | throws InstantiationException, IllegalAccessException, | ||||
ExecutionException { | ExecutionException { | ||||
try { | try { | ||||
java.lang.reflect.Constructor ctor = null; | |||||
java.lang.reflect.Constructor constructor = null; | |||||
// DataType can have a "no arg" constructor or take a single | // DataType can have a "no arg" constructor or take a single | ||||
// Project argument. | // Project argument. | ||||
Object o = null; | |||||
Object component = null; | |||||
try { | 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) { | } 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) { | } catch (java.lang.reflect.InvocationTargetException ite) { | ||||
Throwable t = ite.getTargetException(); | 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); | throw new ExecutionException(msg, t); | ||||
} catch (NoSuchMethodException e) { | } catch (NoSuchMethodException e) { | ||||
throw new ExecutionException("Unable to find an appropriate " | 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. | * Create a converter. | ||||
* | * | ||||
@@ -474,7 +474,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { | |||||
public void targetStarted(org.apache.ant.common.event.BuildEvent event) { | public void targetStarted(org.apache.ant.common.event.BuildEvent event) { | ||||
Target newTarget = new Target(this); | Target newTarget = new Target(this); | ||||
org.apache.ant.common.model.Target realTarget = | 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()); | newTarget.setName(realTarget.getName()); | ||||
targetStack.push(newTarget); | targetStack.push(newTarget); | ||||
fireTargetStarted(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) { | public void targetFinished(org.apache.ant.common.event.BuildEvent event) { | ||||
org.apache.ant.common.model.Target realTarget = | 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(); | Target currentTarget = (Target)targetStack.pop(); | ||||
fireTargetFinished(currentTarget, event.getCause()); | fireTargetFinished(currentTarget, event.getCause()); | ||||
currentTarget = null; | currentTarget = null; | ||||
@@ -881,7 +881,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { | |||||
try { | try { | ||||
task = (Task)c.newInstance(); | task = (Task)c.newInstance(); | ||||
task.setProject(this); | task.setProject(this); | ||||
task.init(context); | |||||
task.init(context, taskType); | |||||
return task; | return task; | ||||
} catch (Throwable e) { | } catch (Throwable e) { | ||||
throw new BuildException(e); | throw new BuildException(e); | ||||
@@ -69,6 +69,8 @@ public abstract class ProjectComponent { | |||||
protected Location location; | protected Location location; | ||||
/** The core context for this component */ | /** The core context for this component */ | ||||
private AntContext context; | private AntContext context; | ||||
/** The type of the component bneing created */ | |||||
private String componentType; | |||||
/** | /** | ||||
* Sets the project of the ProjectComponent | * Sets the project of the ProjectComponent | ||||
@@ -108,16 +110,39 @@ public abstract class ProjectComponent { | |||||
return location; | 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 | * Initialise this component | ||||
* | * | ||||
* @param context the core context for 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 | * @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.context = context; | ||||
this.componentType = componentType; | |||||
org.apache.ant.common.util.Location contextLocation | org.apache.ant.common.util.Location contextLocation | ||||
= context.getModelElement().getLocation(); | |||||
= context.getLocation(); | |||||
if (contextLocation | if (contextLocation | ||||
== org.apache.ant.common.util.Location.UNKNOWN_LOCATION) { | == 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 | * Log a message as a build event | ||||
* | * | ||||
@@ -154,15 +174,5 @@ public abstract class ProjectComponent { | |||||
public void log(String message) { | public void log(String message) { | ||||
log(message, Project.MSG_INFO); | log(message, Project.MSG_INFO); | ||||
} | } | ||||
/** | |||||
* Get the context associated with this component | |||||
* | |||||
* @return the AntContext | |||||
*/ | |||||
protected AntContext getContext() { | |||||
return context; | |||||
} | |||||
} | } | ||||
@@ -54,8 +54,8 @@ | |||||
package org.apache.tools.ant; | package org.apache.tools.ant; | ||||
import org.apache.ant.common.antlib.AntContext; | import org.apache.ant.common.antlib.AntContext; | ||||
import org.apache.ant.common.service.ExecService; | |||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
import org.apache.ant.common.model.BuildElement; | |||||
/** | /** | ||||
* Ant1 Task facade | * Ant1 Task facade | ||||
@@ -74,22 +74,6 @@ public abstract class Task extends ProjectComponent | |||||
/** The description of this task */ | /** The description of this task */ | ||||
protected String description = null; | 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. | * Set the name to use in logging messages. | ||||
* | * | ||||
@@ -147,12 +131,39 @@ public abstract class Task extends ProjectComponent | |||||
return description; | 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 */ | /** Validate this component */ | ||||
public void validateComponent() { | public void validateComponent() { | ||||
// no default validation for Ant1 tasks | // 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 | * Handle output captured for this task | ||||
* | * | ||||
@@ -122,7 +122,7 @@ public class ScriptBase extends AbstractTask implements DeferredTask { | |||||
try { | try { | ||||
BSFManager manager = new BSFManager(); | BSFManager manager = new BSFManager(); | ||||
manager.declareBean("self", this, getClass()); | manager.declareBean("self", this, getClass()); | ||||
manager.declareBean("context", getContext(), AntContext.class); | |||||
manager.declareBean("context", getAntContext(), AntContext.class); | |||||
// execute the script | // execute the script | ||||
BSFEngine engine = manager.loadScriptingEngine(language); | BSFEngine engine = manager.loadScriptingEngine(language); | ||||
@@ -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 | * @param localName the name within the library undeer which the task is | ||||
* defined | * defined | ||||
* @return an instance of the required class | * @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 IllegalAccessException if the instance cannot be accessed | ||||
* @exception ExecutionException if there is a problem creating the task | * @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, | throws InstantiationException, IllegalAccessException, | ||||
ExecutionException { | 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); | 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.setFactory(this); | ||||
scriptBase.setScriptName(localName); | scriptBase.setScriptName(localName); | ||||
} | } | ||||
return task; | |||||
return component; | |||||
} | } | ||||
/** | /** | ||||
@@ -105,7 +105,7 @@ public class Ant extends AntBase { | |||||
*/ | */ | ||||
public void execute() throws ExecutionException { | public void execute() throws ExecutionException { | ||||
if (baseDir == null) { | if (baseDir == null) { | ||||
baseDir = getContext().getBaseDir(); | |||||
baseDir = getAntContext().getBaseDir(); | |||||
} | } | ||||
if (antFile == null) { | if (antFile == null) { | ||||
antFile = new File(baseDir, "build.ant"); | antFile = new File(baseDir, "build.ant"); | ||||
@@ -253,10 +253,13 @@ public abstract class AntBase extends AbstractTask { | |||||
* Initialise this task | * Initialise this task | ||||
* | * | ||||
* @param context core's context | * @param context core's context | ||||
* @param componentType the component type of this component (i.e its | |||||
* defined name in the build file) | |||||
* @exception ExecutionException if we can't access the data service | * @exception 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); | dataService = (DataService)getCoreService(DataService.class); | ||||
} | } | ||||
@@ -70,7 +70,7 @@ public class AntCall extends AntBase { | |||||
*/ | */ | ||||
public void execute() throws ExecutionException { | public void execute() throws ExecutionException { | ||||
setProperty(MagicProperties.BASEDIR, | setProperty(MagicProperties.BASEDIR, | ||||
getContext().getBaseDir().getAbsolutePath()); | |||||
getAntContext().getBaseDir().getAbsolutePath()); | |||||
ExecService execService | ExecService execService | ||||
= (ExecService)getCoreService(ExecService.class); | = (ExecService)getCoreService(ExecService.class); | ||||
@@ -143,7 +143,7 @@ public class Import extends AbstractTask { | |||||
* @exception ExecutionException if the components cannot be imported | * @exception ExecutionException if the components cannot be imported | ||||
*/ | */ | ||||
public void execute() throws ExecutionException { | public void execute() throws ExecutionException { | ||||
AntContext context = getContext(); | |||||
AntContext context = getAntContext(); | |||||
ComponentService componentService = (ComponentService) | ComponentService componentService = (ComponentService) | ||||
context.getCoreService(ComponentService.class); | context.getCoreService(ComponentService.class); | ||||
if (ref != null) { | if (ref != null) { | ||||
@@ -150,7 +150,7 @@ public class LibPath extends AbstractTask { | |||||
* the library | * the library | ||||
*/ | */ | ||||
public void execute() throws ExecutionException { | public void execute() throws ExecutionException { | ||||
AntContext context = getContext(); | |||||
AntContext context = getAntContext(); | |||||
ComponentService componentService = (ComponentService) | ComponentService componentService = (ComponentService) | ||||
context.getCoreService(ComponentService.class); | context.getCoreService(ComponentService.class); | ||||
componentService.addLibPath(libraryId, url); | componentService.addLibPath(libraryId, url); | ||||
@@ -148,7 +148,7 @@ public class LoadLib extends AbstractTask { | |||||
* loaded. | * loaded. | ||||
*/ | */ | ||||
public void execute() throws ExecutionException { | public void execute() throws ExecutionException { | ||||
AntContext context = getContext(); | |||||
AntContext context = getAntContext(); | |||||
ComponentService componentService = (ComponentService) | ComponentService componentService = (ComponentService) | ||||
context.getCoreService(ComponentService.class); | context.getCoreService(ComponentService.class); | ||||
componentService.loadLib(url.toString(), importAll); | componentService.loadLib(url.toString(), importAll); | ||||
@@ -138,6 +138,7 @@ public class Builder { | |||||
files.add(new File(TASKDEFS_ROOT, "LogStreamHandler.java")); | files.add(new File(TASKDEFS_ROOT, "LogStreamHandler.java")); | ||||
files.add(new File(TASKDEFS_ROOT, "LogOutputStream.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/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, "condition/Condition.java")); | ||||
files.add(new File(TASKDEFS_ROOT, "Available.java")); | files.add(new File(TASKDEFS_ROOT, "Available.java")); | ||||
files.add(new File(TASKDEFS_ROOT, "Mkdir.java")); | files.add(new File(TASKDEFS_ROOT, "Mkdir.java")); | ||||
@@ -54,50 +54,73 @@ | |||||
package org.apache.ant.cli; | package org.apache.ant.cli; | ||||
import java.io.PrintStream; | 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.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.AntException; | ||||
import org.apache.ant.common.util.Location; | 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 { | 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; | private PrintStream out; | ||||
/** The stream to where errors should be written */ | |||||
/** The stream to where errors should be written */ | |||||
private PrintStream err; | 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; | private int messageOutputLevel = MessageLevel.MSG_ERR; | ||||
/** Controls whether adornments are added */ | |||||
/** Controls whether adornments are added */ | |||||
private boolean emacsMode = false; | private boolean emacsMode = false; | ||||
/** The time at which the build started */ | |||||
/** The time at which the build started */ | |||||
private long startTime = System.currentTimeMillis(); | 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) { | public void setMessageOutputLevel(int level) { | ||||
this.messageOutputLevel = 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) { | public void setOutputPrintStream(PrintStream output) { | ||||
this.out = 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) { | public void setErrorPrintStream(PrintStream err) { | ||||
this.err = 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. | * other editors can parse files names, etc. | ||||
*/ | */ | ||||
public void setEmacsMode(boolean emacsMode) { | 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) { | public void reportException(Throwable t) { | ||||
if (t instanceof AntException) { | 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) { | public void buildStarted(BuildEvent event) { | ||||
startTime = System.currentTimeMillis(); | 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) { | public void buildFinished(BuildEvent event) { | ||||
Throwable cause = event.getCause(); | 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) { | public void targetStarted(BuildEvent event) { | ||||
if (MessageLevel.MSG_INFO <= messageOutputLevel) { | 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) { | 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) { | 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) { | 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) { | public void messageLogged(BuildEvent event) { | ||||
PrintStream logTo | PrintStream logTo | ||||
@@ -236,20 +258,26 @@ public class DefaultLogger implements BuildLogger { | |||||
// Filter out messages based on priority | // Filter out messages based on priority | ||||
if (event.getPriority() <= messageOutputLevel) { | 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) { | 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++) { | for (int i = 0; i < indentSize; i++) { | ||||
logTo.print(" "); | logTo.print(" "); | ||||
} | } | ||||
logTo.print(msg); | |||||
logTo.print(tag); | |||||
} | } | ||||
} | } | ||||
@@ -257,27 +285,5 @@ public class DefaultLogger implements BuildLogger { | |||||
logTo.println(event.getMessage()); | 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"); | |||||
} | |||||
} | |||||
} | } | ||||
@@ -65,15 +65,43 @@ public abstract class AbstractComponent implements ExecutionComponent { | |||||
/** The components's context */ | /** The components's context */ | ||||
private AntContext 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 | * Initialise the component. The component may use the AntContext to | ||||
* request services from the Ant core. | * request services from the Ant core. | ||||
* | * | ||||
* @param context the component's context | * @param context the component's context | ||||
* @param componentType the type of the component | |||||
* @exception ExecutionException if initialisation fails | * @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.context = context; | ||||
this.componentType = componentType; | |||||
} | } | ||||
/** | /** | ||||
@@ -87,15 +115,6 @@ public abstract class AbstractComponent implements ExecutionComponent { | |||||
// no validation by default | // 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 | * Short cut to get a core service instance | ||||
* | * | ||||
@@ -60,9 +60,26 @@ package org.apache.ant.common.antlib; | |||||
* @created 16 January 2002 | * @created 16 January 2002 | ||||
*/ | */ | ||||
public abstract class AbstractTask extends AbstractComponent implements Task { | 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; | |||||
} | } | ||||
} | } | ||||
@@ -53,9 +53,8 @@ | |||||
*/ | */ | ||||
package org.apache.ant.common.antlib; | package org.apache.ant.common.antlib; | ||||
import java.io.File; | import java.io.File; | ||||
import org.apache.ant.common.model.ModelElement; | |||||
import org.apache.ant.common.util.ExecutionException; | 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 | * The AntContext is the interface through which the Ant container and the | ||||
@@ -95,10 +94,10 @@ public interface AntContext { | |||||
File getBaseDir(); | 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(); | |||||
} | } | ||||
@@ -64,21 +64,6 @@ import org.apache.ant.common.util.ExecutionException; | |||||
* @created 31 January 2002 | * @created 31 January 2002 | ||||
*/ | */ | ||||
public interface AntLibFactory { | 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 | * Initialise the factory | ||||
* | * | ||||
@@ -88,9 +73,9 @@ public interface AntLibFactory { | |||||
void init(AntContext context) throws ExecutionException; | 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 | * @param localName the name within the library under which the task is | ||||
* defined | * defined | ||||
* @return an instance of the required class | * @return an instance of the required class | ||||
@@ -98,7 +83,7 @@ public interface AntLibFactory { | |||||
* @exception IllegalAccessException if the instance cannot be accessed | * @exception IllegalAccessException if the instance cannot be accessed | ||||
* @exception ExecutionException if there is a problem creating the task | * @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, | throws InstantiationException, IllegalAccessException, | ||||
ExecutionException; | ExecutionException; | ||||
@@ -67,17 +67,34 @@ public interface ExecutionComponent { | |||||
* services from the Ant core. | * services from the Ant core. | ||||
* | * | ||||
* @param context the Task's context | * @param context the Task's context | ||||
* @param componentType the type of the component | |||||
* @exception ExecutionException if the component cannot be initialised | * @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 | * Validate the component. This is called after the element has been | ||||
* configured from its build model. The element may perform validation | * configured from its build model. The element may perform validation | ||||
* of its configuration | * 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; | 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(); | |||||
} | } | ||||
@@ -66,9 +66,9 @@ public class StandardLibFactory implements AntLibFactory { | |||||
private AntContext context; | 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 | * @param localName the name within the library under which the task is | ||||
* defined | * defined | ||||
* @return an instance of the required class | * @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 IllegalAccessException if the instance cannot be accessed | ||||
* @exception ExecutionException if there is a problem creating the task | * @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, | throws InstantiationException, IllegalAccessException, | ||||
ExecutionException { | 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(); | |||||
} | } | ||||
/** | /** | ||||
@@ -68,7 +68,18 @@ public interface Task extends ExecutionComponent { | |||||
*/ | */ | ||||
void execute() throws ExecutionException; | 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(); | |||||
} | } | ||||
@@ -54,7 +54,6 @@ | |||||
package org.apache.ant.common.event; | package org.apache.ant.common.event; | ||||
import java.util.EventObject; | import java.util.EventObject; | ||||
import org.apache.ant.common.model.ModelElement; | |||||
/** | /** | ||||
* A BuildEvent indicates the occurence of a significant event in the build. | * A BuildEvent indicates the occurence of a significant event in the build. | ||||
@@ -170,18 +169,5 @@ public class BuildEvent extends EventObject { | |||||
return cause; | 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; | |||||
} | |||||
} | } | ||||
@@ -158,5 +158,18 @@ public interface ComponentService { | |||||
*/ | */ | ||||
void importFrameComponent(String relativeName, String alias) | void importFrameComponent(String relativeName, String alias) | ||||
throws ExecutionException; | 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; | |||||
} | } | ||||
@@ -55,6 +55,7 @@ package org.apache.ant.common.service; | |||||
import java.io.File; | import java.io.File; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import org.apache.ant.common.antlib.Task; | |||||
import org.apache.ant.common.model.Project; | import org.apache.ant.common.model.Project; | ||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
@@ -97,5 +98,13 @@ public interface ExecService { | |||||
void callTarget(Map properties, List targets) | void callTarget(Map properties, List targets) | ||||
throws ExecutionException; | 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; | |||||
} | } | ||||
@@ -267,5 +267,20 @@ public class LoaderUtils { | |||||
} | } | ||||
return urls; | 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; | |||||
} | |||||
} | } | ||||