|
- <html>
-
- <head>
- <meta http-equiv="Content-Language" content="en-us">
- <title>Writing Your Own Task</title>
- </head>
-
- <body>
- <h1>Developing with Ant</h1>
-
- <h2><a name="writingowntask">Writing Your Own Task</a></h2>
- <p>It is very easy to write your own task:</p>
- <ol>
- <li>Create a Java class that extends <code>org.apache.tools.ant.Task</code>.</li>
- <li>For each attribute, write a <i>setter</i> method. The setter method must be a
- <code>public void</code> method that takes a single argument. The
- name of the method must begin with <code>set</code>, followed by the
- attribute name, with the first character of the name in uppercase, and the rest in
- lowercase. The type of the attribute can be:
- <ul>
- <li>
- <code>String</code>
- </li>
- <li>
- any primitive type (they are converted for you from their String-representation
- in the buildfile)
- </li>
- <li>
- boolean - your method will be passed the value
- <i>true</i> if the value specified in the buildfile is one of <code>true</code>,
- <code>yes</code>, or <code>on</code>)
- </li>
- <li>
- <code>Class</code>
- </li>
- <li>
- <code>File</code>
- (in which case the value of the attribute is interpreted relative to the
- project's basedir)
- </li>
- <li>
- any other type that has a constructor with a single
- <code>String</code> argument
- </li>
- </ul>
- </li>
- <li>If your task has enumerated attributes, you should consider using
- a subclass of <code>org.apache.tools.ant.types.EnumeratedAttribute</code>
- as an argument
- to your setter method. See
- <code>org/apache/tools/ant/taskdefs/FixCRLF.java</code> for
- an example.</li>
- <li>If the task should support character data, write a <code>public void
- addText(String)</code> method.</li>
- <li>For each nested element, write a <i>create</i> or <i>add</i> method.
- A create method
- must be a <code>public</code> method that takes no arguments and returns
- an <code>Object</code> type. The name of the create method must begin with
- <code>create</code>, followed by the element name. An add method must be
- a <code>public void</code> method that takes a single argument of an
- <code>Object</code> type with a no-argument constructor.
- The name of the add method
- must begin with <code>add</code>, followed by the element name.</li>
- <li>Write a <code>public void execute</code> method, with no arguments, that
- throws a <code>BuildException</code>. This method implements the task
- itself.</li>
- </ol>
-
- <h3>The Life-cycle of a Task</h3>
- <ol>
- <li>The task gets instantiated using a no-argument constructor, at parser
- time. This means even tasks that are never executed get
- instantiated.</li>
-
- <li>The task gets references to its project and location inside the
- buildfile via its inherited <code>project</code> and
- <code>location</code> variables.</li>
-
- <li>If the user specified an <code>id</code> attribute to this task,
- the project
- registers a reference to this newly created task, at parser
- time.</li>
-
- <li>The task gets a reference to the target it belongs to via its
- inherited <code>target</code> variable.</li>
-
- <li><code>init()</code> is called at parser time.</li>
-
- <li>All child elements of the XML element corresponding to this task
- are created via this task's <code>createXXX()</code> methods or
- instantiated and added to this task via its <code>addXXX()</code>
- methods, at parser time.</li>
-
- <li>All attributes of this task get set via their corresponding
- <code>setXXX</code> methods, at runtime.</li>
-
- <li>The content character data sections inside the XML element
- corresponding to this task is added to the task via its
- <code>addText</code> method, at runtime.</li>
-
- <li>All attributes of all child elements get set via their corresponding
- <code>setXXX</code> methods, at runtime.</li>
-
- <li><code>execute()</code> is called at runtime. While the above initialization
- steps only occur once, the execute() method may be
- called more than once, if the task is invoked more than once. For example,
- if <code>target1</code> and <code>target2</code> both depend
- on <code>target3</code>, then running
- <code>'ant target1 target2'</code> will run all tasks in
- <code>target3</code> twice.</li>
- </ol>
-
- <h3>Example</h3>
- <p>Let's write our own task, which prints a message on the
- <code>System.out</code> stream.
- The
- task has one attribute, called <code>message</code>.</p>
- <blockquote>
- <pre>
- package com.mydomain;
-
- import org.apache.tools.ant.BuildException;
- import org.apache.tools.ant.Task;
-
- public class MyVeryOwnTask extends Task {
- private String msg;
-
- // The method executing the task
- public void execute() throws BuildException {
- System.out.println(msg);
- }
-
- // The setter for the "message" attribute
- public void setMessage(String msg) {
- this.msg = msg;
- }
- }
- </pre>
- </blockquote>
- <p>It's really this simple ;-)</p>
- <p>Adding your task to the system is rather simple too:</p>
- <ol>
- <li>Make sure the class that implements your task is in the classpath when
- starting Ant.</li>
- <li>Add a <code><taskdef></code> element to your project.
- This actually adds your task to the system.</li>
- <li>Use your task in the rest of the buildfile.</li>
- </ol>
-
-
- <h3>Example</h3>
- <blockquote>
- <pre>
- <?xml version="1.0"?>
-
- <project name="OwnTaskExample" default="main" basedir=".">
- <taskdef name="mytask" classname="com.mydomain.MyVeryOwnTask"/>
-
- <target name="main">
- <mytask message="Hello World! MyVeryOwnTask works!"/>
- </target>
- </project>
- </pre>
- </blockquote>
- <h3>Example 2</h3>
- To use a task directly from the buildfile which created it, place the
- <code><taskdef></code> declaration inside a target
- <i>after the compilation</i>. Use the <code>classpath</code> attribute of
- <code><taskdef></code> to point to where the code has just been
- compiled.
- <blockquote>
- <pre>
- <?xml version="1.0"?>
-
- <project name="OwnTaskExample2" default="main" basedir=".">
-
- <target name="build" >
- <mkdir dir="build"/>
- <javac srcdir="source" destdir="build"/>
- </target>
-
- <target name="declare" depends="build">
- <taskdef name="mytask"
- classname="com.mydomain.MyVeryOwnTask"
- classpath="build"/>
- </target>
-
- <target name="main" depends="declare">
- <mytask message="Hello World! MyVeryOwnTask works!"/>
- </target>
- </project>
- </pre>
- </blockquote>
-
-
- <p>Another way to add a task (more permanently), is to add the task name and
- implementing class name to the <code>default.properties</code> file in the
- <code>org.apache.tools.ant.taskdefs</code>
- package. Then you can use it as if it were a built-in task.</p>
-
- <hr>
- <h2><a name="buildevents">Build Events</a></h2>
- <P>Ant is capable of generating build events as it performs the tasks necessary to build a project.
- Listeners can be attached to Ant to receive these events. This capability could be used, for example,
- to connect Ant to a GUI or to integrate Ant with an IDE.
- </P>
- <p>To use build events you need to create an ant <code>Project</code> object. You can then call the
- <code>addBuildListener</code> method to add your listener to the project. Your listener must implement
- the <code>org.apache.tools.antBuildListener</code> interface. The listener will receive BuildEvents
- for the following events</P>
- <ul>
- <li>Build started</li>
- <li>Build finished</li>
- <li>Target started</li>
- <li>Target finished</li>
- <li>Task started</li>
- <li>Task finished</li>
- <li>Message logged</li>
- </ul>
-
- <p>
- If you wish to attach a listener from the command line you may use the
- <code>-listener</code> option. For example:</p>
- <blockquote>
- <pre>ant -listener org.apache.tools.ant.XmlLogger</pre>
- </blockquote>
- <p>will run Ant with a listener that generates an XML representation of the build progress. This
- listener is included with Ant, as is the default listener, which generates the logging to standard output.</p>
-
- <hr>
- <h2><a name="integration">Source code integration</a></h2>
-
-
- The other way to extend Ant through Java is to make changes to existing tasks, which is positively encouraged.
- Both changes to the existing source and new tasks can be incorporated back into the Ant codebase, which
- benefits all users and spreads the maintenance load around.
- <p>
-
- Please consult the
- <a href="http://jakarta.apache.org/site/getinvolved.html">Getting Involved</a> pages on the Jakarta web site
- for details on how to fetch the latest source and how to submit changes for reincorporation into the
- source tree.
- <p>
- Ant also has some
- <a href="http://jakarta.apache.org/ant/ant_task_guidelines.html">task guidelines</a>
- which provides some advice to people developing and testing tasks. Even if you intend to
- keep your tasks to yourself, you should still read this as it should be informative.
-
- <hr>
- <p align="center">Copyright © 2001-2002 Apache Software Foundation. All rights
- Reserved.</p>
-
- </body>
- </html>
|