From 753a6c60f47f3ac4f270005b65e9d6481de8eb68 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Fri, 23 Oct 2015 10:00:02 -0700 Subject: Adding maven and ant source trees Change-Id: I0a39b9add833a31b9c3f98d193983ae2f3a5a445 Signed-off-by: Ashlee Young --- .../src/ant/apache-ant-1.9.6/manual/develop.html | 544 +++++++++++++++++++++ 1 file changed, 544 insertions(+) create mode 100644 framework/src/ant/apache-ant-1.9.6/manual/develop.html (limited to 'framework/src/ant/apache-ant-1.9.6/manual/develop.html') diff --git a/framework/src/ant/apache-ant-1.9.6/manual/develop.html b/framework/src/ant/apache-ant-1.9.6/manual/develop.html new file mode 100644 index 00000000..ed06d301 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/manual/develop.html @@ -0,0 +1,544 @@ + + + + + + +Writing Your Own Task + + + +

Developing with Apache Ant

+ +

Writing Your Own Task

+

It is very easy to write your own task:

+
    +
  1. Create a Java class that extends org.apache.tools.ant.Task + or another class that was designed to be extended.
  2. + +
  3. For each attribute, write a setter method. The setter method must be a + 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*. 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.
  4. + +
  5. 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.
  6. + +
  7. 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.
  8. + +
  9. 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.
  10. + +
  11. Write a public void execute method, with no arguments, that + throws a BuildException. This method implements the task + itself.
  12. +
+ +
+

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

+ +

The Life-cycle of a Task

+
    +
  1. + 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. +
  2. +
  3. + When the target is executed, each UnknownElement is invoked + using an perform() method. This instantiates + the task. This means that tasks only gets + instantiated at run time. +
  4. + +
  5. The task gets references to its project and location inside the + buildfile via its inherited project and + location variables.
  6. + +
  7. If the user specified an id attribute to this task, + the project + registers a reference to this newly created task, at run + time.
  8. + +
  9. The task gets a reference to the target it belongs to via its + inherited target variable.
  10. + +
  11. init() is called at run time.
  12. + +
  13. All child elements of the XML element corresponding to this task + are created via this task's createXXX() methods or + instantiated and added to this task via its addXXX() + methods, at run time. Child elements corresponding + to addConfiguredXXX() are created at this point but + the actual addCondifgired method is not called.
  14. + +
  15. All attributes of this task get set via their corresponding + setXXX methods, at runtime.
  16. + +
  17. The content character data sections inside the XML element + corresponding to this task is added to the task via its + addText method, at runtime.
  18. + +
  19. All attributes of all child elements get set via their corresponding + setXXX methods, at runtime.
  20. + +
  21. If child elements of the XML element corresponding to this task + have been created for addConfiguredXXX() methods, + those methods get invoked now.
  22. + +
  23. execute() is called at runtime. + If target1 and target2 both depend + on target3, then running + 'ant target1 target2' will run all tasks in + target3 twice.
  24. +
+ +

Conversions Ant will perform for attributes

+ +

Ant will always expand properties before it passes the value of an +attribute to the corresponding setter method. Since Ant 1.8, it is +possible to extend Ant's property handling +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. +

+ +

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 or a public one-arg constructor + taking a Project class as a parameter. +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 +addConfiguredInner 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.

+ +

Nested Types

+If your task needs to nest an arbitrary type that has been defined + using <typedef> you have two options. +
    +
  1. public void add(Type type)
  2. +
  3. public void addConfigured(Type type)
  4. +
+ The difference between 1 and 2 is the same as between 2 and 3 in the + previous section. +

+ For example suppose one wanted to handle objects object of type + org.apache.tools.ant.taskdefs.condition.Condition, one may + have a class: +

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

+ One may define and use this class like this: +

+
+
+<taskdef name="mytask" classname="MyTask" classpath="classes"/>
+<typedef name="condition.equals"
+         classname="org.apache.tools.ant.taskdefs.conditions.Equals"/>
+<mytask>
+    <condition.equals arg1="${debug}" arg2="true"/>
+</mytask>
+    
+
+

+ A more complicated example follows: +

+
+
+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) {}
+    }
+}
+    
+
+

+ This class defines a number of static classes that implement/extend + Path, MyFileSelector and MyInterface. These may be defined and used + as follows: +

+
+    
+<typedef name="myfileselector" classname="Sample$MyFileSelector" + classpath="classes" loaderref="classes"/> +<typedef name="buildpath" classname="Sample$BuildPath" + classpath="classes" loaderref="classes"/> +<typedef name="xinterface" classname="Sample$XInterface" + classpath="classes" loaderref="classes"/> + +<copy todir="copy-classes"> + <fileset dir="classes"> + <myfileselector attra="10" attrB="-10"> + <buildpath path="." url="abc"> + <xinterface count="4"/> + </buildpath> + </myfileselector> + </fileset> +</copy> +
+
+ +

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. +The task has one attribute, called message.

+
+
+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;
+    }
+}
+
+
+

It's really this simple ;-)

+

Adding your task to the system is rather simple too:

+
    +
  1. Make sure the class that implements your task is in the classpath when + starting Ant.
  2. +
  3. Add a <taskdef> element to your project. + This actually adds your task to the system.
  4. +
  5. Use your task in the rest of the buildfile.
  6. +
+ +

Example

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

Example 2

+To use a task directly from the buildfile which created it, place the +<taskdef> declaration inside a target +after the compilation. Use the classpath attribute of +<taskdef> to point to where the code has just been +compiled. +
+
+<?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>
+
+
+ +

Another way to add a task (more permanently), is to add the task name and +implementing class name to the default.properties file in the +org.apache.tools.ant.taskdefs +package. Then you can use it as if it were a built-in task.

+ +
+

Build Events

+

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

+

To use build events you need to create an ant Project object. You can then call the +addBuildListener method to add your listener to the project. Your listener must implement +the org.apache.tools.antBuildListener interface. The listener will receive BuildEvents +for the following events

+ + +

If the build file invokes another build file via +<ant> or +<subant> or uses +<antcall>, 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

+ +

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

+ +

If you wish to attach a listener from the command line you may use the +-listener option. For example:

+
+
ant -listener org.apache.tools.ant.XmlLogger
+
+

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.

+ +

Note: 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.

+ +

Note2: 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 <parallel> task.

+ +
+

Source code integration

+ +

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.

+ +

Please consult the +Getting Involved 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.

+ +

Ant also has some +task guidelines +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.

+ + + + -- cgit 1.2.3-korg