bodewig 00/09/18 07:05:00
Modified: . build.xml
docs index.html
src/main/org/apache/tools/ant Project.java
ProjectHelper.java RuntimeConfigurable.java
Target.java Task.java
src/main/org/apache/tools/ant/taskdefs AntStructure.java
Taskdef.java
src/testcases/org/apache/tools/ant
IntrospectionHelperTest.java
src/testcases/org/apache/tools/ant/types PathTest.java
Added: src/main/org/apache/tools/ant UnknownElement.java
Log:
Allow tasks to be added at runtime and only fail if they cannot be
found at runtime.
Revision Changes Path
1.73 +11 -13 jakarta-ant/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-ant/build.xml,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- build.xml 2000/09/14 08:49:37 1.72
+++ build.xml 2000/09/18 14:04:46 1.73
@@ -12,7 +12,7 @@
<property name="Name" value="Ant"/>
<property name="name" value="ant"/>
- <property name="version" value="1.2alpha2"/>
+ <property name="version" value="1.2alpha3"/>
<property name="ant.home" value="."/>
<property name="src.bin.dir" value="src/bin"/>
@@ -178,6 +178,8 @@
<copydir src="${docs.dir}" dest="${ant.dist.dir}/docs"/>
<copydir src="${build.javadocs}" dest="${ant.dist.dir}/docs/api"/>
+ <fixcrlf srcdir="${ant.dist.dir}/bin" includes="ant,antRun"
cr="remove"/>
+ <fixcrlf srcdir="${ant.dist.dir}/bin" includes="*.bat" cr="add"/>
<chmod perm="+x">
<fileset dir="${ant.dist.dir}/bin">
<patternset refid="chmod.patterns"/>
@@ -185,6 +187,7 @@
</chmod>
<copyfile src="README" dest="${ant.dist.dir}/README"/>
+ <copyfile src="WHATSNEW" dest="${ant.dist.dir}/WHATSNEW"/>
<copyfile src="TODO" dest="${ant.dist.dir}/TODO"/>
<copyfile src="LICENSE" dest="${ant.dist.dir}/LICENSE"/>
</target>
@@ -302,11 +305,6 @@
<!-- Run testcase
-->
<!-- ===================================================================
-->
<target name="runtests" depends="compiletests" if="junit.present">
-
-<!--
- This would make the buildprocess fail if using an Ant version
- without the junit task
-
<junit printsummary="yes" fork="yes" haltonfailure="yes">
<classpath>
<pathelement location="${lib.dir}/${name}.jar" />
@@ -324,19 +322,19 @@
</fileset>
</batchtest>
</junit>
--->
-
- <java fork="yes"
- classname="junit.textui.TestRunner"
- taskname="junit">
- <arg value="org.apache.tools.ant.AllJUnitTests" />
+ <taskdef name="a" classname="A">
<classpath>
<pathelement location="${lib.dir}/${name}.jar" />
<pathelement location="${build.tests}" />
<path refid="classpath" />
<pathelement path="${java.class.path}" />
+ <path location="/tmp" />
</classpath>
- </java>
+ </taskdef>
+ <a test="set">
+Bla
+ <c test="1" />
+ </a>
</target>
</project>
1.104 +20 -0 jakarta-ant/docs/index.html
Index: index.html
===================================================================
RCS file: /home/cvs/jakarta-ant/docs/index.html,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -r1.103 -r1.104
--- index.html 2000/09/18 07:54:54 1.103
+++ index.html 2000/09/18 14:04:48 1.104
@@ -1002,7 +1002,17 @@
<td valign="top">file</td>
<td valign="top">the file to look for.</td>
</tr>
+ <tr>
+ <td valign="top">classpath</td> <td valign="top">the classpath to
+ use when looking up <code>classname</code>.</td> <td
+ align="center" valign="top">No</td>
+ </tr>
</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath</h4>
+<p><code>Available</code>'s <em>classpath</em> attribute is a <a
+href="#path">PATH like structure</a> and can also be set via a nested
+<em>classpath</em> element.</p>
<h3>Examples</h3>
<pre> <available classname="org.whatever.Myclass"
property="Myclass.present" /></pre>
<p>sets the property <code><i>Myclass.present</i></code> to the value
"true"
@@ -3650,7 +3660,17 @@
<td valign="top">the full class name implementing the task</td>
<td valign="top" align="center">Yes</td>
</tr>
+ <tr>
+ <td valign="top">classpath</td> <td valign="top">the classpath to
+ use when looking up <code>classname</code>.</td> <td
+ align="center" valign="top">No</td>
+ </tr>
</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath</h4>
+<p><code>Taskdef</code>'s <em>classpath</em> attribute is a <a
+href="#path">PATH like structure</a> and can also be set via a nested
+<em>classpath</em> element.</p>
<h3>Examples</h3>
<pre> <taskdef name="myjavadoc"
classname="com.mydomain.JavadocTask" /></pre>
<p>makes a task called <code>myjavadoc</code> available to Ant. The class
<code>com.mydomain.JavadocTask</code>
1.40 +1 -3 jakarta-ant/src/main/org/apache/tools/ant/Project.java
Index: Project.java
===================================================================
RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Project.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- Project.java 2000/09/18 08:50:08 1.39
+++ Project.java 2000/09/18 14:04:50 1.40
@@ -429,9 +429,7 @@
Class c = (Class) taskClassDefinitions.get(taskType);
if (c == null)
- throw new BuildException("Could not create task of type: "+taskType+
- " because I can't find it in the list of
task"+
- " class definitions");
+ return null;
try {
Object o = c.newInstance();
Task task = null;
1.30 +18 -2
jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java
Index: ProjectHelper.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/ProjectHelper.java,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- ProjectHelper.java 2000/09/14 14:04:38 1.29
+++ ProjectHelper.java 2000/09/18 14:04:51 1.30
@@ -363,7 +363,17 @@
}
public void init(String tag, AttributeList attrs) throws
SAXParseException {
- task = project.createTask(tag);
+ try {
+ task = project.createTask(tag);
+ } catch (BuildException e) {
+ // swallow here, will be thrown again in
+ // UnknownElement.maybeConfigure if the problem persists.
+ }
+
+ if (task == null) {
+ task = new UnknownElement(tag);
+ task.setProject(project);
+ }
task.setLocation(new Location(buildFile.toString(),
locator.getLineNumber(), locator.getColumnNumber()));
configureId(task, attrs);
@@ -422,7 +432,13 @@
IntrospectionHelper.getHelper(targetClass);
try {
- child = ih.createElement(target, propType.toLowerCase());
+ if (target instanceof UnknownElement) {
+ child = new UnknownElement(propType.toLowerCase());
+ ((UnknownElement) target).addChild((UnknownElement)
child);
+ } else {
+ child = ih.createElement(target, propType.toLowerCase());
+ }
+
configureId(child, attrs);
if (parentWrapper != null) {
1.2 +18 -0
jakarta-ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java
Index: RuntimeConfigurable.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- RuntimeConfigurable.java 2000/09/14 07:19:51 1.1
+++ RuntimeConfigurable.java 2000/09/18 14:04:51 1.2
@@ -80,6 +80,10 @@
wrappedObject = proxy;
}
+ void setProxy(Object proxy) {
+ wrappedObject = proxy;
+ }
+
/**
* Set's the attributes for the wrapped element.
*/
@@ -88,10 +92,24 @@
}
/**
+ * Returns the AttributeList of the wrapped element.
+ */
+ public AttributeList getAttributes() {
+ return attributes;
+ }
+
+ /**
* Adds child elements to the wrapped element.
*/
public void addChild(RuntimeConfigurable child) {
children.addElement(child);
+ }
+
+ /**
+ * Returns the child with index <code>index</code>.
+ */
+ RuntimeConfigurable getChild(int index) {
+ return (RuntimeConfigurable) children.elementAt(index);
}
/**
1.11 +7 -0 jakarta-ant/src/main/org/apache/tools/ant/Target.java
Index: Target.java
===================================================================
RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Target.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Target.java 2000/09/14 07:19:51 1.10
+++ Target.java 2000/09/18 14:04:53 1.11
@@ -159,6 +159,13 @@
}
}
+ void replaceTask(UnknownElement el, Task t) {
+ int index = -1;
+ while ((index = tasks.indexOf(el)) >= 0) {
+ tasks.setElementAt(t, index);
+ }
+ }
+
private boolean testIfCondition() {
return "".equals(ifCondition)
|| project.getProperty(ifCondition) != null;
1.14 +4 -0 jakarta-ant/src/main/org/apache/tools/ant/Task.java
Index: Task.java
===================================================================
RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/Task.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- Task.java 2000/09/14 07:19:51 1.13
+++ Task.java 2000/09/18 14:04:53 1.14
@@ -205,6 +205,10 @@
return wrapper;
}
+ protected void setRuntimeConfigurableWrapper(RuntimeConfigurable
wrapper) {
+ this.wrapper = wrapper;
+ }
+
/**
* Configure this task - if it hasn't been done already.
*/
1.1
jakarta-ant/src/main/org/apache/tools/ant/UnknownElement.java
Index: UnknownElement.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant;
import java.util.Vector;
/**
* Wrapper class that holds all information necessary to create a task
* that did not exist when Ant started.
*
* @author <a href="[EMAIL PROTECTED]">Stefan Bodewig</a>
*/
public class UnknownElement extends Task {
private String elementName;
private Task realTask;
private Vector children = new Vector();
public UnknownElement (String elementName) {
this.elementName = elementName;
}
/**
* return the corresponding XML tag.
*/
public String getTag() {
return elementName;
}
public void maybeConfigure() throws BuildException {
realTask = project.createTask(elementName);
if (realTask == null) {
throw new BuildException("Could not create task of type:
"+elementName+
" because I can\'t find it in the list
of task"+
" class definitions", location);
}
realTask.setLocation(location);
String id = wrapper.getAttributes().getValue("id");
if (id != null) {
project.addReference(id, realTask);
}
realTask.init();
// UnknownElement always has an associated target
realTask.setOwningTarget(target);
wrapper.setProxy(realTask);
realTask.setRuntimeConfigurableWrapper(wrapper);
handleChildren(realTask, wrapper);
realTask.maybeConfigure();
target.replaceTask(this, realTask);
}
/**
* Called when the real task has been configured for the first time.
*/
public void execute() {
if (realTask == null) {
// plain impossible to get here, maybeConfigure should
// have thrown an exception.
throw new BuildException("Could not create task of type: "
+ elementName, location);
}
realTask.execute();
}
public void addChild(UnknownElement child) {
children.addElement(child);
}
protected void handleChildren(Object parent,
RuntimeConfigurable parentWrapper)
throws BuildException {
if (parent instanceof TaskAdapter) {
parent = ((TaskAdapter) parent).getProxy();
}
Class parentClass = parent.getClass();
IntrospectionHelper ih = IntrospectionHelper.getHelper(parentClass);
for (int i=0; i<children.size(); i++) {
UnknownElement child = (UnknownElement) children.elementAt(i);
Object realChild = ih.createElement(parent, child.getTag());
RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
childWrapper.setProxy(realChild);
child.handleChildren(realChild, childWrapper);
}
}
}// UnknownElement
1.8 +2 -0
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
Index: AntStructure.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/AntStructure.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- AntStructure.java 2000/09/06 15:00:15 1.7
+++ AntStructure.java 2000/09/18 14:04:56 1.8
@@ -242,6 +242,8 @@
enum = ih.getAttributes();
while (enum.hasMoreElements()) {
String attrName = (String) enum.nextElement();
+ if ("id".equals(attrName)) continue;
+
sb.append(lSep).append(" ").append(attrName).append("
");
Class type = ih.getAttributeType(attrName);
if (type.equals(java.lang.Boolean.class) ||
1.9 +35 -2
jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
Index: Taskdef.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Taskdef.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Taskdef.java 2000/09/04 13:19:54 1.8
+++ Taskdef.java 2000/09/18 14:04:57 1.9
@@ -55,6 +55,7 @@
package org.apache.tools.ant.taskdefs;
import org.apache.tools.ant.*;
+import org.apache.tools.ant.types.*;
/**
* Define a new task - name and class
@@ -64,7 +65,27 @@
public class Taskdef extends Task {
private String name;
private String value;
+ private Path classpath;
+ public void setClasspath(Path classpath) {
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(project);
+ }
+ return this.classpath.createPath();
+ }
+
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
public void execute() throws BuildException {
if (name==null || value==null ) {
String msg = "name or classname attributes of taskdef element "
@@ -72,8 +93,20 @@
throw new BuildException(msg);
}
try {
- Class taskClass = Class.forName(value);
- project.addTaskDefinition(name, taskClass);
+ ClassLoader loader = null;
+ if (classpath != null) {
+ loader = new AntClassLoader(project, classpath, false);
+ } else {
+ loader = this.getClass().getClassLoader();
+ }
+
+ Class taskClass = null;
+ if (loader != null) {
+ taskClass = loader.loadClass(value);
+ } else {
+ taskClass = Class.forName(value);
+ }
+ project.addTaskDefinition(name, taskClass);
} catch (ClassNotFoundException cnfe) {
String msg = "taskdef class " + value +
" cannot be found";
1.3 +7 -1
jakarta-ant/src/testcases/org/apache/tools/ant/IntrospectionHelperTest.java
Index: IntrospectionHelperTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/IntrospectionHelperTest.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- IntrospectionHelperTest.java 2000/07/19 13:00:44 1.2
+++ IntrospectionHelperTest.java 2000/09/18 14:04:58 1.3
@@ -67,6 +67,8 @@
public class IntrospectionHelperTest extends TestCase {
+ public static boolean isUnixStyle = File.pathSeparatorChar == ':';
+
public IntrospectionHelperTest(String name) {
super(name);
}
@@ -404,7 +406,11 @@
}
public void setTen(File f) {
- assertEquals("/tmp/2", f.getAbsolutePath());
+ if (isUnixStyle) {
+ assertEquals("/tmp/2", f.getAbsolutePath());
+ } else {
+ assertEquals("c:\\tmp\\2", f.getAbsolutePath().toLowerCase());
+ }
}
public void setEleven(boolean b) {
1.6 +2 -2
jakarta-ant/src/testcases/org/apache/tools/ant/types/PathTest.java
Index: PathTest.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/types/PathTest.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- PathTest.java 2000/09/07 09:51:02 1.5
+++ PathTest.java 2000/09/18 14:04:59 1.6
@@ -129,7 +129,7 @@
assertEquals("/test", l[1]);
} else {
assertEquals("drives on DOS", 1, l.length);
- assertEquals("c:\\test", l[0]);
+ assertEquals("c:\\test", l[0].toLowerCase());
}
p = new Path(project, "c:/test");
@@ -141,7 +141,7 @@
assertEquals("/test", l[1]);
} else {
assertEquals("drives on DOS", 1, l.length);
- assertEquals("c:\\test", l[0]);
+ assertEquals("c:\\test", l[0].toLowerCase());
}
}