source: release-kits/shared/ant/src/main/org/apache/tools/ant/taskdefs/CallTarget.java@ 16685

Last change on this file since 16685 was 16685, checked in by oranfry, 16 years ago

hacked ant now addresses all targets and supports -sim, -from, -to and -descend without need of a custom task

File size: 10.9 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.taskdefs;
19import java.io.IOException;
20
21import org.apache.tools.ant.Task;
22import org.apache.tools.ant.Target;
23import org.apache.tools.ant.BuildException;
24import org.apache.tools.ant.types.PropertySet;
25
26/**
27 * Call another target in the same project.
28 *
29 * <pre>
30 * &lt;target name="foo"&gt;
31 * &lt;antcall target="bar"&gt;
32 * &lt;param name="property1" value="aaaaa" /&gt;
33 * &lt;param name="foo" value="baz" /&gt;
34 * &lt;/antcall&gt;
35 * &lt;/target&gt;
36 *
37 * &lt;target name="bar" depends="init"&gt;
38 * &lt;echo message="prop is ${property1} ${foo}" /&gt;
39 * &lt;/target&gt;
40 * </pre>
41 *
42 * <p>This only works as expected if neither property1 nor foo are
43 * defined in the project itself.
44 *
45 *
46 * @since Ant 1.2
47 *
48 * @ant.task name="antcall" category="control"
49 */
50public class CallTarget extends Task {
51
52 private Ant callee;
53 // must match the default value of Ant#inheritAll
54 private boolean inheritAll = true;
55 // must match the default value of Ant#inheritRefs
56 private boolean inheritRefs = false;
57
58 private boolean targetSet = false;
59 private String theTarget = null;
60 private String address = null;
61
62 /**
63 * If true, pass all properties to the new Ant project.
64 * Defaults to true.
65 * @param inherit <code>boolean</code> flag.
66 */
67 public void setInheritAll(boolean inherit) {
68 inheritAll = inherit;
69 }
70
71 /**
72 * If true, pass all references to the new Ant project.
73 * Defaults to false.
74 * @param inheritRefs <code>boolean</code> flag.
75 */
76 public void setInheritRefs(boolean inheritRefs) {
77 this.inheritRefs = inheritRefs;
78 }
79
80 /**
81 * Initialize this task by creating new instance of the ant task and
82 * configuring it by calling its own init method.
83 */
84 public void init() {
85 callee = (Ant) getProject().createTask("ant");
86 callee.setOwningTarget(getOwningTarget());
87 callee.setTaskName(getTaskName());
88 callee.setLocation(getLocation());
89 callee.init();
90 }
91
92 /**
93 * Delegate the work to the ant task instance, after setting it up.
94 * @throws BuildException on validation failure or if the target didn't
95 * execute.
96 */
97 public void execute() throws BuildException {
98 if (callee == null) {
99 init();
100 }
101 if (!targetSet) {
102 throw new BuildException(
103 "Attribute target or at least one nested target is required.",
104 getLocation());
105 }
106
107 /* -- start target addressing code -- */
108
109 //figure out what the address of this instance should be
110 String callingAddress = this.getOwningTarget().getAddress();
111 int subAddress = this.getOwningTarget().getNextSubAddress();
112 this.getOwningTarget().incrementNextSubAddress();
113
114 if ( callingAddress == null ) {
115 address = "" + subAddress;
116 } else {
117 address = callingAddress + "." + subAddress;
118 }
119
120
121 //check that the target should be run given address, resume.descend, resume.from and resume.to
122 String resumeFrom = this.getProject().getProperty("resume.from");
123 String resumeDescend = this.getProject().getProperty("resume.descend");
124 String resumeTo = this.getProject().getProperty("resume.to");
125
126 //given resumeFrom, resumeDescend and ResumeTo, might we execute?
127 boolean shouldExecOnFrom = resumeFrom == null || isDescendantOf(resumeFrom,address) || isAfter(address,resumeFrom);
128 boolean shouldExecuteOnDescend = resumeDescend == null || isDescendantOf(resumeDescend,address) || isDescendantOf(address,resumeDescend);
129 boolean shouldExecOnTo = resumeTo == null || !isAfter(address,resumeTo);
130
131 //check that all are true
132 boolean execute = shouldExecOnFrom && shouldExecuteOnDescend && shouldExecOnTo;
133
134 if ( !execute ) {
135 return;
136 }
137
138 /* -- end target addressing code -- */
139
140 callee.setAntfile(getProject().getProperty("ant.file"));
141 callee.setInheritAll(inheritAll);
142 callee.setInheritRefs(inheritRefs);
143 Target calleeTarget = (Target)callee.getProject().getTargets().get(theTarget);
144 calleeTarget.setAddress(address);
145 callee.execute(theTarget,address);
146
147 }
148
149 /**
150 * Create a new Property to pass to the invoked target(s).
151 * @return a <code>Property</code> object.
152 */
153 public Property createParam() {
154 if (callee == null) {
155 init();
156 }
157 return callee.createProperty();
158 }
159
160 /**
161 * Reference element identifying a data type to carry
162 * over to the invoked target.
163 * @param r the specified <code>Ant.Reference</code>.
164 * @since Ant 1.5
165 */
166 public void addReference(Ant.Reference r) {
167 if (callee == null) {
168 init();
169 }
170 callee.addReference(r);
171 }
172
173 /**
174 * Set of properties to pass to the new project.
175 * @param ps the <code>PropertySet</code> to pass.
176 * @since Ant 1.6
177 */
178 public void addPropertyset(PropertySet ps) {
179 if (callee == null) {
180 init();
181 }
182 callee.addPropertyset(ps);
183 }
184
185 /**
186 * Set target to execute.
187 * @param target the name of the target to execute.
188 */
189 public void setTarget(String target) {
190 if (callee == null) {
191 init();
192 }
193 callee.setTarget(target);
194 theTarget = target;
195 targetSet = true;
196 }
197
198 /**
199 * Add a target to the list of targets to invoke.
200 * @param t <code>Ant.TargetElement</code> representing the target.
201 * @since Ant 1.6.3
202 */
203 public void addConfiguredTarget(Ant.TargetElement t) {
204 if (callee == null) {
205 init();
206 }
207 callee.addConfiguredTarget(t);
208 targetSet = true;
209 }
210
211 /**
212 * @see Task#handleOutput(String)
213 *
214 * @since Ant 1.5
215 */
216 public void handleOutput(String output) {
217 if (callee != null) {
218 callee.handleOutput(output);
219 } else {
220 super.handleOutput(output);
221 }
222 }
223
224 /**
225 * @see Task#handleInput(byte[], int, int)
226 *
227 * @since Ant 1.6
228 */
229 public int handleInput(byte[] buffer, int offset, int length)
230 throws IOException {
231 if (callee != null) {
232 return callee.handleInput(buffer, offset, length);
233 } else {
234 return super.handleInput(buffer, offset, length);
235 }
236 }
237
238 /**
239 * @see Task#handleFlush(String)
240 *
241 * @since Ant 1.5.2
242 */
243 public void handleFlush(String output) {
244 if (callee != null) {
245 callee.handleFlush(output);
246 } else {
247 super.handleFlush(output);
248 }
249 }
250
251 /**
252 * @see Task#handleErrorOutput(String)
253 *
254 * @since Ant 1.5
255 */
256 public void handleErrorOutput(String output) {
257 if (callee != null) {
258 callee.handleErrorOutput(output);
259 } else {
260 super.handleErrorOutput(output);
261 }
262 }
263
264 /**
265 * @see Task#handleErrorFlush(String)
266 *
267 * @since Ant 1.5.2
268 */
269 public void handleErrorFlush(String output) {
270 if (callee != null) {
271 callee.handleErrorFlush(output);
272 } else {
273 super.handleErrorFlush(output);
274 }
275 }
276
277
278 /* --- node address relations for target addressing --- */
279 public static boolean isAfter(String x, String y) {
280
281 System.out.println( "x: " + x );
282 System.out.println( "y: " + y );
283
284 if ( x.equals("") || y.equals("") ) {
285 throw new BuildException("Error - x or y not specified !!");
286 }
287
288 //check that both are in the form int.int.int
289
290 //break into chambers
291 String[] xs = x.split("\\.");
292 String[] ys = y.split("\\.");
293
294 //figure out n
295 int n = ys.length;
296
297 //step through, making sure x values are higher than or equal to y values
298 for ( int i=0; i<n; i++ ) {
299 int xValue = i<xs.length ? Integer.parseInt( xs[i] ) : 0;
300 int yValue = Integer.parseInt( ys[i] );
301
302 System.out.println( xValue + " " + yValue );
303 if( xValue < yValue ) {
304 System.out.println("x not after y");
305 return false;
306 }
307
308 if( xValue > yValue ) {
309 System.out.println("x is after y");
310 return true;
311 }
312 }
313
314 // if execution reaches here, first n places are equal
315 System.out.println("x is after y");
316 return true;
317 }
318
319
320 public static boolean isDescendantOf(String x, String y) {
321
322 System.out.println( "x: " + x );
323 System.out.println( "y: " + y );
324
325 if ( x.equals("") || y.equals("") ) {
326 throw new BuildException("Error - x or y not specified !!");
327 }
328
329 //check that both are in the form int.int.int
330
331 //break into chambers
332 String[] xs = x.split("\\.");
333 String[] ys = y.split("\\.");
334
335 //make sure x is at least as deep as y
336 if ( xs.length < ys.length ) {
337 System.out.println("x not descendant of y");
338 return false;
339 }
340
341 //figure out n
342 int n = ys.length;
343
344 //step through, making sure x values are equal to y values
345 for ( int i=0; i<n; i++ ) {
346 int xValue = Integer.parseInt( xs[i] );
347 int yValue = Integer.parseInt( ys[i] );
348
349 System.out.println( xValue + " " + yValue );
350 if( xValue != yValue ) {
351 System.out.println("x not descendant of y");
352 return false;
353 }
354 }
355
356 // if execution reaches here, first n places are equal
357 System.out.println("x is descendant of y");
358 return true;
359 }
360
361 public static boolean isEqualTo(String x, String y) {
362
363 System.out.println( "x: " + x );
364 System.out.println( "y: " + y );
365
366 if ( x.equals("") || y.equals("") ) {
367 throw new BuildException("Error - x or y not specified !!");
368 }
369
370 //check that both are in the form int.int.int
371
372 //break into chambers
373 String[] xs = x.split("\\.");
374 String[] ys = y.split("\\.");
375
376 //make sure x is exactly as deep as y
377 if ( xs.length != ys.length ) {
378 System.out.println("x not equal to y");
379 return false;
380 }
381
382 //figure out n
383 int n = xs.length;
384
385 //step through, making sure x values are equal to y values
386 for ( int i=0; i<n; i++ ) {
387 int xValue = Integer.parseInt( xs[i] );
388 int yValue = Integer.parseInt( ys[i] );
389
390 System.out.println( xValue + " " + yValue );
391 if( xValue != yValue ) {
392 System.out.println("x not equal to y");
393 return false;
394 }
395 }
396
397 // if execution reaches here, first all places
398 System.out.println("x is equal to y");
399 return true;
400 }
401
402
403}
Note: See TracBrowser for help on using the repository browser.