Hi All,
I have been experimenting with writing extensions to ANT. I want to write a
extension that creates a dependency graph
between components of our system. I was thinking of defining a task which
looks something like this:
<component name="my_component">
<dependency name="javasrc"/>
<dependency name="jspsrc"/>
</component>
Each component's build script has a target 'dependency-graph' which uses
this tag to define it's dependencies. The ant task can then be used to
execute the 'dependency-graph' target for all the dependencies. The graph
can then be checked for cycles and used to perform a build etc.
The problem:
I found that when I used this structure the order of execute of methods for
a task was as follows:
A - Component.setName()
B - Component.init()
C - Component.createDependency()
D - Component$Depencency.setName()
E - Component.createDependency()
F - Component$Depencency.setName()
G - Component.execute()
This problem is that all the properties for 'component' are not set when the
Component.init() call is made (A), since the dependencies have not been
added (C-F). A preferable order for execution would be:
1 - Component.setName()
2 - Component.createDependency()
3 - Component$Depencency.setName()
4 - Component.createDependency()
5 - Component$Depencency.setName()
6 - Component.init()
7 - Component.execute()
Where init (6) has been called after the sub-elements of the component have
been set (2-5). I looked into the code and found that this could be achieved
by calling the init() method of a task during the endElement() method of the
TaskHandler SAX processing class. I have provided the code below and marked
what I have changed.
Is this change desirable, and would it have any negative impact on
functionality. I think that this would be a useful
change to make.
ABOUT ME
I am working for Another.com on a new build process. I would like ANT to be
the key tool for performing builds and deployment in our new build process.
I will be developing several new tasks in the process which I will be more
than happy to discuss and submit.
Keep up the good work!
Tim Wright
Java Developer
Another.com
-------------------------------------------------------
ProjectHelper$TaskHandler
/**
* Handler for all task elements.
*/
private class TaskHandler extends AbstractHandler {
private Target target;
private Task task;
public TaskHandler(DocumentHandler parentHandler, Target
target) {
super(parentHandler);
this.target = target;
}
public void init(String tag, AttributeList attrs) throws
SAXParseException
{
task = project.createTask(tag);
configure(task, attrs);
task.setLocation(new Location(buildFile.toString(),
locator.getLineNumber(), locator.getColumnNumber()));
//****Exectute the init after the sub-elements have been added
// task.init();
// Top level tasks don't have associated targets
if (target != null) {
task.setOwningTarget(target);
target.addTask(task);
}
}
public void characters(char[] buf, int start, int end) throws
SAXParseException {
String text = new String(buf, start, end).trim();
if (text.length() == 0) return;
IntrospectionHelper ih =
IntrospectionHelper.getHelper(task.getClass());
try {
ih.addText(task, text);
} catch (BuildException exc) {
throw new SAXParseException(exc.getMessage(),
locator, exc);
}
}
public void startElement(String name, AttributeList attrs)
throws
SAXParseException {
new NestedElementHandler(this, task).init(name, attrs);
}
// *****Execute the task initialisation after procesing sub-elements
public void endElement(String name) throws SAXException {
task.init();
super.endElement(name);
}
}