diff --git a/docs/manual/CoreTypes/custom-programming.html b/docs/manual/CoreTypes/custom-programming.html new file mode 100644 index 000000000..f75d4b065 --- /dev/null +++ b/docs/manual/CoreTypes/custom-programming.html @@ -0,0 +1,391 @@ + + + + Custom Components + + + +

Custom Components

+

Overview

+

+ Custom components are conditions, selectors, filters and other + objects that are defined outside ant core. +

+

+ In Ant 1.6 custom conditions, selectors and filters has + been overhauled. +

+

+ It is now possible to define custom conditions, selectors and filters + that behave like Ant Core components. + This is achieved by allowing datatypes defined in build scripts + to be used as custom components if the class of the datatype + is compatible, or has been adapted by an adapter class. +

+

+ The old methods of defining custom components are still supported. +

+

Definition and use

+

+ A custom component is a normal Java class that implements a particular + interface or extends a particular class, or has been adapted to the + interface or class. +

+

+ It is exactly like writing a + custom task. + One defines attributes and nested elements by writing setter + methods and add methods. +

+

+ After the class has been written, it is added to the ant system + by using <typedef>. +

+

Custom Conditions

+

+ Custom conditions are datatypes that implement + org.apache.tools.ant.taskdefs.condition.Condition. + For example a custom condition that returns true if a + string is all upper case could be written as: +

+
+
+package com.mydomain;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+
+public class AllUpperCaseCondition extends Condition {
+    private String value;
+
+    // The setter for the "value" attribute
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    // This method evaluates the condition
+    public boolean eval() {
+        if (value == null) {
+            throw new BuildException("value attribute is not set");
+        }
+        return value.toUpperCase().equals(value);
+   }        
+}
+      
+
+ +

+ Adding the condition to the system is achieved as follows: +

+
+
+<typedef
+    name="alluppercase"
+    classname="com.mydomain.AllUpperCaseCondition"
+    classpath="${mydomain.classes"/>
+      
+
+

+ This condition can now be used wherever a Core Ant condition + is used. +

+
+
+<condition property="allupper">
+   <alluppercase value="THIS IS ALL UPPER CASE"/>
+</condition>
+      
+
+

Custom Selectors

+

+ Custom selectors are datatypes that implement + org.apache.tools.ant.types.selectors.FileSelector. +

There is only one method required. + public boolean isSelected(File basedir, String filename, + File file). + It returns true + or false depending on whether the given file should be + selected or not. +

+

+ An example of a custom selection that selects filenames ending + in ".java" would be: +

+
+
+package com.mydomain;
+import org.apache.tools.ant.types.selectors.FileSelector;
+public class JavaSelector {
+    public boolean isSelected(File b, String filename, File f) {
+       return filename.toLowerCase().endsWith(".java");
+    }
+}
+      
+
+

+

+

+ Adding the selector to the system is achieved as follows: +

+
+
+<typedef
+    name="javaselector"
+    classname="com.mydomain.JavaSelector"
+    classpath="${mydomain.classes"/>
+      
+
+

+ This selector can now be used wherever a Core Ant selector + is used. +

+

+ One may use + org.apache.tools.ant.types.selectors.BaseSelector, + a convenience class that provides reasonable default + behaviour. + It has some predefined behaviours you can take advantage + of. Any time you encounter a problem when setting attributes or + adding tags, you can call setError(String errmsg) and the class + will know that there is a problem. Then, at the top of your + isSelected() method call validate() and + a BuildException will be thrown with the contents of your error + message. The validate() method also gives you a + last chance to check your settings for consistency because it + calls verifySettings(). Override this method and + call setError() within it if you detect any + problems in how your selector is set up.

+

+

+ To write custom selector containers one should extend + org.apache.tools.ant.types.selectors.BaseSelectorContainer. + Implement the + public boolean isSelected(File baseDir, String filename, File file) + method to do the right thing. Chances are you'll want to iterate + over the selectors under you, so use + selectorElements() to get an iterator that will do + that. +

+

+ For example to create a selector container that will select files + if a certain number of contained selectors select, one could write + a selector as follows: +

+
+
+public class MatchNumberSelectors extends BaseSelectorContainer {
+    private int number = -1;
+    public void setNumber(int number) {
+        this.number = number;
+    }
+    public void verifySettings() {
+        if (number < 0) {
+           throw new BuildException("Number attribute should be set");
+        }
+    }
+    public boolean isSelected(File baseDir, String filename, File file) {
+        validate();
+        int numberSelected = 0;
+        for (Enumeration e = selectorElements(); e.hasNextElement();) {
+            FileSelector s = (FileSelector) e.nextElement();
+            if (s.isSelected(baseDir, filename, file)) {
+                numberSelected++;
+            }
+        }
+        return numberSelected == number;
+    }
+}
+      
+
+

+ To define and use this selector one could do: +

+
+
+<typedef name="numberselected"
+         classname="com.mydomain.MatchNumberSelectors"/>
+...
+<fileset dir="${src.path}">
+   <numberselected number="2">
+      <contains text="script" casesensitive="no"/>
+      <size value="4" units="Ki" when="more"/>
+      <javaselector/>
+   </numberselected>
+</fileset>
+      
+
+

+ The custom selector +

+

+ The custom selector was the pre ant 1.6 way of defining custom selectors. + This method is still supported for backward compatiblity. +

+

You can write your own selectors and use them within the selector + containers by specifying them within the <custom> tag.

+ +

To create a new Custom Selector, you have to create a class that + implements + org.apache.tools.ant.types.selectors.ExtendFileSelector. + The easiest way to do that is through the convenience base class + org.apache.tools.ant.types.selectors.BaseExtendSelector, + which provides all of the methods for supporting + <param> tags. First, override the + isSelected() method, and optionally the + verifySettings() method. If your custom + selector requires parameters to be set, you can also override + the setParameters() method and interpret the + parameters that are passed in any way you like. Several of the + core selectors demonstrate how to do that because they can + also be used as custom selectors.

+ + +

Once that is written, you include it in your build file by using + the <custom> tag. +

+ + + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionRequired
classnameThe name of your class that implements + org.apache.tools.ant.types.selectors.FileSelector. + Yes
classpathThe classpath to use in order to load the + custom selector class. If neither this classpath nor the + classpathref are specified, the class will be + loaded from the classpath that Ant uses. + No
classpathrefA reference to a classpath previously + defined. If neither this reference nor the + classpath above are specified, the class will be + loaded from the classpath that Ant uses. + No
+ +

Here is how you use <custom> to + use your class as a selector: +

+ +
+<fileset dir="${mydir}" includes="**/*">
+    <custom classname="com.mydomain.MySelector">
+        <param name="myattribute" value="myvalue"/>
+    </custom>
+</fileset>
+      
+ + +

The core selectors that can also be used as custom selectors + are

+ + + +

Here is the example from the Depth Selector section rewritten + to use the selector through <custom>.

+ +
+<fileset dir="${doc.path}" includes="**/*">
+    <custom classname="org.apache.tools.ant.types.selectors.DepthSelector">
+        <param name="max" value="1"/>
+    </custom>
+</fileset>
+      
+ +

Selects all files in the base directory and one directory below + that.

+ +

Custom Filter Readers

+

+ Custom filter readers selectors are datatypes that implement + org.apache.tools.ant.types.filters.ChainableReader. +

+

There is only one method required. + Reader chain(Reader reader). + This returns a reader that filters input from the specified + reader. +

+

+ For example a filterreader that removes every second character + could be: +

+
+
+public class RemoveOddCharacters implements ChainableReader {
+   public Reader chain(Reader reader) {
+      return new BaseFilterReader(reader) {
+          int count = 0;
+          public int read() throws IOException {
+              while (true) {
+                int c = in.read();
+                if (c == -1) {
+                    return c;
+                }
+                count++;
+                if ((count % 2) == 1) {
+                    return c;
+                }   
+              }
+          }
+      }
+   }
+}
+      
+
+

+ For line oriented filters it may be easier to extend + ChainableFilterReader an inner class of + org.apache.tools.ant.filters.TokenFilter. +

+

+ For example a filter that appends the line number could be +

+
+
+public class AddLineNumber extends ChainableReaderFilter {
+   private void lineNumber = 0;
+   public String filter(String string) {
+      lineNumber++;
+      return "" + lineNumber + "\t" + string;
+   }
+}
+      
+
+ + +
+

Copyright © 2003 Apache Software Foundation. All rights + Reserved.

+ + + diff --git a/docs/manual/conceptstypeslist.html b/docs/manual/conceptstypeslist.html index 1b95bfce1..dc60cab07 100644 --- a/docs/manual/conceptstypeslist.html +++ b/docs/manual/conceptstypeslist.html @@ -34,5 +34,11 @@ Class Fileset
Extension Package
Set of Extension Packages
+ +

Custom Components

+Custom Components
+Conditions
+Selectors
+FilterReaders