KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > Target


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  */

18
19 package org.apache.tools.ant;
20
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Hashtable JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.StringTokenizer JavaDoc;
28
29 import org.apache.tools.ant.util.CollectionUtils;
30
31 /**
32  * Class to implement a target object with required parameters.
33  *
34  */

35 public class Target implements TaskContainer {
36
37     /** Name of this target. */
38     private String JavaDoc name;
39     /** The "if" condition to test on execution. */
40     private String JavaDoc ifCondition = "";
41     /** The "unless" condition to test on execution. */
42     private String JavaDoc unlessCondition = "";
43     /** List of targets this target is dependent on. */
44     private List JavaDoc dependencies = null;
45     /** Children of this target (tasks and data types). */
46     private List JavaDoc children = new ArrayList JavaDoc();
47     /** Since Ant 1.6.2 */
48     private Location location = Location.UNKNOWN_LOCATION;
49
50     /** Project this target belongs to. */
51     private Project project;
52
53     /** Description of this target, if any. */
54     private String JavaDoc description = null;
55
56     /** Default constructor. */
57     public Target() {
58         //empty
59
}
60
61     /**
62      * Cloning constructor.
63      * @param other the Target to clone.
64      */

65     public Target(Target other) {
66         this.name = other.name;
67         this.ifCondition = other.ifCondition;
68         this.unlessCondition = other.unlessCondition;
69         this.dependencies = other.dependencies;
70         this.location = other.location;
71         this.project = other.project;
72         this.description = other.description;
73         // The children are added to after this cloning
74
this.children = other.children;
75     }
76
77     /**
78      * Sets the project this target belongs to.
79      *
80      * @param project The project this target belongs to.
81      * Must not be <code>null</code>.
82      */

83     public void setProject(Project project) {
84         this.project = project;
85     }
86
87     /**
88      * Returns the project this target belongs to.
89      *
90      * @return The project this target belongs to, or <code>null</code> if
91      * the project has not been set yet.
92      */

93     public Project getProject() {
94         return project;
95     }
96
97     /**
98      * Sets the location of this target's definition.
99      *
100      * @param location <code>Location</code>
101      * @since 1.6.2
102      */

103     public void setLocation(Location location) {
104         this.location = location;
105     }
106
107     /**
108      * Get the location of this target's definition.
109      *
110      * @return <code>Location</code>
111      * @since 1.6.2
112      */

113     public Location getLocation() {
114         return location;
115     }
116
117     /**
118      * Sets the list of targets this target is dependent on.
119      * The targets themselves are not resolved at this time.
120      *
121      * @param depS A comma-separated list of targets this target
122      * depends on. Must not be <code>null</code>.
123      */

124     public void setDepends(String JavaDoc depS) {
125         if (depS.length() > 0) {
126             StringTokenizer JavaDoc tok =
127                 new StringTokenizer JavaDoc(depS, ",", true);
128             while (tok.hasMoreTokens()) {
129                 String JavaDoc token = tok.nextToken().trim();
130
131                 // Make sure the dependency is not empty string
132
if ("".equals(token) || ",".equals(token)) {
133                     throw new BuildException("Syntax Error: depends "
134                         + "attribute of target \"" + getName()
135                         + "\" has an empty string as dependency.");
136                 }
137
138                 addDependency(token);
139
140                 // Make sure that depends attribute does not
141
// end in a ,
142
if (tok.hasMoreTokens()) {
143                     token = tok.nextToken();
144                     if (!tok.hasMoreTokens() || !",".equals(token)) {
145                         throw new BuildException("Syntax Error: Depend "
146                             + "attribute for target \"" + getName()
147                             + "\" ends with a , character");
148                     }
149                 }
150             }
151         }
152     }
153
154     /**
155      * Sets the name of this target.
156      *
157      * @param name The name of this target. Should not be <code>null</code>.
158      */

159     public void setName(String JavaDoc name) {
160         this.name = name;
161     }
162
163     /**
164      * Returns the name of this target.
165      *
166      * @return the name of this target, or <code>null</code> if the
167      * name has not been set yet.
168      */

169     public String JavaDoc getName() {
170         return name;
171     }
172
173     /**
174      * Adds a task to this target.
175      *
176      * @param task The task to be added. Must not be <code>null</code>.
177      */

178     public void addTask(Task task) {
179         children.add(task);
180     }
181
182     /**
183      * Adds the wrapper for a data type element to this target.
184      *
185      * @param r The wrapper for the data type element to be added.
186      * Must not be <code>null</code>.
187      */

188     public void addDataType(RuntimeConfigurable r) {
189         children.add(r);
190     }
191
192     /**
193      * Returns the current set of tasks to be executed by this target.
194      *
195      * @return an array of the tasks currently within this target
196      */

197     public Task[] getTasks() {
198         List JavaDoc tasks = new ArrayList JavaDoc(children.size());
199         Iterator JavaDoc it = children.iterator();
200         while (it.hasNext()) {
201             Object JavaDoc o = it.next();
202             if (o instanceof Task) {
203                 tasks.add(o);
204             }
205         }
206
207         return (Task[]) tasks.toArray(new Task[tasks.size()]);
208     }
209
210     /**
211      * Adds a dependency to this target.
212      *
213      * @param dependency The name of a target this target is dependent on.
214      * Must not be <code>null</code>.
215      */

216     public void addDependency(String JavaDoc dependency) {
217         if (dependencies == null) {
218             dependencies = new ArrayList JavaDoc(2);
219         }
220         dependencies.add(dependency);
221     }
222
223     /**
224      * Returns an enumeration of the dependencies of this target.
225      *
226      * @return an enumeration of the dependencies of this target
227      */

228     public Enumeration JavaDoc getDependencies() {
229         return (dependencies != null ? Collections.enumeration(dependencies)
230                                      : new CollectionUtils.EmptyEnumeration());
231     }
232
233     /**
234      * Does this target depend on the named target?
235      * @param other the other named target.
236      * @return true if the target does depend on the named target
237      * @since Ant 1.6
238      */

239     public boolean dependsOn(String JavaDoc other) {
240         Project p = getProject();
241         Hashtable JavaDoc t = (p == null) ? null : p.getTargets();
242         return (p != null
243                 && p.topoSort(getName(), t, false).contains(t.get(other)));
244     }
245
246     /**
247      * Sets the "if" condition to test on execution. This is the
248      * name of a property to test for existence - if the property
249      * is not set, the task will not execute. The property goes
250      * through property substitution once before testing, so if
251      * property <code>foo</code> has value <code>bar</code>, setting
252      * the "if" condition to <code>${foo}_x</code> will mean that the
253      * task will only execute if property <code>bar_x</code> is set.
254      *
255      * @param property The property condition to test on execution.
256      * May be <code>null</code>, in which case
257      * no "if" test is performed.
258      */

259     public void setIf(String JavaDoc property) {
260         ifCondition = (property == null) ? "" : property;
261     }
262
263     /**
264      * Returns the "if" property condition of this target.
265      *
266      * @return the "if" property condition or <code>null</code> if no
267      * "if" condition had been defined.
268      * @since 1.6.2
269      */

270     public String JavaDoc getIf() {
271         return ("".equals(ifCondition) ? null : ifCondition);
272     }
273
274     /**
275      * Sets the "unless" condition to test on execution. This is the
276      * name of a property to test for existence - if the property
277      * is set, the task will not execute. The property goes
278      * through property substitution once before testing, so if
279      * property <code>foo</code> has value <code>bar</code>, setting
280      * the "unless" condition to <code>${foo}_x</code> will mean that the
281      * task will only execute if property <code>bar_x</code> isn't set.
282      *
283      * @param property The property condition to test on execution.
284      * May be <code>null</code>, in which case
285      * no "unless" test is performed.
286      */

287     public void setUnless(String JavaDoc property) {
288         unlessCondition = (property == null) ? "" : property;
289     }
290
291     /**
292      * Returns the "unless" property condition of this target.
293      *
294      * @return the "unless" property condition or <code>null</code>
295      * if no "unless" condition had been defined.
296      * @since 1.6.2
297      */

298     public String JavaDoc getUnless() {
299         return ("".equals(unlessCondition) ? null : unlessCondition);
300     }
301
302     /**
303      * Sets the description of this target.
304      *
305      * @param description The description for this target.
306      * May be <code>null</code>, indicating that no
307      * description is available.
308      */

309     public void setDescription(String JavaDoc description) {
310         this.description = description;
311     }
312
313     /**
314      * Returns the description of this target.
315      *
316      * @return the description of this target, or <code>null</code> if no
317      * description is available.
318      */

319     public String JavaDoc getDescription() {
320         return description;
321     }
322
323     /**
324      * Returns the name of this target.
325      *
326      * @return the name of this target, or <code>null</code> if the
327      * name has not been set yet.
328      */

329     public String JavaDoc toString() {
330         return name;
331     }
332
333     /**
334      * Executes the target if the "if" and "unless" conditions are
335      * satisfied. Dependency checking should be done before calling this
336      * method, as it does no checking of its own. If either the "if"
337      * or "unless" test prevents this target from being executed, a verbose
338      * message is logged giving the reason. It is recommended that clients
339      * of this class call performTasks rather than this method so that
340      * appropriate build events are fired.
341      *
342      * @exception BuildException if any of the tasks fail or if a data type
343      * configuration fails.
344      *
345      * @see #performTasks()
346      * @see #setIf(String)
347      * @see #setUnless(String)
348      */

349     public void execute() throws BuildException {
350         if (testIfCondition() && testUnlessCondition()) {
351             for (int taskPosition = 0;
352                  taskPosition < children.size();
353                  ++taskPosition) {
354                 Object JavaDoc o = children.get(taskPosition);
355                 if (o instanceof Task) {
356                     Task task = (Task) o;
357                     task.perform();
358                 } else {
359                     RuntimeConfigurable r = (RuntimeConfigurable) o;
360                     r.maybeConfigure(project);
361                 }
362             }
363         } else if (!testIfCondition()) {
364             project.log(this, "Skipped because property '"
365                         + project.replaceProperties(ifCondition)
366                         + "' not set.", Project.MSG_VERBOSE);
367         } else {
368             project.log(this, "Skipped because property '"
369                         + project.replaceProperties(unlessCondition)
370                         + "' set.", Project.MSG_VERBOSE);
371         }
372     }
373
374     /**
375      * Performs the tasks within this target (if the conditions are met),
376      * firing target started/target finished messages around a call to
377      * execute.
378      *
379      * @see #execute()
380      */

381     public final void performTasks() {
382         RuntimeException JavaDoc thrown = null;
383         project.fireTargetStarted(this);
384         try {
385             execute();
386         } catch (RuntimeException JavaDoc exc) {
387             thrown = exc;
388             throw exc;
389         } finally {
390             project.fireTargetFinished(this, thrown);
391         }
392     }
393
394     /**
395      * Replaces all occurrences of the given task in the list
396      * of children with the replacement data type wrapper.
397      *
398      * @param el The task to replace.
399      * Must not be <code>null</code>.
400      * @param o The data type wrapper to replace <code>el</code> with.
401      */

402     void replaceChild(Task el, RuntimeConfigurable o) {
403         int index;
404         while ((index = children.indexOf(el)) >= 0) {
405             children.set(index, o);
406         }
407     }
408
409     /**
410      * Replaces all occurrences of the given task in the list
411      * of children with the replacement task.
412      *
413      * @param el The task to replace.
414      * Must not be <code>null</code>.
415      * @param o The task to replace <code>el</code> with.
416      */

417     void replaceChild(Task el, Task o) {
418         int index;
419         while ((index = children.indexOf(el)) >= 0) {
420             children.set(index, o);
421         }
422     }
423
424     /**
425      * Tests whether or not the "if" condition is satisfied.
426      *
427      * @return whether or not the "if" condition is satisfied. If no
428      * condition (or an empty condition) has been set,
429      * <code>true</code> is returned.
430      *
431      * @see #setIf(String)
432      */

433     private boolean testIfCondition() {
434         if ("".equals(ifCondition)) {
435             return true;
436         }
437
438         String JavaDoc test = project.replaceProperties(ifCondition);
439         return project.getProperty(test) != null;
440     }
441
442     /**
443      * Tests whether or not the "unless" condition is satisfied.
444      *
445      * @return whether or not the "unless" condition is satisfied. If no
446      * condition (or an empty condition) has been set,
447      * <code>true</code> is returned.
448      *
449      * @see #setUnless(String)
450      */

451     private boolean testUnlessCondition() {
452         if ("".equals(unlessCondition)) {
453             return true;
454         }
455         String JavaDoc test = project.replaceProperties(unlessCondition);
456         return project.getProperty(test) == null;
457     }
458 }
459
Popular Tags