You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

custom-programming.html 14 KiB

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