source: other-projects/trunk/realistic-books/packages/AntInstaller/web/manual/manual/CoreTypes/selectors-program.html@ 19253

Last change on this file since 19253 was 19253, checked in by davidb, 15 years ago

Establishing a source code repository for Veronica's Realistic Book's software

File size: 12.0 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">
20 <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
21<title>Programming Selectors in Ant</title>
22 </head>
23
24 <body>
25 <h2>Programming your own Selectors</h2>
26
27 <h3>Selector Programming API</h3>
28
29 <p>Want to define your own selectors? It's easy!</p>
30
31 <p>First, pick the type of selector that you want to define. There
32 are three types, and a recipe for each one follows. Chances are
33 you'll want to work with the first one, Custom Selectors.</p>
34
35 <ol>
36 <li>Custom Selectors
37
38 <p>This is the category that Ant provides specifically for you to
39 define your own Selectors. Anywhere you want to use your selector
40 you use the <code>&lt;custom&gt;</code> element and specify
41 the class name of your selector within it. See the
42 <a href="selectors.html#customselect">Custom Selectors</a>
43 section of the Selector page for details. The
44 <code>&lt;custom&gt;</code> element can be used anywhere
45 the core selectors can be used. It can be contained within
46 <a href="selectors.html#selectcontainers">Selector Containers</a>,
47 for example.</p>
48
49 <p>To create a new Custom Selector, you have to create a class that
50 implements
51 <code>org.apache.tools.ant.types.selectors.ExtendFileSelector</code>.
52 The easiest way to do that is through the convenience base class
53 <code>org.apache.tools.ant.types.selectors.BaseExtendSelector</code>,
54 which provides all of the methods for supporting
55 <code>&lt;param&gt;</code> tags. First, override the
56 <code>isSelected()</code> method, and optionally the
57 <code>verifySettings()</code> method. If your custom
58 selector requires parameters to be set, you can also override
59 the <code>setParameters()</code> method and interpret the
60 parameters that are passed in any way you like. Several of the
61 core selectors demonstrate how to do that because they can
62 also be used as custom selectors.</p>
63
64 <li>Core Selectors
65
66 <p>These are the selectors used by Ant itself. To implement one of
67 these, you will have to alter some of the classes contained within
68 Ant.</p>
69
70 <ul>
71 <li><p>First, create a class that implements
72 <code>org.apache.tools.ant.types.selectors.FileSelector</code>.
73 You can either choose to implement all methods yourself from
74 scratch, or you can extend
75 <code>org.apache.tools.ant.types.selectors.BaseSelector</code>
76 instead, a convenience class that provides reasonable default
77 behaviour for many methods.</p>
78
79 <p>There is only one method required.
80 <code>public boolean isSelected(File basedir, String filename,
81 File file)</code>
82 is the real purpose of the whole exercise. It returns true
83 or false depending on whether the given file should be
84 selected from the list or not.</p>
85
86 <p>If you are using
87 <code>org.apache.tools.ant.types.selectors.BaseSelector</code>
88 there are also some predefined behaviours you can take advantage
89 of. Any time you encounter a problem when setting attributes or
90 adding tags, you can call setError(String errmsg) and the class
91 will know that there is a problem. Then, at the top of your
92 <code>isSelected()</code> method call <code>validate()</code> and
93 a BuildException will be thrown with the contents of your error
94 message. The <code>validate()</code> method also gives you a
95 last chance to check your settings for consistency because it
96 calls <code>verifySettings()</code>. Override this method and
97 call <code>setError()</code> within it if you detect any
98 problems in how your selector is set up.</p>
99
100 <p>You may also want to override <code>toString()</code>.</p>
101
102 <li><p>Put an <code>add</code> method for your selector in
103 <code>org.apache.tools.ant.types.selectors.SelectorContainer</code>.
104 This is an interface, so you will also have to add an implementation
105 for the method in the classes which implement it, namely
106 <code>org.apache.tools.ant.types.AbstractFileSet</code>,
107 <code>org.apache.tools.ant.taskdefs.MatchingTask</code> and
108 <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
109 Once it is in there, it will be available everywhere that core
110 selectors are appropriate.</p>
111 </ul>
112
113 <li>Selector Containers
114 <p>Got an idea for a new Selector Container? Creating a new one is
115 no problem:</p>
116 <ul>
117 <li><p>Create a new class that implements
118 <code>org.apache.tools.ant.types.selectors.SelectorContainer</code>.
119 This will ensure that your new
120 Container can access any new selectors that come along. Again, there
121 is a convenience class available for you called
122 <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
123 </p>
124 <li><p>Implement the
125 <code>public boolean isSelected(String filename, File file)</code>
126 method to do the right thing. Chances are you'll want to iterate
127 over the selectors under you, so use
128 <code>selectorElements()</code> to get an iterator that will do
129 that.</p>
130 <li><p>Again, put an <code>add</code> method for your container in
131 <code>org.apache.tools.ant.types.selectors.SelectorContainer</code>
132 and its implementations
133 <code>org.apache.tools.ant.types.AbstractFileSet</code> and
134 <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
135 </p>
136 </ul>
137 </ol>
138
139 <h3>Testing Selectors</h3>
140
141 <p>For a robust component (and selectors are (Project)Components) tests are
142 necessary. For testing Tasks we use JUnit TestCases - more specific
143 <tt>org.apache.tools.ant.BuildFileTest extends junit.framework.TestCase</tt>.
144 Some of its features like configure the (test) project by reading its buildfile and
145 execute targets we need for selector tests also. Therefore we use that BuildFileTest.
146 But testing selectors requires some more work: having a set of files, instantiate
147 and configure the selector, check the selection work and more. Because we usually
148 extend <tt>BaseExtendSelector</tt> its features have to be tested also (e.g. setError()).
149 </p>
150
151 <p>That's why we have a base class for doing our selector tests:
152 <tt>org.apache.tools.ant.types.selectors.BaseSelectorTest</tt>.</p>
153
154 <p>This class extends TestCase and therefore can included in the set of Ant's
155 unit tests. It holds an instance of preconfigured BuildFileTest. Configuration
156 is done by parsing the src/etc/testcases/types/selectors.xml. BaseSelectorTest
157 then gives us helper methods for handling multiple selections. </p>
158
159 <p>Because the term "testcase" or "testenvironment" are so often used, this
160 special testenvironment got a new name: <i>bed</i>. Like you initialize the
161 test environment by calling setUp() and cleaning by calling tearDown() (<i>or like
162 to make your bed before go sleeping</i>) you have to do that work with your
163 <i>bed</i> by calling <tt>makeBed()</tt> respecitive <tt>cleanupBed()</tt>.</p>
164
165 <p>A usual test scenario is<ol>
166 <li>make the bed</li>
167 <li>instantiate the selector</li>
168 <li>configure the selector</li>
169 <li>let the selector do some work</li>
170 <li>verify the work</li>
171 <li>clean the bed</li>
172 </ol>
173 </p>
174
175 <p>For common way of instantiation you have to override the <tt>getInstance()</tt>
176 simply by returning a new object of your selector. For easier "selection and verification work"
177 BaseSelectorTest provides the method <tt>performTests()</tt> which
178 iterates over all files (and directories) in the String array <tt>filenames</tt>
179 and checks whether the given selector returns the expected result. If an error
180 occurred (especially the selector does not return the expected result) the test
181 fails and the failing filenames are logged.</p>
182
183 <p>An example test would be:<pre>
184package org.apache.tools.ant.types.selectors;
185
186public class MySelectorTest extends BaseSelectorTest {
187
188 public MySelectorTest(String name) {
189 super(name);
190 }
191
192 public BaseSelector getInstance() {
193 return new MySelector();
194 }
195
196 public void testCase1() {
197 try {
198 // initialize test environment 'bed'
199 makeBed();
200
201 // Configure the selector
202 MySelector s = (MySelector)getSelector();
203 s.addParam("key1", "value1");
204 s.addParam("key2", "value2");
205 s.setXX(true);
206 s.setYY("a value");
207
208 // do the tests
209 performTests(s, "FTTTTTTTTTTT"); // First is not selected - rest is
210
211 } finally {
212 // cleanup the environment
213 cleanupBed();
214 }
215 }
216}
217 </pre>
218 As an example of an error JUnit could log<pre>
219 [junit] FAILED
220 [junit] Error for files: <font color=blue>.;copy.filterset.filtered;tar/gz/asf-logo.gif.tar.gz</font>
221 [junit] expected:&lt;<font color=blue>FTTTFTTTF...</font>&gt; but was:&lt;TTTTTTTTT...&gt;
222 [junit] junit.framework.ComparisonFailure: Error for files: .;copy.filterset.filtered;tar/gz/asf-logo.gif.tar.gz
223 [junit] expected:&lt;FTTTFTTTF...&gt; but was:&lt;TTTTTTTTT...&gt;
224 [junit] at junit.framework.Assert.assertEquals(Assert.java:81)
225 [junit] at org.apache.tools.ant.types.selectors.BaseSelectorTest.performTest(BaseSelectorTest.java:194)
226 </pre></p>
227
228 <p>Described above the test class should provide a <tt>getInstance()</tt>
229 method. But that isn't used here. The used <tt>getSelector()</tt> method is
230 implemented in the base class and gives an instance of an Ant Project to
231 the selector. This is usually done inside normal build file runs, but not
232 inside this special environment, so this method gives the selector the
233 ability to use its own Project object (<tt>getProject()</tt>), for example
234 for logging.</p>
235
236
237 <h3>Logging</h3>
238
239 <p>During development and maybe later you sometimes need the output of information.
240 Therefore Logging is needed. Because the selector extends BaseExtendSelector or directly
241 BaseSelector it is an Ant <tt>DataType</tt> and therefore a <tt>ProjectComponent</tt>. <br>
242 That means that you have access to the project object and its logging capability.
243 <tt>ProjectComponent</tt> itself provides <i>log</i> methods which will do the
244 access to the project instance. Logging is therefore done simply with:
245 <pre>
246 log( "message" );
247 </pre>
248 or
249 <pre>
250 log( "message" , loglevel );
251 </pre>
252 where the <tt>loglevel</tt> is one of the values <ul>
253 <li> org.apache.tools.ant.Project.MSG_ERR </li>
254 <li> org.apache.tools.ant.Project.MSG_WARN </li>
255 <li> org.apache.tools.ant.Project.MSG_INFO (= default) </li>
256 <li> org.apache.tools.ant.Project.MSG_VERBOSE </li>
257 <li> org.apache.tools.ant.Project.MSG_DEBUG </li>
258 </ul>
259 </p>
260
261
262 </body>
263
264</html>
Note: See TracBrowser for help on using the repository browser.