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 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. +
++ 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 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 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.
+
| Attribute | +Description | +Required | +
| classname | +The name of your class that implements
+ org.apache.tools.ant.types.selectors.FileSelector.
+ |
+ Yes | +
| classpath | +The 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 | +
| classpathref | +A 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
+ +org.apache.tools.ant.types.selectors.ContainsSelector
+ org.apache.tools.ant.types.selectors.DateSelector
+ org.apache.tools.ant.types.selectors.DepthSelector
+ org.apache.tools.ant.types.selectors.FilenameSelector
+ org.apache.tools.ant.types.selectors.SizeSelector
+ 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 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