Browse Source

Add ability to define several tasks/types at once, reading definitions

from a property file.

Submitted by:	<cmanolache@yahoo.com>


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269355 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 24 years ago
parent
commit
2ecc6fa52a
4 changed files with 151 additions and 24 deletions
  1. +7
    -0
      WHATSNEW
  2. +26
    -4
      docs/manual/CoreTasks/taskdef.html
  3. +23
    -2
      docs/manual/CoreTasks/typedef.html
  4. +95
    -18
      src/main/org/apache/tools/ant/taskdefs/Definer.java

+ 7
- 0
WHATSNEW View File

@@ -31,6 +31,10 @@ Changes that could break older environments:
* The output generated by the xml formatter for <junit> has changed
again, it doesn't format the numeric value in the time attribute anymore.

* Pattern matching rules have changes slightly, the pattern foo*
doesn't match files contained in a directory named foo - use foo/*
instead.

Other changes:
--------------

@@ -120,6 +124,9 @@ Other changes:

* <junit> can now optionally set a property on test failure.

* <taskdef> can now define several tasks at once, reading the
name/classname pairs from a property file or resource.

Fixed bugs:
-----------



+ 26
- 4
docs/manual/CoreTasks/taskdef.html View File

@@ -13,6 +13,13 @@
used in the current project. Two attributes are needed, the name that identifies
this task uniquely, and the full name of the class (including the packages) that
implements this task.</p>
<p>You can also define a group of tasks at once using the file or
resource attributes. These attributes point to files in the format of
Java property files. Each line defines a single task in the
format:</p>
<pre>
taskname=fully.qualified.java.classname
</pre>
<p>Taskdef should be used to add your own tasks to the system. See also &quot;<a
href="../develop.html#writingowntask">Writing your own task</a>&quot;.</p>
<h3>Parameters</h3>
@@ -25,17 +32,32 @@ href="../develop.html#writingowntask">Writing your own task</a>&quot;.</p>
<tr>
<td valign="top">name</td>
<td valign="top">the name of the task</td>
<td valign="top" align="center">Yes</td>
<td valign="top" align="center">Yes, unless file or resource have
been specified.</td>
</tr>
<tr>
<td valign="top">classname</td>
<td valign="top">the full class name implementing the task</td>
<td valign="top" align="center">Yes</td>
<td valign="top" align="center">Yes, unless file or resource have
been specified.</td>
</tr>
<tr>
<td valign="top">file</td>
<td valign="top">Name of the property file to load
taskname/classname pairs from.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">resource</td>
<td valign="top">Name of the property resource to load
taskname/classname pairs from.</td>
<td valign="top" align="center">No</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>
use when looking up <code>classname</code> or
<code>resource</code>.</td>
<td align="center" valign="top">No</td>
</tr>
</table>
<h3>Parameters specified as nested elements</h3>


+ 23
- 2
docs/manual/CoreTasks/typedef.html View File

@@ -14,6 +14,13 @@ new type can be used in the current project. Two attributes are
needed, the name that identifies this data type uniquely, and the full
name of the class (including the packages) that implements this
type.</p>
<p>You can also define a group of data types at once using the file or
resource attributes. These attributes point to files in the format of
Java property files. Each line defines a single data type in the
format:</p>
<pre>
typename=fully.qualified.java.classname
</pre>
<p>Typedef should be used to add your own types to the system. Data
types are things like <a href="../using.html#path">paths</a> or <a
href="../CoreTypes/fileset.html">filesets</a> that can be defined at
@@ -29,12 +36,26 @@ the project level and referenced via their ID attribute.</p>
<tr>
<td valign="top">name</td>
<td valign="top">the name of the data type</td>
<td valign="top" align="center">Yes</td>
<td valign="top" align="center">Yes, unless file or resource have
been specified.</td>
</tr>
<tr>
<td valign="top">classname</td>
<td valign="top">the full class name implementing the data type</td>
<td valign="top" align="center">Yes</td>
<td valign="top" align="center">Yes, unless file or resource have
been specified.</td>
</tr>
<tr>
<td valign="top">file</td>
<td valign="top">Name of the property file to load
typename/classname pairs from.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">resource</td>
<td valign="top">Name of the property resource to load
typename/classname pairs from.</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">classpath</td> <td valign="top">the classpath to


+ 95
- 18
src/main/org/apache/tools/ant/taskdefs/Definer.java View File

@@ -57,17 +57,22 @@ package org.apache.tools.ant.taskdefs;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;

import java.util.*;
import java.io.*;

/**
* Base class for Taskdef and Typedef - does all the classpath
* handling and and class loading.
*
* @author costin@dnt.ro
* @author Costin Manolache
* @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public abstract class Definer extends Task {
private String name;
private String value;
private Path classpath;
private File file;
private String resource;

public void setClasspath(Path classpath) {
if (this.classpath == null) {
@@ -89,24 +94,73 @@ public abstract class Definer extends Task {
}

public void execute() throws BuildException {
if (name==null || value==null ) {
String msg = "name or classname attributes of "
+ getTaskName() + " element "
+ "are undefined";
throw new BuildException(msg);
}
try {
AntClassLoader al = null;
if (classpath != null) {
al = new AntClassLoader(project, classpath);
} else {
al = new AntClassLoader(project, Path.systemClasspath);
AntClassLoader al=createLoader();

if (file==null && resource==null ) {

// simple case - one definition
if ( name==null || value==null ) {
String msg = "name or classname attributes of "
+ getTaskName() + " element "
+ "are undefined";
throw new BuildException(msg);
}
// need to load Task via system classloader or the new
// task we want to define will never be a Task but always
// be wrapped into a TaskAdapter.
al.addSystemPackageRoot("org.apache.tools.ant");
addDefinition( al, name, value );

} else {

try {
if (name != null || value != null) {
String msg = "You must not specify name or value "
+ "together with file or resource.";
throw new BuildException(msg, location);
}
if (file != null && resource != null) {
String msg = "You must not specify both, file and resource.";
throw new BuildException(msg, location);
}

Properties props=new Properties();
InputStream is=null;
if( file != null ) {
log("Loading definitions from file " + file,
Project.MSG_VERBOSE);
is=new FileInputStream( file );
if (is == null) {
log("Could not load definitions from file " + file
+ ". It doesn\'t exist.", Project.MSG_WARN);
}
}
if( resource!=null ) {
log("Loading definitions from resource " + resource,
Project.MSG_VERBOSE);
is=al.getResourceAsStream( resource );
if (is == null) {
log("Could not load definitions from resource "
+ resource + ". It could not be found.",
Project.MSG_WARN);
}
}

if( is!=null ) {
props.load( is );
Enumeration keys=props.keys();
while( keys.hasMoreElements() ) {
String n=(String)keys.nextElement();
String v=props.getProperty( n );
addDefinition( al, n, v );
}
}
} catch( IOException ex ) {
throw new BuildException(ex, location);
}
}
}
private void addDefinition( ClassLoader al, String name, String value ) {
try {
Class c = al.loadClass(value);
AntClassLoader.initializeClass(c);
addDefinition(name, c);
@@ -120,7 +174,30 @@ public abstract class Definer extends Task {
throw new BuildException(msg, ncdfe, location);
}
}


private AntClassLoader createLoader() {
AntClassLoader al = null;
if (classpath != null) {
al = new AntClassLoader(project, classpath);
} else {
al = new AntClassLoader(project, Path.systemClasspath);
}
// need to load Task via system classloader or the new
// task we want to define will never be a Task but always
// be wrapped into a TaskAdapter.
al.addSystemPackageRoot("org.apache.tools.ant");
return al;
}

public void setFile( File file ) {
this.file=file;
}

public void setResource( String res ) {
this.resource=res;
}

public void setName( String name) {
this.name = name;
}


Loading…
Cancel
Save