<!--
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->
<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
<title>Writing Your Own Task</title>
</head>

<body>
<h1>Developing with Apache 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>
      or <a href="base_task_classes.html">another class</a> that was designed to be extended.</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<a href="#footnote-1"><sup>*</sup></a>.  That is, to support an attribute named
    <code>file</code> you create a method <code>setFile</code>.
    Depending on the type of the argument, Ant will perform some
    conversions for you, see <a href="#set-magic">below</a>.</li>

  <li>If your task shall contain other tasks as nested elements (like
    <a href="Tasks/parallel.html"><code>parallel</code></a>), your
    class must implement the interface
    <code>org.apache.tools.ant.TaskContainer</code>.  If you do so, your
    task can not support any other nested elements.  See 
    <a href="#taskcontainer">below</a>.</li>

  <li>If the task should support character data (text nested between the
    start end end tags), write a <code>public void addText(String)</code>
    method.  Note that Ant does <strong>not</strong> expand properties on
    the text it passes to the task.</li>

  <li>For each nested element, write a <i>create</i>, <i>add</i> or
    <i>addConfigured</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 (or
    addConfigured) 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 (addConfigured) method
    must begin with <code>add</code> (<code>addConfigured</code>),
    followed by the element name.  For a more complete discussion see 
    <a href="#nested-elements">below</a>.</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>

<hr>
<p><a name="footnote-1">*</a> Actually the case of the letters after
the first one doesn't really matter to Ant, using all lower case is a
good convention, though.</p>

<h3>The Life-cycle of a Task</h3>
<ol>
  <li>
    The xml element that contains the tag corresponding to the
    task gets converted to an UnknownElement at parser time.
    This UnknownElement gets placed in a list within a target
    object, or recursively within another UnknownElement.
  </li>
  <li>
    When the target is executed, each UnknownElement is invoked
    using an <code>perform()</code> method. This instantiates
    the task. This means that tasks only gets
    instantiated at run time.
  </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 run
    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 run 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 run time.  Child elements corresponding
    to <code>addConfiguredXXX()</code> are created at this point but
    the actual <code>addConfigured</code> method is not called.</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>If child elements of the XML element corresponding to this task
    have been created for <code>addConfiguredXXX()</code> methods,
    those methods get invoked now.</li>

  <li><a name="execute"><code>execute()</code></a> is called at runtime.
    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><a name="set-magic">Conversions Ant will perform for attributes</a></h3>

<p>Ant will always expand properties before it passes the value of an
attribute to the corresponding setter method. <b>Since Ant 1.8</b>, it is
possible to <a href="Tasks/propertyhelper.html">extend Ant's property handling</a>
such that a non-string Object may be the result of the evaluation of a string
containing a single property reference. These will be assigned directly via
setter methods of matching type. Since it requires some beyond-the-basics
intervention to enable this behavior, it may be a good idea to flag attributes
intended to permit this usage paradigm.
</p>

<p>The most common way to write an attribute setter is to use a
<code>java.lang.String</code> argument.  In this case Ant will pass
the literal value (after property expansion) to your task.  But there
is more!  If the argument of you setter method is</p>

<ul>

  <li><code>boolean</code>, your method will be passed the value
  <i>true</i> if the value specified in the build file is one of
  <code>true</code>, <code>yes</code>, or <code>on</code> and
  <i>false</i> otherwise.</li>

  <li><code>char</code> or <code>java.lang.Character</code>, your
  method will be passed the first character of the value specified in
  the build file.</li>

  <li>any other primitive type (<code>int</code>, <code>short</code>
  and so on), Ant will convert the value of the attribute into this
  type, thus making sure that you'll never receive input that is not a
  number for that attribute.</li>

  <li><code>java.io.File</code>, Ant will first determine whether the
  value given in the build file represents an absolute path name.  If
  not, Ant will interpret the value as a path name relative to the
  project's basedir.</li>

  <li><code>org.apache.tools.ant.types.Resource</code>
  <code>org.apache.tools.ant.types.Resource</code>, Ant will
  resolve the string as a <code>java.io.File</code> as above, then
  pass in as a <code>org.apache.tools.ant.types.resources.FileResource</code>.
  <b>Since Ant 1.8</b>
  </li>

  <li><code>org.apache.tools.ant.types.Path</code>, Ant will tokenize
  the value specified in the build file, accepting <code>:</code> and
  <code>;</code> as path separators.  Relative path names will be
  interpreted as relative to the project's basedir.</li>

  <li><code>java.lang.Class</code>, Ant will interpret the value
  given in the build file as a Java class name and load the named
  class from the system class loader.</li>

  <li>any other type that has a constructor with a single
  <code>String</code> argument, Ant will use this constructor to
  create a new instance from the value given in the build file.</li>

  <li>A subclass of
  <code>org.apache.tools.ant.types.EnumeratedAttribute</code>, Ant
  will invoke this classes <code>setValue</code> method.  Use this if
  your task should support enumerated attributes (attributes with
  values that must be part of a predefined set of values).  See
  <code>org/apache/tools/ant/taskdefs/FixCRLF.java</code> and the
  inner <code>AddAsisRemove</code> class used in <code>setCr</code>
  for an example.</li>

  <li>A (Java 5) enumeration. Ant will call the setter with the enum constant
  matching the value given in the build file. This is easier than using
  <code>EnumeratedAttribute</code> and can result in cleaner code, but of course
  your task will not run on JDK 1.4 or earlier. Note that any override of
  <code>toString()</code> in the enumeration is ignored; the build file must use
  the declared name (see <code>Enum.getName()</code>). You may wish to use lowercase
  enum constant names, in contrast to usual Java style, to look better in build files.
  <em>As of Ant 1.7.0.</em></li>

</ul>

<p>What happens if more than one setter method is present for a given
attribute?  A method taking a <code>String</code> argument will always
lose against the more specific methods.  If there are still more
setters Ant could chose from, only one of them will be called, but we
don't know which, this depends on the implementation of your Java
virtual machine.</p>

<h3><a name="nested-elements">Supporting nested elements</a></h3>

<p>Let's assume your task shall support nested elements with the name
<code>inner</code>.  First of all, you need a class that represents
this nested element.  Often you simply want to use one of Ant's
classes like <code>org.apache.tools.ant.types.FileSet</code> to
support nested <code>fileset</code> elements.</p>

<p>Attributes of the nested elements or nested child elements of them
will be handled using the same mechanism used for tasks (i.e. setter
methods for attributes, addText for nested text and
create/add/addConfigured methods for child elements).</p>

<p>Now you have a class <code>NestedElement</code> that is supposed to
be used for your nested <code>&lt;inner&gt;</code> elements, you have
three options:</p>

<ol>
  <li><code>public NestedElement createInner()</code></li>
  <li><code>public void addInner(NestedElement anInner)</code></li>
  <li><code>public void addConfiguredInner(NestedElement anInner)</code></li>
</ol>

<p>What is the difference?</p>

<p>Option 1 makes the task create the instance of
<code>NestedElement</code>, there are no restrictions on the type.
For the options 2 and 3, Ant has to create an instance of
<code>NestedInner</code> before it can pass it to the task, this
means, <code>NestedInner</code> must have a <code>public</code> no-arg
  constructor or a <code>public</code> one-arg constructor
  taking a Project class as a parameter.
This is the only difference between options 1 and 2.</p>

<p>The difference between 2 and 3 is what Ant has done to the object
before it passes it to the method.  <code>addInner</code> will receive
an object directly after the constructor has been called, while
<code>addConfiguredInner</code> gets the object <em>after</em> the
attributes and nested children for this new object have been
handled.</p>

<p>What happens if you use more than one of the options?  Only one of
the methods will be called, but we don't know which, this depends on
the implementation of your Java virtual machine.</p>

<h3><a name="nestedtype">Nested Types</a></h3>
If your task needs to nest an arbitrary type that has been defined
  using <code>&lt;typedef&gt;</code> you have two options.
  <ol>
    <li><code>public void add(Type type)</code></li>
    <li><code>public void addConfigured(Type type)</code></li>
  </ol>
  The difference between 1 and 2 is the same as between 2 and 3 in the
  previous section.
  <p>
    For example suppose one wanted to handle objects object of type
    org.apache.tools.ant.taskdefs.condition.Condition, one may
    have a class:
  </p>
  <blockquote>
  <pre>
public class MyTask extends Task {
    private List conditions = new ArrayList();
    public void add(Condition c) {
        conditions.add(c);
    }
    public void execute() {
     // iterator over the conditions
    }
}
  </pre>
  </blockquote>
  <p>
    One may define and use this class like this:
  </p>
  <blockquote>
    <pre>
&lt;taskdef name="mytask" classname="MyTask" classpath="classes"/&gt;
&lt;typedef name="condition.equals"
         classname="org.apache.tools.ant.taskdefs.conditions.Equals"/&gt;
&lt;mytask&gt;
    &lt;condition.equals arg1="${debug}" arg2="true"/&gt;
&lt;/mytask&gt;
    </pre>
  </blockquote>
  <p>
    A more complicated example follows:
  </p>
  <blockquote>
    <pre>
public class Sample {
    public static class MyFileSelector implements FileSelector {
         public void setAttrA(int a) {}
         public void setAttrB(int b) {}
         public void add(Path path) {}
         public boolean isSelected(File basedir, String filename, File file) {
             return true;
         }
     }

    interface MyInterface {
        void setVerbose(boolean val);
    }        

    public static class BuildPath extends Path {
        public BuildPath(Project project) {
            super(project);
        }
        
        public void add(MyInterface inter) {}
        public void setUrl(String url) {}
    }

    public static class XInterface implements MyInterface {
        public void setVerbose(boolean x) {}
        public void setCount(int c) {}
    }
}
    </pre>
  </blockquote>
  <p>
    This class defines a number of static classes that implement/extend
    Path, MyFileSelector and MyInterface. These may be defined and used
    as follows:
  </p>
  <pre>
    <blockquote>
&lt;typedef name="myfileselector" classname="Sample$MyFileSelector"
         classpath="classes" loaderref="classes"/&gt;
&lt;typedef name="buildpath" classname="Sample$BuildPath"
         classpath="classes" loaderref="classes"/&gt;
&lt;typedef name="xinterface" classname="Sample$XInterface"
         classpath="classes" loaderref="classes"/&gt;

&lt;copy todir="copy-classes"&gt;
   &lt;fileset dir="classes"&gt;
      &lt;myfileselector attra="10" attrB="-10"&gt;
         &lt;buildpath path="." url="abc"&gt;
            &lt;xinterface count="4"/&gt;
         &lt;/buildpath&gt;
      &lt;/myfileselector&gt;
   &lt;/fileset&gt;
&lt;/copy&gt;
    </blockquote>
  </pre>

<h3><a name="taskcontainer">TaskContainer</a></h3>

<p>The <code>TaskContainer</code> consists of a single method,
<code>addTask</code> that basically is the same as an <a
href="#nested-elements">add method</a> for nested elements.  The task
instances will be configured (their attributes and nested elements
have been handled) when your task's <code>execute</code> method gets
invoked, but not before that.</p>

<p>When we <a href="#execute">said</a> <code>execute</code> would be
called, we lied ;-).  In fact, Ant will call the <code>perform</code>
method in <code>org.apache.tools.ant.Task</code>, which in turn calls
<code>execute</code>.  This method makes sure that <a
href="#buildevents">Build Events</a> will be triggered.  If you
execute the task instances nested into your task, you should also
invoke <code>perform</code> on these instances instead of
<code>execute</code>.</p>

<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 &quot;message&quot; 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>&lt;taskdef&gt;</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>
&lt;?xml version=&quot;1.0&quot;?&gt;

&lt;project name=&quot;OwnTaskExample&quot; default=&quot;main&quot; basedir=&quot;.&quot;&gt;
  &lt;taskdef name=&quot;mytask&quot; classname=&quot;com.mydomain.MyVeryOwnTask&quot;/&gt;

  &lt;target name=&quot;main&quot;&gt;
    &lt;mytask message=&quot;Hello World! MyVeryOwnTask works!&quot;/&gt;
  &lt;/target&gt;
&lt;/project&gt;
</pre>
</blockquote>

<h3>Example 2</h3>
To use a task directly from the buildfile which created it, place the
<code>&lt;taskdef&gt;</code> declaration inside a target
<i>after the compilation</i>. Use the <code>classpath</code> attribute of
<code>&lt;taskdef&gt;</code> to point to where the code has just been
compiled.
<blockquote>
<pre>
&lt;?xml version=&quot;1.0&quot;?&gt;

&lt;project name=&quot;OwnTaskExample2&quot; default=&quot;main&quot; basedir=&quot;.&quot;&gt;

  &lt;target name=&quot;build&quot; &gt;
    &lt;mkdir dir=&quot;build&quot;/&gt;
    &lt;javac srcdir=&quot;source&quot; destdir=&quot;build&quot;/&gt;
  &lt;/target&gt;

  &lt;target name=&quot;declare&quot; depends=&quot;build&quot;&gt;
    &lt;taskdef name=&quot;mytask&quot;
        classname=&quot;com.mydomain.MyVeryOwnTask&quot;
        classpath=&quot;build&quot;/&gt;
  &lt;/target&gt;

  &lt;target name=&quot;main&quot; depends=&quot;declare&quot;&gt;
    &lt;mytask message=&quot;Hello World! MyVeryOwnTask works!&quot;/&gt;
  &lt;/target&gt;
&lt;/project&gt;
</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 the build file invokes another build file via 
<a href="Tasks/ant.html"><code>&lt;ant&gt;</code></a> or 
<a href="Tasks/subant.html"><code>&lt;subant&gt;</code></a> or uses 
<a href="Tasks/antcall.html"><code>&lt;antcall&gt;</code></a>, you are creating a
new Ant "project" that will send target and task level events of its
own but never sends build started/finished events.  Ant 1.6.2
introduces an extension of the BuildListener interface named
SubBuildListener that will receive two new events for</p>
<ul>
  <li>SubBuild started</li>
  <li>SubBuild finished</li>
</ul>
<p>If you are interested in those events, all you need to do is to
implement the new interface instead of BuildListener (and register the
listener, of course).</p>

<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>

<p><b>Note: </b>A listener must not access System.out and System.err directly since output on 
these streams is redirected by Ant's core to the build event system. Accessing these 
streams can cause an infinite loop in Ant. Depending on the version of Ant, this will
either cause the build to terminate or the Java VM to run out of Stack space. A logger, also, may 
not access System.out and System.err directly. It must use the streams with which it has
been configured.</p>

<p><b>Note2:</b> All methods of a BuildListener except for the "Build
  Started" and "Build Finished" events may occur on several threads
  simultaneously - for example while Ant is executing
  a <code>&lt;parallel&gt;</code> task.</p>





<h3>Example</h3>
Writing an adapter to your favourite log library is very easy.
Just implent the BuildListener interface, instantiate your logger and delegate
the message to that instance. <br>
When starting your build provide your adapter class and the log library to the
build classpath and activate your logger via <code>-listener</code> option as
described above.

<blockquote>
<pre>
public class MyLogAdapter implements BuildListener {

    private MyLogger getLogger() {
        final MyLogger log = MyLoggerFactory.getLogger(Project.class.getName());
        return log;
    }

    @Override
    public void buildStarted(final BuildEvent event) {
        final MyLogger log = getLogger();
        log.info("Build started.");
    }

    @Override
    public void buildFinished(final BuildEvent event) {
        final MyLogger logger = getLogger();
        MyLogLevelEnum loglevel = ... // map event.getPriority() to enum via Project.MSG_* constants
        boolean allOK = event.getException() == null;
        String logmessage = ... // create log message using data of the event and the message invoked
        logger.log(loglevel, logmessage);
    }

    // implement all methods in that way
}
</pre>
</blockquote>



<hr>
<h2><a name="integration">Source code integration</a></h2>

<p>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>

<p>Please consult the
<a href="http://www.apache.org/foundation/getinvolved.html">Getting Involved</a> pages on the Apache web site
for details on how to fetch the latest source and how to submit changes for reincorporation into the
source tree.</p>

<p>Ant also has some
<a href="http://ant.apache.org/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.</p>

</body>
</html>

