source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/Target.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 15.0 KB
Line 
1/*
2 * Copyright 2000-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
18package org.apache.tools.ant;
19
20import java.util.ArrayList;
21import java.util.Collections;
22import java.util.Enumeration;
23import java.util.Hashtable;
24import java.util.Iterator;
25import java.util.List;
26import java.util.StringTokenizer;
27
28import org.apache.tools.ant.util.CollectionUtils;
29
30/**
31 * Class to implement a target object with required parameters.
32 *
33 */
34public class Target implements TaskContainer {
35
36 /** Name of this target. */
37 private String name;
38 /** The "if" condition to test on execution. */
39 private String ifCondition = "";
40 /** The "unless" condition to test on execution. */
41 private String unlessCondition = "";
42 /** List of targets this target is dependent on. */
43 private List dependencies = null;
44 /** Children of this target (tasks and data types). */
45 private List children = new ArrayList();
46 /** Since Ant 1.6.2 */
47 private Location location = Location.UNKNOWN_LOCATION;
48
49 /** Oran's: The node address stuff for this target. */
50 private String address = null;
51 private int nextSubAddress = 1;
52
53
54 /** Project this target belongs to. */
55 private Project project;
56
57 /** Description of this target, if any. */
58 private String description = null;
59
60 /** Sole constructor. */
61 public Target() {
62 }
63
64 /**
65 * Sets the project this target belongs to.
66 *
67 * @param project The project this target belongs to.
68 * Must not be <code>null</code>.
69 */
70 public void setProject(Project project) {
71 this.project = project;
72 }
73
74 /**
75 * Returns the project this target belongs to.
76 *
77 * @return The project this target belongs to, or <code>null</code> if
78 * the project has not been set yet.
79 */
80 public Project getProject() {
81 return project;
82 }
83
84 /**
85 * Sets the location of this target's definition.
86 *
87 * @param location <CODE>Location</CODE>
88 * @since 1.6.2
89 */
90 public void setLocation(Location location) {
91 this.location = location;
92 }
93
94 /**
95 * Get the location of this target's definition.
96 *
97 * @return <CODE>Location</CODE>
98 * @since 1.6.2
99 */
100 public Location getLocation() {
101 return location;
102 }
103
104 /**
105 * Sets the list of targets this target is dependent on.
106 * The targets themselves are not resolved at this time.
107 *
108 * @param depS A comma-separated list of targets this target
109 * depends on. Must not be <code>null</code>.
110 */
111 public void setDepends(String depS) {
112 if (depS.length() > 0) {
113 StringTokenizer tok =
114 new StringTokenizer(depS, ",", true);
115 while (tok.hasMoreTokens()) {
116 String token = tok.nextToken().trim();
117
118 // Make sure the dependency is not empty string
119 if (token.equals("") || token.equals(",")) {
120 throw new BuildException("Syntax Error: Depend "
121 + "attribute for target \"" + getName()
122 + "\" has an empty string for dependency.");
123 }
124
125 addDependency(token);
126
127 // Make sure that depends attribute does not
128 // end in a ,
129 if (tok.hasMoreTokens()) {
130 token = tok.nextToken();
131 if (!tok.hasMoreTokens() || !token.equals(",")) {
132 throw new BuildException("Syntax Error: Depend "
133 + "attribute for target \"" + getName()
134 + "\" ends with a , character");
135 }
136 }
137 }
138 }
139 }
140
141 /**
142 * Sets the name of this target.
143 *
144 * @param name The name of this target. Should not be <code>null</code>.
145 */
146 public void setName(String name) {
147 this.name = name;
148 }
149
150 /**
151 * Returns the name of this target.
152 *
153 * @return the name of this target, or <code>null</code> if the
154 * name has not been set yet.
155 */
156 public String getName() {
157 return name;
158 }
159
160 /**
161 * Adds a task to this target.
162 *
163 * @param task The task to be added. Must not be <code>null</code>.
164 */
165 public void addTask(Task task) {
166 children.add(task);
167 }
168
169 /**
170 * Adds the wrapper for a data type element to this target.
171 *
172 * @param r The wrapper for the data type element to be added.
173 * Must not be <code>null</code>.
174 */
175 public void addDataType(RuntimeConfigurable r) {
176 children.add(r);
177 }
178
179 /**
180 * Returns the current set of tasks to be executed by this target.
181 *
182 * @return an array of the tasks currently within this target
183 */
184 public Task[] getTasks() {
185 List tasks = new ArrayList(children.size());
186 Iterator it = children.iterator();
187 while (it.hasNext()) {
188 Object o = it.next();
189 if (o instanceof Task) {
190 tasks.add(o);
191 }
192 }
193
194 return (Task[]) tasks.toArray(new Task[tasks.size()]);
195 }
196
197 /**
198 * Adds a dependency to this target.
199 *
200 * @param dependency The name of a target this target is dependent on.
201 * Must not be <code>null</code>.
202 */
203 public void addDependency(String dependency) {
204 if (dependencies == null) {
205 dependencies = new ArrayList(2);
206 }
207 dependencies.add(dependency);
208 }
209
210 /**
211 * Returns an enumeration of the dependencies of this target.
212 *
213 * @return an enumeration of the dependencies of this target
214 */
215 public Enumeration getDependencies() {
216 if (dependencies != null) {
217 return Collections.enumeration(dependencies);
218 } else {
219 return new CollectionUtils.EmptyEnumeration();
220 }
221 }
222
223 /**
224 * Does this target depend on the named target?
225 * @param other the other named target.
226 * @return true if the target does depend on the named target
227 * @since Ant 1.6
228 */
229 public boolean dependsOn(String other) {
230 Project p = getProject();
231 Hashtable t = (p == null) ? null : p.getTargets();
232 return (p != null && p.topoSort(getName(), t, false).contains(t.get(other)));
233 }
234
235 /**
236 * Sets the "if" condition to test on execution. This is the
237 * name of a property to test for existence - if the property
238 * is not set, the task will not execute. The property goes
239 * through property substitution once before testing, so if
240 * property <code>foo</code> has value <code>bar</code>, setting
241 * the "if" condition to <code>${foo}_x</code> will mean that the
242 * task will only execute if property <code>bar_x</code> is set.
243 *
244 * @param property The property condition to test on execution.
245 * May be <code>null</code>, in which case
246 * no "if" test is performed.
247 */
248 public void setIf(String property) {
249 this.ifCondition = (property == null) ? "" : property;
250 }
251
252 /**
253 * Returns the "if" property condition of this target.
254 *
255 * @return the "if" property condition or <code>null</code> if no
256 * "if" condition had been defined.
257 * @since 1.6.2
258 */
259 public String getIf() {
260 return ("".equals(ifCondition) ? null : ifCondition);
261 }
262
263 /**
264 * Sets the "unless" condition to test on execution. This is the
265 * name of a property to test for existence - if the property
266 * is set, the task will not execute. The property goes
267 * through property substitution once before testing, so if
268 * property <code>foo</code> has value <code>bar</code>, setting
269 * the "unless" condition to <code>${foo}_x</code> will mean that the
270 * task will only execute if property <code>bar_x</code> isn't set.
271 *
272 * @param property The property condition to test on execution.
273 * May be <code>null</code>, in which case
274 * no "unless" test is performed.
275 */
276 public void setUnless(String property) {
277 this.unlessCondition = (property == null) ? "" : property;
278 }
279
280 /**
281 * Returns the "unless" property condition of this target.
282 *
283 * @return the "unless" property condition or <code>null</code>
284 * if no "unless" condition had been defined.
285 * @since 1.6.2
286 */
287 public String getUnless() {
288 return ("".equals(unlessCondition) ? null : unlessCondition);
289 }
290
291 /**
292 * Sets the description of this target.
293 *
294 * @param description The description for this target.
295 * May be <code>null</code>, indicating that no
296 * description is available.
297 */
298 public void setDescription(String description) {
299 this.description = description;
300 }
301
302 /**
303 * Returns the description of this target.
304 *
305 * @return the description of this target, or <code>null</code> if no
306 * description is available.
307 */
308 public String getDescription() {
309 return description;
310 }
311
312 /**
313 * Sets the address of this target.
314 *
315 * @param address The address of this target. Should not be <code>null</code>.
316 */
317 public void setAddress(String address) {
318 //check in the form int.int.int
319
320 //set
321 this.address = address;
322 }
323
324 /**
325 * Returns the address of this target.
326 *
327 * @return the address of this target, or <code>null</code> if the
328 * address has not been set yet.
329 */
330 public String getAddress() {
331 return address;
332 }
333
334 public void incrementNextSubAddress() {
335 nextSubAddress++;
336 }
337
338 public int getNextSubAddress() {
339 return nextSubAddress;
340 }
341
342
343
344
345 /**
346 * Returns the name of this target.
347 *
348 * @return the name of this target, or <code>null</code> if the
349 * name has not been set yet.
350 */
351 public String toString() {
352 return name;
353 }
354
355 /**
356 * Executes the target if the "if" and "unless" conditions are
357 * satisfied. Dependency checking should be done before calling this
358 * method, as it does no checking of its own. If either the "if"
359 * or "unless" test prevents this target from being executed, a verbose
360 * message is logged giving the reason. It is recommended that clients
361 * of this class call performTasks rather than this method so that
362 * appropriate build events are fired.
363 *
364 * @exception BuildException if any of the tasks fail or if a data type
365 * configuration fails.
366 *
367 * @see #performTasks()
368 * @see #setIf(String)
369 * @see #setUnless(String)
370 */
371 public void execute() throws BuildException {
372 if (testIfCondition() && testUnlessCondition()) {
373 for (int taskPosition = 0;
374 taskPosition < children.size();
375 ++taskPosition) {
376 Object o = children.get(taskPosition);
377 if (o instanceof Task) {
378 Task task = (Task) o;
379 task.perform();
380 } else {
381 RuntimeConfigurable r = (RuntimeConfigurable) o;
382 r.maybeConfigure(project);
383 }
384 }
385 } else if (!testIfCondition()) {
386 project.log(this, "Skipped because property '"
387 + project.replaceProperties(this.ifCondition)
388 + "' not set.", Project.MSG_VERBOSE);
389 } else {
390 project.log(this, "Skipped because property '"
391 + project.replaceProperties(this.unlessCondition)
392 + "' set.", Project.MSG_VERBOSE);
393 }
394 }
395
396 /**
397 * Performs the tasks within this target (if the conditions are met),
398 * firing target started/target finished messages around a call to
399 * execute.
400 *
401 * @see #execute()
402 */
403 public final void performTasks() {
404 RuntimeException thrown = null;
405 project.fireTargetStarted(this);
406 try {
407 execute();
408 } catch (RuntimeException exc) {
409 thrown = exc;
410 throw exc;
411 } finally {
412 project.fireTargetFinished(this, thrown);
413 }
414 }
415
416 /**
417 * Replaces all occurrences of the given task in the list
418 * of children with the replacement data type wrapper.
419 *
420 * @param el The task to replace.
421 * Must not be <code>null</code>.
422 * @param o The data type wrapper to replace <code>el</code> with.
423 */
424 void replaceChild(Task el, RuntimeConfigurable o) {
425 int index;
426 while ((index = children.indexOf(el)) >= 0) {
427 children.set(index, o);
428 }
429 }
430
431 /**
432 * Replaces all occurrences of the given task in the list
433 * of children with the replacement task.
434 *
435 * @param el The task to replace.
436 * Must not be <code>null</code>.
437 * @param o The task to replace <code>el</code> with.
438 */
439 void replaceChild(Task el, Task o) {
440 int index;
441 while ((index = children.indexOf(el)) >= 0) {
442 children.set(index, o);
443 }
444 }
445
446 /**
447 * Tests whether or not the "if" condition is satisfied.
448 *
449 * @return whether or not the "if" condition is satisfied. If no
450 * condition (or an empty condition) has been set,
451 * <code>true</code> is returned.
452 *
453 * @see #setIf(String)
454 */
455 private boolean testIfCondition() {
456 if ("".equals(ifCondition)) {
457 return true;
458 }
459
460 String test = project.replaceProperties(ifCondition);
461 return project.getProperty(test) != null;
462 }
463
464 /**
465 * Tests whether or not the "unless" condition is satisfied.
466 *
467 * @return whether or not the "unless" condition is satisfied. If no
468 * condition (or an empty condition) has been set,
469 * <code>true</code> is returned.
470 *
471 * @see #setUnless(String)
472 */
473 private boolean testUnlessCondition() {
474 if ("".equals(unlessCondition)) {
475 return true;
476 }
477 String test = project.replaceProperties(unlessCondition);
478 return project.getProperty(test) == null;
479 }
480}
Note: See TracBrowser for help on using the repository browser.