source: release-kits/lirk3/bin/ant-installer/web/manual1.7.0/manual/CoreTypes/custom-programming.html@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 13.8 KB
Line 
1<!--
2 Licensed to the Apache Software Foundation (ASF) under one or more
3 contributor license agreements. See the NOTICE file distributed with
4 this work for additional information regarding copyright ownership.
5 The ASF licenses this file to You under the Apache License, Version 2.0
6 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16-->
17<html>
18 <head>
19 <meta http-equiv="Content-Language" content="en-us"></meta>
20<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
21<title>Custom Components</title>
22 </head>
23 <body>
24 <h2>Custom Components</h2>
25 <h3>Overview</h3>
26 <p>
27 Custom components are conditions, selectors, filters and other
28 objects that are defined outside ant core.
29 </p>
30 <p>
31 In Ant 1.6 custom conditions, selectors and filters has
32 been overhauled.
33 </p>
34 <p>
35 It is now possible to define custom conditions, selectors and filters
36 that behave like Ant Core components.
37 This is achieved by allowing datatypes defined in build scripts
38 to be used as custom components if the class of the datatype
39 is compatible, or has been adapted by an adapter class.
40 </p>
41 <p>
42 The old methods of defining custom components are still supported.
43 </p>
44 <h3>Definition and use</h3>
45 <p>
46 A custom component is a normal Java class that implements a particular
47 interface or extends a particular class, or has been adapted to the
48 interface or class.
49 </p>
50 <p>
51 It is exactly like writing a
52 <a href="../develop.html#writingowntask">custom task</a>.
53 One defines attributes and nested elements by writing <i>setter</i>
54 methods and <i>add</i> methods.
55 </p>
56 <p>
57 After the class has been written, it is added to the ant system
58 by using <code>&lt;typedef&gt;</code>.
59 </p>
60 <h3><a name="customconditions">Custom Conditions</a></h3>
61 <p>
62 Custom conditions are datatypes that implement
63 <code>org.apache.tools.ant.taskdefs.condition.Condition</code>.
64 For example a custom condition that returns true if a
65 string is all upper case could be written as:
66 </p>
67 <blockquote>
68 <pre>
69package com.mydomain;
70
71import org.apache.tools.ant.BuildException;
72import org.apache.tools.ant.taskdefs.condition.Condition;
73
74public class AllUpperCaseCondition implements Condition {
75 private String value;
76
77 // The setter for the "value" attribute
78 public void setValue(String value) {
79 this.value = value;
80 }
81
82 // This method evaluates the condition
83 public boolean eval() {
84 if (value == null) {
85 throw new BuildException("value attribute is not set");
86 }
87 return value.toUpperCase().equals(value);
88 }
89}
90 </pre>
91 </blockquote>
92
93 <p>
94 Adding the condition to the system is achieved as follows:
95 </p>
96 <blockquote>
97 <pre>
98&lt;typedef
99 name="alluppercase"
100 classname="com.mydomain.AllUpperCaseCondition"
101 classpath="${mydomain.classes}"/&gt;
102 </pre>
103 </blockquote>
104 <p>
105 This condition can now be used wherever a Core Ant condition
106 is used.
107 </p>
108 <blockquote>
109 <pre>
110&lt;condition property="allupper"&gt;
111 &lt;alluppercase value="THIS IS ALL UPPER CASE"/&gt;
112&lt;/condition&gt;
113 </pre>
114 </blockquote>
115 <h3><a name="customselectors">Custom Selectors</a></h3>
116 <p>
117 Custom selectors are datatypes that implement
118 <code>org.apache.tools.ant.types.selectors.FileSelector</code>.
119 </p>
120 <p>There is only one method required.
121 <code>public boolean isSelected(File basedir, String filename,
122 File file)</code>.
123 It returns true
124 or false depending on whether the given file should be
125 selected or not.
126 </p>
127 <p>
128 An example of a custom selection that selects filenames ending
129 in ".java" would be:
130 </p>
131 <blockquote>
132 <pre>
133package com.mydomain;
134import java.io.File;
135import org.apache.tools.ant.types.selectors.FileSelector;
136public class JavaSelector implements FileSelector {
137 public boolean isSelected(File b, String filename, File f) {
138 return filename.toLowerCase().endsWith(".java");
139 }
140}
141 </pre>
142 </blockquote>
143 <p>
144 Adding the selector to the system is achieved as follows:
145 </p>
146 <blockquote>
147 <pre>
148&lt;typedef
149 name="javaselector"
150 classname="com.mydomain.JavaSelector"
151 classpath="${mydomain.classes}"/&gt;
152 </pre>
153 </blockquote>
154 <p>
155 This selector can now be used wherever a Core Ant selector
156 is used, for example:
157 </p>
158 <blockquote>
159 <pre>
160&lt;copy todir="to"&gt;
161 &lt;fileset dir="src"&gt;
162 &lt;javaselector/&gt;
163 &lt;/fileset&gt;
164&lt;/copy&gt;
165 </pre>
166 </blockquote>
167
168 <p>
169 One may use
170 <code>org.apache.tools.ant.types.selectors.BaseSelector</code>,
171 a convenience class that provides reasonable default
172 behaviour.
173 It has some predefined behaviours you can take advantage
174 of. Any time you encounter a problem when setting attributes or
175 adding tags, you can call setError(String errmsg) and the class
176 will know that there is a problem. Then, at the top of your
177 <code>isSelected()</code> method call <code>validate()</code> and
178 a BuildException will be thrown with the contents of your error
179 message. The <code>validate()</code> method also gives you a
180 last chance to check your settings for consistency because it
181 calls <code>verifySettings()</code>. Override this method and
182 call <code>setError()</code> within it if you detect any
183 problems in how your selector is set up.
184 </p>
185 <p>
186 To write custom selector containers one should extend
187 <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
188 Implement the
189 <code>public boolean isSelected(File baseDir, String filename, File file)</code>
190 method to do the right thing. Chances are you'll want to iterate
191 over the selectors under you, so use
192 <code>selectorElements()</code> to get an iterator that will do
193 that.
194 </p>
195 <p>
196 For example to create a selector container that will select files
197 if a certain number of contained selectors select, one could write
198 a selector as follows:
199 </p>
200 <blockquote>
201 <pre>
202public class MatchNumberSelectors extends BaseSelectorContainer {
203 private int number = -1;
204 public void setNumber(int number) {
205 this.number = number;
206 }
207 public void verifySettings() {
208 if (number &lt; 0) {
209 throw new BuildException("Number attribute should be set");
210 }
211 }
212 public boolean isSelected(File baseDir, String filename, File file) {
213 validate();
214 int numberSelected = 0;
215 for (Enumeration e = selectorElements(); e.hasNextElement();) {
216 FileSelector s = (FileSelector) e.nextElement();
217 if (s.isSelected(baseDir, filename, file)) {
218 numberSelected++;
219 }
220 }
221 return numberSelected == number;
222 }
223}
224 </pre>
225 </blockquote>
226 <p>
227 To define and use this selector one could do:
228 </p>
229 <blockquote>
230 <pre>
231&lt;typedef name="numberselected"
232 classname="com.mydomain.MatchNumberSelectors"/&gt;
233...
234&lt;fileset dir="${src.path}"&gt;
235 &lt;numberselected number="2"&gt;
236 &lt;contains text="script" casesensitive="no"/&gt;
237 &lt;size value="4" units="Ki" when="more"/&gt;
238 &lt;javaselector/&gt;
239 &lt;/numberselected&gt;
240&lt;/fileset&gt;
241 </pre>
242 </blockquote>
243 <p>
244 <i>The custom selector</i>
245 </p>
246 <p>
247 The custom selector was the pre ant 1.6 way of defining custom selectors.
248 This method is still supported for backward compatibility.
249 </p>
250 <p>You can write your own selectors and use them within the selector
251 containers by specifying them within the <code>&lt;custom&gt;</code> tag.</p>
252
253 <p>To create a new Custom Selector, you have to create a class that
254 implements
255 <code>org.apache.tools.ant.types.selectors.ExtendFileSelector</code>.
256 The easiest way to do that is through the convenience base class
257 <code>org.apache.tools.ant.types.selectors.BaseExtendSelector</code>,
258 which provides all of the methods for supporting
259 <code>&lt;param&gt;</code> tags. First, override the
260 <code>isSelected()</code> method, and optionally the
261 <code>verifySettings()</code> method. If your custom
262 selector requires parameters to be set, you can also override
263 the <code>setParameters()</code> method and interpret the
264 parameters that are passed in any way you like. Several of the
265 core selectors demonstrate how to do that because they can
266 also be used as custom selectors.</p>
267
268
269 <p>Once that is written, you include it in your build file by using
270 the <code>&lt;custom&gt;</code> tag.
271 </p>
272
273 <table border="1" cellpadding="2" cellspacing="0">
274 <tr>
275 <td valign="top"><b>Attribute</b></td>
276 <td valign="top"><b>Description</b></td>
277 <td align="center" valign="top"><b>Required</b></td>
278 </tr>
279 <tr>
280 <td valign="top">classname</td>
281 <td valign="top">The name of your class that implements
282 <code>org.apache.tools.ant.types.selectors.FileSelector</code>.
283 </td>
284 <td valign="top" align="center">Yes</td>
285 </tr>
286 <tr>
287 <td valign="top">classpath</td>
288 <td valign="top">The classpath to use in order to load the
289 custom selector class. If neither this classpath nor the
290 classpathref are specified, the class will be
291 loaded from the classpath that Ant uses.
292 </td>
293 <td valign="top" align="center">No</td>
294 </tr>
295 <tr>
296 <td valign="top">classpathref</td>
297 <td valign="top">A reference to a classpath previously
298 defined. If neither this reference nor the
299 classpath above are specified, the class will be
300 loaded from the classpath that Ant uses.
301 </td>
302 <td valign="top" align="center">No</td>
303 </tr>
304 </table>
305
306 <p>Here is how you use <code>&lt;custom&gt;</code> to
307 use your class as a selector:
308 </p>
309
310 <blockquote><pre>
311&lt;fileset dir="${mydir}" includes="**/*"&gt;
312 &lt;custom classname="com.mydomain.MySelector"&gt;
313 &lt;param name="myattribute" value="myvalue"/&gt;
314 &lt;/custom&gt;
315&lt;/fileset&gt;
316 </pre></blockquote>
317
318
319 <p>The core selectors that can also be used as custom selectors
320 are</p>
321
322 <ul>
323 <li><a href="selectors.html#containsselect">Contains Selector</a> with
324 classname <code>org.apache.tools.ant.types.selectors.ContainsSelector</code>
325 </li>
326 <li><a href="selectors.html#dateselect">Date Selector</a> with
327 classname <code>org.apache.tools.ant.types.selectors.DateSelector</code>
328 </li>
329 <li><a href="selectors.html#depthselect">Depth Selector</a> with
330 classname <code>org.apache.tools.ant.types.selectors.DepthSelector</code>
331 </li>
332 <li><a href="selectors.html#filenameselect">Filename Selector</a> with
333 classname <code>org.apache.tools.ant.types.selectors.FilenameSelector</code>
334 </li>
335 <li><a href="selectors.html#sizeselect">Size Selector</a> with
336 classname <code>org.apache.tools.ant.types.selectors.SizeSelector</code>
337 </li>
338 </ul>
339
340 <p>Here is the example from the Depth Selector section rewritten
341 to use the selector through <code>&lt;custom&gt;</code>.</p>
342
343 <blockquote><pre>
344&lt;fileset dir="${doc.path}" includes="**/*"&gt;
345 &lt;custom classname="org.apache.tools.ant.types.selectors.DepthSelector"&gt;
346 &lt;param name="max" value="1"/&gt;
347 &lt;/custom&gt;
348&lt;/fileset&gt;
349 </pre></blockquote>
350
351 <p>Selects all files in the base directory and one directory below
352 that.</p>
353
354 <h3><a name="filterreaders">Custom Filter Readers</a></h3>
355 <p>
356 Custom filter readers selectors are datatypes that implement
357 <code>org.apache.tools.ant.types.filters.ChainableReader</code>.
358 </p>
359 <p>There is only one method required.
360 <code>Reader chain(Reader reader)</code>.
361 This returns a reader that filters input from the specified
362 reader.
363 </p>
364 <p>
365 For example a filterreader that removes every second character
366 could be:
367 </p>
368 <blockquote>
369 <pre>
370public class RemoveOddCharacters implements ChainableReader {
371 public Reader chain(Reader reader) {
372 return new BaseFilterReader(reader) {
373 int count = 0;
374 public int read() throws IOException {
375 while (true) {
376 int c = in.read();
377 if (c == -1) {
378 return c;
379 }
380 count++;
381 if ((count % 2) == 1) {
382 return c;
383 }
384 }
385 }
386 }
387 }
388}
389 </pre>
390 </blockquote>
391 <p>
392 For line oriented filters it may be easier to extend
393 <code>ChainableFilterReader</code> an inner class of
394 <code>org.apache.tools.ant.filters.TokenFilter</code>.
395 </p>
396 <p>
397 For example a filter that appends the line number could be
398 </p>
399 <blockquote>
400 <pre>
401public class AddLineNumber extends ChainableReaderFilter {
402 private void lineNumber = 0;
403 public String filter(String string) {
404 lineNumber++;
405 return "" + lineNumber + "\t" + string;
406 }
407}
408 </pre>
409 </blockquote>
410
411
412 <hr></hr>
413 </body>
414</html>
415
Note: See TracBrowser for help on using the repository browser.