1 | /*
|
---|
2 | * Copyright 2003-2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 |
|
---|
18 | package org.apache.tools.ant.types.selectors.modifiedselector;
|
---|
19 |
|
---|
20 |
|
---|
21 | // Java
|
---|
22 | import java.util.Comparator;
|
---|
23 | import java.util.Vector;
|
---|
24 | import java.util.Iterator;
|
---|
25 | import java.io.File;
|
---|
26 |
|
---|
27 | // Ant
|
---|
28 | import org.apache.tools.ant.Project;
|
---|
29 | import org.apache.tools.ant.IntrospectionHelper;
|
---|
30 | import org.apache.tools.ant.types.EnumeratedAttribute;
|
---|
31 | import org.apache.tools.ant.types.Parameter;
|
---|
32 | import org.apache.tools.ant.types.selectors.BaseExtendSelector;
|
---|
33 |
|
---|
34 |
|
---|
35 | /**
|
---|
36 | * <p>Selector class that uses <i>Algorithm</i>, <i>Cache</i> and <i>Comparator</i>
|
---|
37 | * for its work.
|
---|
38 | * The <i>Algorithm</i> is used for computing a hashvalue for a file.
|
---|
39 | * The <i>Comparator</i> decides whether to select or not.
|
---|
40 | * The <i>Cache</i> stores the other value for comparison by the <i>Comparator</i>
|
---|
41 | * in a persistent manner.</p>
|
---|
42 | *
|
---|
43 | * <p>The ModifiedSelector is implemented as a <b>CoreSelector</b> and uses default
|
---|
44 | * values for all its attributes therefore the simpliest example is <pre>
|
---|
45 | * <copy todir="dest">
|
---|
46 | * <filelist dir="src">
|
---|
47 | * <modified/>
|
---|
48 | * </filelist>
|
---|
49 | * </copy>
|
---|
50 | * </pre></p>
|
---|
51 | *
|
---|
52 | * <p>The same example rewritten as CoreSelector with setting the all values
|
---|
53 | * (same as defaults are) would be <pre>
|
---|
54 | * <copy todir="dest">
|
---|
55 | * <filelist dir="src">
|
---|
56 | * <modified update="true"
|
---|
57 | * cache="propertyfile"
|
---|
58 | * algorithm="digest"
|
---|
59 | * comparator="equal">
|
---|
60 | * <param name="cache.cachefile" value="cache.properties"/>
|
---|
61 | * <param name="algorithm.algorithm" value="MD5"/>
|
---|
62 | * </modified>
|
---|
63 | * </filelist>
|
---|
64 | * </copy>
|
---|
65 | * </pre></p>
|
---|
66 | *
|
---|
67 | * <p>And the same rewritten as CustomSelector would be<pre>
|
---|
68 | * <copy todir="dest">
|
---|
69 | * <filelist dir="src">
|
---|
70 | * <custom class="org.apache.tools.ant.type.selectors.ModifiedSelector">
|
---|
71 | * <param name="update" value="true"/>
|
---|
72 | * <param name="cache" value="propertyfile"/>
|
---|
73 | * <param name="algorithm" value="digest"/>
|
---|
74 | * <param name="comparator" value="equal"/>
|
---|
75 | * <param name="cache.cachefile" value="cache.properties"/>
|
---|
76 | * <param name="algorithm.algorithm" value="MD5"/>
|
---|
77 | * </custom>
|
---|
78 | * </filelist>
|
---|
79 | * </copy>
|
---|
80 | * </pre></p>
|
---|
81 | *
|
---|
82 | * <p>All these three examples copy the files from <i>src</i> to <i>dest</i>
|
---|
83 | * using the ModifiedSelector. The ModifiedSelector uses the <i>PropertyfileCache
|
---|
84 | * </i>, the <i>DigestAlgorithm</i> and the <i>EqualComparator</i> for its
|
---|
85 | * work. The PropertyfileCache stores key-value-pairs in a simple java
|
---|
86 | * properties file. The filename is <i>cache.properties</i>. The <i>update</i>
|
---|
87 | * flag lets the selector update the values in the cache (and on first call
|
---|
88 | * creates the cache). The <i>DigestAlgorithm</i> computes a hashvalue using the
|
---|
89 | * java.security.MessageDigest class with its MD5-Algorithm and its standard
|
---|
90 | * provider. The new computed hashvalue and the stored one are compared by
|
---|
91 | * the <i>EqualComparator</i> which returns 'true' (more correct a value not
|
---|
92 | * equals zero (1)) if the values are not the same using simple String
|
---|
93 | * comparison.</p>
|
---|
94 | *
|
---|
95 | * <p>A useful scenario for this selector is inside a build environment
|
---|
96 | * for homepage generation (e.g. with <a href="http://xml.apache.org/forrest/">
|
---|
97 | * Apache Forrest</a>). <pre>
|
---|
98 | * <target name="generate-and-upload-site">
|
---|
99 | * <echo> generate the site using forrest </echo>
|
---|
100 | * <antcall target="site"/>
|
---|
101 | *
|
---|
102 | * <echo> upload the changed files </echo>
|
---|
103 | * <ftp server="${ftp.server}" userid="${ftp.user}" password="${ftp.pwd}">
|
---|
104 | * <fileset dir="htdocs/manual">
|
---|
105 | * <modified/>
|
---|
106 | * </fileset>
|
---|
107 | * </ftp>
|
---|
108 | * </target>
|
---|
109 | * </pre> Here all <b>changed</b> files are uploaded to the server. The
|
---|
110 | * ModifiedSelector saves therefore much upload time.</p>
|
---|
111 | *
|
---|
112 | * <p>This selector supports the following nested param's:
|
---|
113 | * <table>
|
---|
114 | * <tr><th>name</th><th>values</th><th>description</th><th>required</th></tr>
|
---|
115 | * <tr>
|
---|
116 | * <td> cache </td>
|
---|
117 | * <td> propertyfile </td>
|
---|
118 | * <td> which cache implementation should be used <ul>
|
---|
119 | * <li><b>propertyfile</b> - using java.util.Properties </li>
|
---|
120 | * </td>
|
---|
121 | * <td> no, defaults to 'propertyfile' </td>
|
---|
122 | * </tr>
|
---|
123 | * <tr>
|
---|
124 | * <td> algorithm </td>
|
---|
125 | * <td> hashvalue | digest </td>
|
---|
126 | * <td> which algorithm implementation should be used
|
---|
127 | * <li><b>hashvalue</b> - loads the file content into a String and
|
---|
128 | * uses its hashValue() method </li>
|
---|
129 | * <li><b>digest</b> - uses java.security.MessageDigest class </i>
|
---|
130 | * </td>
|
---|
131 | * <td> no, defaults to digest </td>
|
---|
132 | * </tr>
|
---|
133 | * <tr>
|
---|
134 | * <td> comparator </td>
|
---|
135 | * <td> equal | role </td>
|
---|
136 | * <td> which comparator implementation should be used
|
---|
137 | * <li><b>equal</b> - simple comparison using String.equals() </li>
|
---|
138 | * <li><b>role</b> - uses java.text.RuleBasedCollator class </i>
|
---|
139 | * </td>
|
---|
140 | * <td> no, defaults to equal </td>
|
---|
141 | * </tr>
|
---|
142 | * <tr>
|
---|
143 | * <td> update </td>
|
---|
144 | * <td> true | false </td>
|
---|
145 | * <td> If set to <i>true</i>, the cache will be stored, otherwise the values
|
---|
146 | * will be lost. </td>
|
---|
147 | * <td> no, defaults to true </td>
|
---|
148 | * </tr>
|
---|
149 | * <tr>
|
---|
150 | * <td> seldirs </td>
|
---|
151 | * <td> true | false </td>
|
---|
152 | * <td> If set to <i>true</i>, directories will be selected otherwise not </td>
|
---|
153 | * <td> no, defaults to true </td>
|
---|
154 | * </tr>
|
---|
155 | * <tr>
|
---|
156 | * <td> cache.* </td>
|
---|
157 | * <td> depends on used cache </td>
|
---|
158 | * <td> value is stored and given to the Cache-Object for initialisation </td>
|
---|
159 | * <td> depends on used cache </td>
|
---|
160 | * </tr>
|
---|
161 | * <tr>
|
---|
162 | * <td> algorithm.* </td>
|
---|
163 | * <td> depends on used algorithm </td>
|
---|
164 | * <td> value is stored and given to the Algorithm-Object for initialisation </td>
|
---|
165 | * <td> depends on used algorithm </td>
|
---|
166 | * </tr>
|
---|
167 | * <tr>
|
---|
168 | * <td> comparator.* </td>
|
---|
169 | * <td> depends on used comparator </td>
|
---|
170 | * <td> value is stored and given to the Comparator-Object for initialisation </td>
|
---|
171 | * <td> depends on used comparator </td>
|
---|
172 | * </tr>
|
---|
173 | * </table>
|
---|
174 | * If another name is used a BuildException "Invalid parameter" is thrown. </p>
|
---|
175 | *
|
---|
176 | * <p>This selector uses reflection for setting the values of its three interfaces
|
---|
177 | * (using org.apache.tools.ant.IntrospectionHelper) therefore no special
|
---|
178 | * 'configuration interfaces' has to be implemented by new caches, algorithms or
|
---|
179 | * comparators. All present <i>set</i>XX methods can be used. E.g. the DigestAlgorithm
|
---|
180 | * can use a specified provider for computing its value. For selecting this
|
---|
181 | * there is a <i>setProvider(String providername)</i> method. So you can use
|
---|
182 | * a nested <i><param name="algorithm.provider" value="MyProvider"/></i>.
|
---|
183 | *
|
---|
184 | *
|
---|
185 | * @version 2003-09-13
|
---|
186 | * @since Ant 1.6
|
---|
187 | */
|
---|
188 | public class ModifiedSelector extends BaseExtendSelector {
|
---|
189 |
|
---|
190 |
|
---|
191 | // ----- member variables - configuration
|
---|
192 |
|
---|
193 |
|
---|
194 | /** The Cache containing the old values. */
|
---|
195 | private Cache cache = null;
|
---|
196 |
|
---|
197 | /** Algorithm for computing new values and updating the cache. */
|
---|
198 | private Algorithm algorithm = null;
|
---|
199 |
|
---|
200 | /** How should the cached value and the new one compared? */
|
---|
201 | private Comparator comparator = null;
|
---|
202 |
|
---|
203 | /** Should the cache be updated? */
|
---|
204 | private boolean update = true;
|
---|
205 |
|
---|
206 | /** Are directories selected? */
|
---|
207 | private boolean selectDirectories = true;
|
---|
208 |
|
---|
209 |
|
---|
210 | // ----- member variables - internal use
|
---|
211 |
|
---|
212 |
|
---|
213 | /** Flag whether this object is configured. Configuration is only done once. */
|
---|
214 | private boolean isConfigured = false;
|
---|
215 |
|
---|
216 | /** Algorithm name for later instantiation. */
|
---|
217 | private AlgorithmName algoName = null;
|
---|
218 |
|
---|
219 | /** Cache name for later instantiation. */
|
---|
220 | private CacheName cacheName = null;
|
---|
221 |
|
---|
222 | /** Comparator name for later instantiation. */
|
---|
223 | private ComparatorName compName = null;
|
---|
224 |
|
---|
225 |
|
---|
226 | /**
|
---|
227 | * Parameter vector with parameters for later initialization.
|
---|
228 | * @see #configure
|
---|
229 | */
|
---|
230 | private Vector configParameter = new Vector();
|
---|
231 |
|
---|
232 | /**
|
---|
233 | * Parameter vector with special parameters for later initialization.
|
---|
234 | * The names have the pattern '*.*', e.g. 'cache.cachefile'.
|
---|
235 | * These parameters are used <b>after</b> the parameters with the pattern '*'.
|
---|
236 | * @see #configure
|
---|
237 | */
|
---|
238 | private Vector specialParameter = new Vector();
|
---|
239 |
|
---|
240 |
|
---|
241 | // ----- constructors -----
|
---|
242 |
|
---|
243 |
|
---|
244 | /** Bean-Constructor. */
|
---|
245 | public ModifiedSelector() {
|
---|
246 | }
|
---|
247 |
|
---|
248 |
|
---|
249 | // ----- configuration -----
|
---|
250 |
|
---|
251 |
|
---|
252 | /** Overrides BaseSelector.verifySettings(). */
|
---|
253 | public void verifySettings() {
|
---|
254 | configure();
|
---|
255 | if (cache == null) {
|
---|
256 | setError("Cache must be set.");
|
---|
257 | } else if (algorithm == null) {
|
---|
258 | setError("Algorithm must be set.");
|
---|
259 | } else if (!cache.isValid()) {
|
---|
260 | setError("Cache must be proper configured.");
|
---|
261 | } else if (!algorithm.isValid()) {
|
---|
262 | setError("Algorithm must be proper configured.");
|
---|
263 | }
|
---|
264 | }
|
---|
265 |
|
---|
266 |
|
---|
267 | /**
|
---|
268 | * Configures this Selector.
|
---|
269 | * Does this work only once per Selector object.
|
---|
270 | * <p>Because some problems while configuring from <custom>Selector
|
---|
271 | * the configuration is done in the following order:<ol>
|
---|
272 | * <li> collect the configuration data </li>
|
---|
273 | * <li> wait for the first isSelected() call </li>
|
---|
274 | * <li> set the default values </li>
|
---|
275 | * <li> set values for name pattern '*': update, cache, algorithm, comparator </li>
|
---|
276 | * <li> set values for name pattern '*.*: cache.cachefile, ... </li>
|
---|
277 | * </ol></p>
|
---|
278 | * <p>This configuration algorithm is needed because you don't know
|
---|
279 | * the order of arriving config-data. E.g. if you first set the
|
---|
280 | * <i>cache.cachefilename</i> and after that the <i>cache</i> itself,
|
---|
281 | * the default value for cachefilename is used, because setting the
|
---|
282 | * cache implies creating a new Cache instance - with its defaults.</p>
|
---|
283 | */
|
---|
284 | public void configure() {
|
---|
285 | //
|
---|
286 | // ----- The "Singleton" -----
|
---|
287 | //
|
---|
288 | if (isConfigured) {
|
---|
289 | return;
|
---|
290 | }
|
---|
291 | isConfigured = true;
|
---|
292 |
|
---|
293 | //
|
---|
294 | // ----- Set default values -----
|
---|
295 | //
|
---|
296 | org.apache.tools.ant.Project project = getProject();
|
---|
297 | String filename = "cache.properties";
|
---|
298 | File cachefile = null;
|
---|
299 | if (project != null) {
|
---|
300 | // normal use inside Ant
|
---|
301 | cachefile = new File(project.getBaseDir(), filename);
|
---|
302 | } else {
|
---|
303 | // no reference to project - e.g. during JUnit tests
|
---|
304 | cachefile = new File(filename);
|
---|
305 | }
|
---|
306 | cache = new PropertiesfileCache(cachefile);
|
---|
307 | algorithm = new DigestAlgorithm();
|
---|
308 | comparator = new EqualComparator();
|
---|
309 | update = true;
|
---|
310 | selectDirectories = true;
|
---|
311 |
|
---|
312 |
|
---|
313 | //
|
---|
314 | // ----- Set the main attributes, pattern '*' -----
|
---|
315 | //
|
---|
316 | for (Iterator itConfig = configParameter.iterator(); itConfig.hasNext();) {
|
---|
317 | Parameter par = (Parameter) itConfig.next();
|
---|
318 | if (par.getName().indexOf(".") > 0) {
|
---|
319 | // this is a *.* parameter for later use
|
---|
320 | specialParameter.add(par);
|
---|
321 | } else {
|
---|
322 | useParameter(par);
|
---|
323 | }
|
---|
324 | }
|
---|
325 | configParameter = new Vector();
|
---|
326 |
|
---|
327 | //
|
---|
328 | // ----- Instantiate the interfaces -----
|
---|
329 | //
|
---|
330 | String className = null;
|
---|
331 | String pkg = "org.apache.tools.ant.types.selectors.cacheselector";
|
---|
332 |
|
---|
333 | // the algorithm
|
---|
334 | if (algorithm == null) {
|
---|
335 | if ("hashvalue".equals(algoName.getValue())) {
|
---|
336 | className = pkg + ".HashvalueAlgorithm";
|
---|
337 | } else if ("digest".equals(algoName.getValue())) {
|
---|
338 | className = pkg + ".DigestAlgorithm";
|
---|
339 | }
|
---|
340 | if (className != null) {
|
---|
341 | try {
|
---|
342 | // load the specified Algorithm, save the reference and configure it
|
---|
343 | algorithm = (Algorithm) Class.forName(className).newInstance();
|
---|
344 | } catch (Exception e) {
|
---|
345 | e.printStackTrace();
|
---|
346 | }
|
---|
347 | }
|
---|
348 | }
|
---|
349 |
|
---|
350 | // the cache
|
---|
351 | if (cache == null) {
|
---|
352 | if ("propertyfile".equals(cacheName.getValue())) {
|
---|
353 | className = pkg + ".PropertiesfileCache";
|
---|
354 | }
|
---|
355 | if (className != null) {
|
---|
356 | try {
|
---|
357 | // load the specified Cache, save the reference and configure it
|
---|
358 | cache = (Cache) Class.forName(className).newInstance();
|
---|
359 | } catch (Exception e) {
|
---|
360 | e.printStackTrace();
|
---|
361 | }
|
---|
362 | }
|
---|
363 | }
|
---|
364 |
|
---|
365 | // the comparator
|
---|
366 | if (comparator == null) {
|
---|
367 | if ("equal".equals(compName.getValue())) {
|
---|
368 | className = pkg + ".EqualComparator";
|
---|
369 | } else if ("role".equals(compName.getValue())) {
|
---|
370 | className = "java.text.RuleBasedCollator";
|
---|
371 | }
|
---|
372 | if (className != null) {
|
---|
373 | try {
|
---|
374 | // load the specified Cache, save the reference and configure it
|
---|
375 | comparator = (Comparator) Class.forName(className).newInstance();
|
---|
376 | } catch (Exception e) {
|
---|
377 | e.printStackTrace();
|
---|
378 | }
|
---|
379 | }
|
---|
380 | }
|
---|
381 |
|
---|
382 | //
|
---|
383 | // ----- Set the special attributes, pattern '*.*' -----
|
---|
384 | //
|
---|
385 | for (Iterator itSpecial = specialParameter.iterator(); itSpecial.hasNext();) {
|
---|
386 | Parameter par = (Parameter) itSpecial.next();
|
---|
387 | useParameter(par);
|
---|
388 | }
|
---|
389 | specialParameter = new Vector();
|
---|
390 | }
|
---|
391 |
|
---|
392 |
|
---|
393 | // ----- the selection work -----
|
---|
394 |
|
---|
395 |
|
---|
396 | /**
|
---|
397 | * Implementation of BaseExtendSelector.isSelected().
|
---|
398 | * @param basedir as described in BaseExtendSelector
|
---|
399 | * @param filename as described in BaseExtendSelector
|
---|
400 | * @param file as described in BaseExtendSelector
|
---|
401 | * @return as described in BaseExtendSelector
|
---|
402 | */
|
---|
403 | public boolean isSelected(File basedir, String filename, File file) {
|
---|
404 | validate();
|
---|
405 | File f = new File(basedir, filename);
|
---|
406 |
|
---|
407 | // You can not compute a value for a directory
|
---|
408 | if (f.isDirectory()) {
|
---|
409 | return selectDirectories;
|
---|
410 | }
|
---|
411 |
|
---|
412 | // Get the values and do the comparison
|
---|
413 | String cachedValue = String.valueOf(cache.get(f.getAbsolutePath()));
|
---|
414 | String newValue = algorithm.getValue(f);
|
---|
415 | boolean rv = (comparator.compare(cachedValue, newValue) != 0);
|
---|
416 |
|
---|
417 | // Maybe update the cache
|
---|
418 | if (update && !cachedValue.equals(newValue)) {
|
---|
419 | cache.put(f.getAbsolutePath(), newValue);
|
---|
420 | cache.save();
|
---|
421 | }
|
---|
422 |
|
---|
423 | return rv;
|
---|
424 | }
|
---|
425 |
|
---|
426 |
|
---|
427 | // ----- attribute and nested element support -----
|
---|
428 |
|
---|
429 |
|
---|
430 | /**
|
---|
431 | * Support for <i>update</i> attribute.
|
---|
432 | * @param update new value
|
---|
433 | */
|
---|
434 | public void setUpdate(boolean update) {
|
---|
435 | this.update = update;
|
---|
436 | }
|
---|
437 |
|
---|
438 |
|
---|
439 | /**
|
---|
440 | * Support for <i>seldirs</i> attribute.
|
---|
441 | * @param seldirs new value
|
---|
442 | */
|
---|
443 | public void setSeldirs(boolean seldirs) {
|
---|
444 | selectDirectories = seldirs;
|
---|
445 | }
|
---|
446 |
|
---|
447 |
|
---|
448 | /**
|
---|
449 | * Support for nested <param> tags.
|
---|
450 | * @param key the key of the parameter
|
---|
451 | * @param value the value of the parameter
|
---|
452 | */
|
---|
453 | public void addParam(String key, Object value) {
|
---|
454 | Parameter par = new Parameter();
|
---|
455 | par.setName(key);
|
---|
456 | par.setValue(String.valueOf(value));
|
---|
457 | configParameter.add(par);
|
---|
458 | }
|
---|
459 |
|
---|
460 |
|
---|
461 | /**
|
---|
462 | * Support for nested <param> tags.
|
---|
463 | * @param parameter the parameter object
|
---|
464 | */
|
---|
465 | public void addParam(Parameter parameter) {
|
---|
466 | configParameter.add(parameter);
|
---|
467 | }
|
---|
468 |
|
---|
469 |
|
---|
470 | /**
|
---|
471 | * Defined in org.apache.tools.ant.types.Parameterizable.
|
---|
472 | * Overwrite implementation in superclass because only special
|
---|
473 | * parameters are valid.
|
---|
474 | * @see #addParam(String,Object).
|
---|
475 | */
|
---|
476 | public void setParameters(Parameter[] parameters) {
|
---|
477 | if (parameters != null) {
|
---|
478 | for (int i = 0; i < parameters.length; i++) {
|
---|
479 | configParameter.add(parameters[i]);
|
---|
480 | }
|
---|
481 | }
|
---|
482 | }
|
---|
483 |
|
---|
484 |
|
---|
485 | /**
|
---|
486 | * Support for nested <param name="" value=""/> tags.
|
---|
487 | * Parameter named <i>cache</i>, <i>algorithm</i>,
|
---|
488 | * <i>comparator</i> or <i>update</i> are mapped to
|
---|
489 | * the respective set-Method.
|
---|
490 | * Parameter which names starts with <i>cache.</i> or
|
---|
491 | * <i>algorithm.</i> or <i>comparator.</i> are tried
|
---|
492 | * to set on the appropriate object via its set-methods.
|
---|
493 | * Other parameters are invalid and an BuildException will
|
---|
494 | * be thrown.
|
---|
495 | *
|
---|
496 | * @param parameter Key and value as parameter object
|
---|
497 | */
|
---|
498 | public void useParameter(Parameter parameter) {
|
---|
499 | String key = parameter.getName();
|
---|
500 | String value = parameter.getValue();
|
---|
501 | if ("cache".equals(key)) {
|
---|
502 | CacheName cn = new CacheName();
|
---|
503 | cn.setValue(value);
|
---|
504 | setCache(cn);
|
---|
505 | } else if ("algorithm".equals(key)) {
|
---|
506 | AlgorithmName an = new AlgorithmName();
|
---|
507 | an.setValue(value);
|
---|
508 | setAlgorithm(an);
|
---|
509 | } else if ("comparator".equals(key)) {
|
---|
510 | ComparatorName cn = new ComparatorName();
|
---|
511 | cn.setValue(value);
|
---|
512 | setComparator(cn);
|
---|
513 | } else if ("update".equals(key)) {
|
---|
514 | boolean updateValue =
|
---|
515 | ("true".equalsIgnoreCase(value))
|
---|
516 | ? true
|
---|
517 | : false;
|
---|
518 | setUpdate(updateValue);
|
---|
519 | } else if ("seldirs".equals(key)) {
|
---|
520 | boolean sdValue =
|
---|
521 | ("true".equalsIgnoreCase(value))
|
---|
522 | ? true
|
---|
523 | : false;
|
---|
524 | setSeldirs(sdValue);
|
---|
525 | } else if (key.startsWith("cache.")) {
|
---|
526 | String name = key.substring(6);
|
---|
527 | tryToSetAParameter(cache, name, value);
|
---|
528 | } else if (key.startsWith("algorithm.")) {
|
---|
529 | String name = key.substring(10);
|
---|
530 | tryToSetAParameter(algorithm, name, value);
|
---|
531 | } else if (key.startsWith("comparator.")) {
|
---|
532 | String name = key.substring(11);
|
---|
533 | tryToSetAParameter(comparator, name, value);
|
---|
534 | } else {
|
---|
535 | setError("Invalid parameter " + key);
|
---|
536 | }
|
---|
537 | }
|
---|
538 |
|
---|
539 |
|
---|
540 | /**
|
---|
541 | * Try to set a value on an object using reflection.
|
---|
542 | * Helper method for easier access to IntrospectionHelper.setAttribute().
|
---|
543 | * @param obj the object on which the attribute should be set
|
---|
544 | * @param name the attributename
|
---|
545 | * @param value the new value
|
---|
546 | */
|
---|
547 | protected void tryToSetAParameter(Object obj, String name, String value) {
|
---|
548 | Project prj = (getProject() != null) ? getProject() : new Project();
|
---|
549 | IntrospectionHelper iHelper
|
---|
550 | = IntrospectionHelper.getHelper(prj, obj.getClass());
|
---|
551 |
|
---|
552 | try {
|
---|
553 | iHelper.setAttribute(prj, obj, name, value);
|
---|
554 | } catch (org.apache.tools.ant.BuildException e) {
|
---|
555 | // no-op
|
---|
556 | }
|
---|
557 | }
|
---|
558 |
|
---|
559 |
|
---|
560 | // ----- 'beautiful' output -----
|
---|
561 |
|
---|
562 |
|
---|
563 | /**
|
---|
564 | * Override Object.toString().
|
---|
565 | * @return information about this selector
|
---|
566 | */
|
---|
567 | public String toString() {
|
---|
568 | StringBuffer buf = new StringBuffer("{modifiedselector");
|
---|
569 | buf.append(" update=").append(update);
|
---|
570 | buf.append(" seldirs=").append(selectDirectories);
|
---|
571 | buf.append(" cache=").append(cache);
|
---|
572 | buf.append(" algorithm=").append(algorithm);
|
---|
573 | buf.append(" comparator=").append(comparator);
|
---|
574 | buf.append("}");
|
---|
575 | return buf.toString();
|
---|
576 | }
|
---|
577 |
|
---|
578 |
|
---|
579 | // The EnumeratedAttributes for the three interface implementations.
|
---|
580 | // Name-Classname mapping is done in the configure() method.
|
---|
581 |
|
---|
582 |
|
---|
583 | public Cache getCache() { return cache; }
|
---|
584 | public void setCache(CacheName name) {
|
---|
585 | cacheName = name;
|
---|
586 | }
|
---|
587 | public static class CacheName extends EnumeratedAttribute {
|
---|
588 | public String[] getValues() {
|
---|
589 | return new String[] {"propertyfile" };
|
---|
590 | }
|
---|
591 | }
|
---|
592 |
|
---|
593 |
|
---|
594 | public Algorithm getAlgorithm() { return algorithm; }
|
---|
595 | public void setAlgorithm(AlgorithmName name) {
|
---|
596 | algoName = name;
|
---|
597 | }
|
---|
598 | public static class AlgorithmName extends EnumeratedAttribute {
|
---|
599 | public String[] getValues() {
|
---|
600 | return new String[] {"hashvalue", "digest" };
|
---|
601 | }
|
---|
602 | }
|
---|
603 |
|
---|
604 |
|
---|
605 | public Comparator getComparator() { return comparator; }
|
---|
606 | public void setComparator(ComparatorName name) {
|
---|
607 | compName = name;
|
---|
608 | }
|
---|
609 | public static class ComparatorName extends EnumeratedAttribute {
|
---|
610 | public String[] getValues() {
|
---|
611 | return new String[] {"equal", "rule" };
|
---|
612 | }
|
---|
613 | }
|
---|
614 |
|
---|
615 | }
|
---|