From 1910108c776c3e33b175bd1e948133361ded8412 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 27 Mar 2002 16:32:49 +0000 Subject: [PATCH] improve (at least I hope so ;-) the "Writing your Own Tasks" section. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272054 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/develop.html | 218 +++++++++++++++++++++++++++++---------- 1 file changed, 163 insertions(+), 55 deletions(-) diff --git a/docs/manual/develop.html b/docs/manual/develop.html index e9c66af87..5c13f64e5 100644 --- a/docs/manual/develop.html +++ b/docs/manual/develop.html @@ -16,51 +16,36 @@ public void method that takes a single argument. The name of the method must begin with set, 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: - - -
  • If your task has enumerated attributes, you should consider using -a subclass of org.apache.tools.ant.types.EnumeratedAttribute -as an argument -to your setter method. See -org/apache/tools/ant/taskdefs/FixCRLF.java for -an example.
  • -
  • If the task should support character data, write a public void -addText(String) method.
  • -
  • For each nested element, write a create or add method. -A create method -must be a public method that takes no arguments and returns -an Object type. The name of the create method must begin with -create, followed by the element name. An add method must be -a public void method that takes a single argument of an -Object type with a no-argument constructor. -The name of the add method -must begin with add, followed by the element name.
  • + + lowercase. That is, to support an attribute named + file you create a method setFile. + Depending on the type of the argument, Ant will perform some + conversions for you, see below. + +
  • If your task shall contain other tasks as nested elements (like + parallel), your + class must implement the interface + org.apache.tools.ant.TaskContainer. If you do so, your + task can not support any other nested elements. See + below.
  • + +
  • If the task should support character data (text nested between the +start end end tags), write a public void addText(String) +method. Note that Ant does not expand properties on +the text it passes to the task.
  • + +
  • For each nested element, write a create, add or +addConfigured method. A create method must be a +public method that takes no arguments and returns an +Object type. The name of the create method must begin +with create, followed by the element name. An add (or +addConfigured) method must be a public void method that +takes a single argument of an Object type with a +no-argument constructor. The name of the add (addConfigured) method +must begin with add (addConfigured), +followed by the element name. For a more complete discussion see +below.
  • +
  • Write a public void execute method, with no arguments, that throws a BuildException. This method implements the task itself.
  • @@ -101,7 +86,7 @@ itself.
  • All attributes of all child elements get set via their corresponding setXXX methods, at runtime.
  • -
  • execute() is called at runtime. While the above initialization +
  • execute() 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 target1 and target2 both depend @@ -110,6 +95,129 @@ itself.
  • target3 twice. +

    Conversions Ant will perform for attributes

    + +

    Ant will always expand properties before it passes the value of an +attribute to the corresponding setter method.

    + +

    The most common way to write an attribute setter is to use a +java.lang.String 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

    + + + +

    What happens if more than one setter method is present for a given +attribute? A method taking a String 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.

    + +

    Supporting nested elements

    + +

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

    + +

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

    + +

    Now you have a class NestedElement that is supposed to +be used for your nested <inner> elements, you have +three options:

    + +
      +
    1. public NestedElement createInner()
    2. +
    3. public void addInner(NestedElement anInner)
    4. +
    5. public void addConfiguredInner(NestedElement anInner)
    6. +
    + +

    What is the difference?

    + +

    Option 1 makes the task create the instance of +NestedElement, there are no restrictions on the type. +For the options 2 and 3, Ant has to create an instance of +NestedInner before it can pass it to the task, this +means, NestedInner must have a public no-arg +constructor. This is the only difference between options 1 and 2.

    + +

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

    + +

    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.

    + +

    TaskContainer

    + +

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

    + +

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

    +

    Example

    Let's write our own task, which prints a message on the System.out stream. @@ -123,17 +231,17 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; public class MyVeryOwnTask extends Task { - private String msg; + private String msg; - // The method executing the task - public void execute() throws BuildException { - System.out.println(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; - } + // The setter for the "message" attribute + public void setMessage(String msg) { + this.msg = msg; + } }