KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > idaremedia > antx > starters > TaskSet


1 /**
2  * $Id: TaskSet.java 187 2007-03-25 17:59:16Z ssmc $
3  * Copyright 2002-2004,2007 iDare Media, Inc. All rights reserved.
4  *
5  * Originally written by iDare Media, Inc. for release into the public domain. This
6  * library, source form and binary form, is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation; either version 2.1 of the License, or (at your option) any
9  * later version.<p>
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU LGPL (GNU Lesser General Public License) for more details.<p>
14  *
15  * You should have received a copy of the GNU Lesser General Public License along with this
16  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
17  * 330, Boston, MA 02111-1307 USA. The LGPL can be found online at
18  * http://www.fsf.org/copyleft/lesser.html<p>
19  *
20  * This product has been influenced by several projects within the open-source community.
21  * The JWare developers wish to acknowledge the open-source community's support. For more
22  * information regarding the open-source products used within JWare, please visit the
23  * JWare website.
24  *----------------------------------------------------------------------------------------*
25  * WEBSITE- http://antxtras.sf.net/ EMAIL- jware[at]users[dot]sourceforge[dot]net
26  *----------------------------------------------------------------------------------------*
27  **/

28
29 package com.idaremedia.antx.starters;
30
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33
34 import org.apache.tools.ant.BuildException;
35 import org.apache.tools.ant.Project;
36 import org.apache.tools.ant.RuntimeConfigurable;
37 import org.apache.tools.ant.Target;
38 import org.apache.tools.ant.Task;
39 import org.apache.tools.ant.TaskContainer;
40 import org.apache.tools.ant.UnknownElement;
41 import org.apache.tools.ant.util.CollectionUtils;
42
43 import com.idaremedia.antx.AntX;
44 import com.idaremedia.antx.AntXFixture;
45 import com.idaremedia.antx.AssertableTask;
46 import com.idaremedia.antx.helpers.Empties;
47 import com.idaremedia.antx.helpers.TaskHandle;
48 import com.idaremedia.antx.ownhelpers.TaskExaminer;
49
50 /**
51  * Base implementation of AntX task containers. Implements basic support for the
52  * following behavior:<ul>
53  * <li>Unmasking of "UnknownElements" proxies for true AntX tasks.</li>
54  * <li>Delay configuration of nested tasks.</li>
55  * <li>Filtering of nested tasks (by default allows anything).</li>
56  * <li>Template method(s) for nested task execution.</li>
57  * </ul>
58  *
59  * @since JWare/AntX 0.1
60  * @author ssmc, &copy;2002-2004,2007 <a HREF="http://www.jware.info">iDare&nbsp;Media,&nbsp;Inc.</a>
61  * @version 0.5.1
62  * @.safety single
63  * @.group impl,infra
64  * @see StrictInnerTask
65  * @see StrictOuterTask
66  **/

67
68 public class TaskSet extends AssertableTask implements TaskContainer
69 {
70     /**
71      * Default setting of the delay-configure behavior of this
72      * container (<i>true</i>).
73      **/

74     public static final boolean DEFAULT_DELAY_CONFIGURE= true;
75
76
77     /**
78      * Used to mark the number of tasks to be added as "unknown".
79      * @since JWare/AntXtras 0.5.1
80      */

81     private static final int INFINITE_TASKS = Integer.MAX_VALUE;
82
83
84
85     /**
86      * Initializes a new empty taskset.
87      **/

88     public TaskSet()
89     {
90         super(AntX.starters);
91     }
92
93
94     /**
95      * Initializes a new CV-labeled empty taskset.
96      * @param iam CV-label (non-null)
97      **/

98     protected TaskSet(String JavaDoc iam)
99     {
100         super(iam);
101     }
102
103
104
105     /**
106      * Empties this taskset's current list of tasks. This method
107      * is only triggered if a taskset subclass implements the
108      * <span class="src">Reconfigurable</span> interface.
109      * @since JWare/AntX 0.5
110      */

111     public void unconfigure()
112     {
113         super.unconfigure();
114         getTasksList().clear();
115     }
116
117
118
119     /**
120      * Initializes new configuration-delaying empty taskset.
121      * @param iam CV-label (non-null)
122      * @param delayConfigure <i>true</i> if nested tasks configured
123      * when they're actually executed
124      **/

125     protected TaskSet(String JavaDoc iam, boolean delayConfigure)
126     {
127         super(iam);
128         delayChildrenConfigure(delayConfigure);
129     }
130
131
132
133     /**
134      * Explicitly tells this taskset whether to delay configuration
135      * of nested tasks until they're executed.
136      * @param delay <i>true</i> if configuration delayed
137      **/

138     protected final void delayChildrenConfigure(boolean delay)
139     {
140         m_delayConfigure = delay;
141     }
142
143
144
145     /**
146      * Returns <i>true</i> if this taskset prefers to delay child
147      * configuration until they're executed(performed).
148      **/

149     protected final boolean isDelayChildrenConfigure()
150     {
151         return m_delayConfigure;
152     }
153
154
155
156     /**
157      * Optionally delays configuration of nested tasks until they're
158      * executed (like standard '<i>sequential</i>' task).
159      * @see TaskExaminer#ignoreConfigure TaskExaminer.ignoreConfigure(&#8230;)
160      **/

161     public void maybeConfigure()
162         throws BuildException
163     {
164         if (!TaskExaminer.ignoreConfigure(this)) {//@since AntX0.4+Ant1.6
165
if (isInvalid() || !isDelayChildrenConfigure()) {
166                 super.maybeConfigure();
167             } else {
168                 getRuntimeConfigurableWrapper().maybeConfigure(getProject(),false);
169                 if (AntX.ANT_PRE17) {//order: children,configure
170
maybeConfigureSpecialTasks();
171                 }
172             }
173         }
174     }
175
176
177     /**
178      * Half of workaround for the switch in ordering of the UnknownElement's
179      * maybeConfigure processing since Ant 1&#46;7.
180      * @since JWare/AntX 0.5.1
181      */

182     public void setRuntimeConfigurableWrapper(RuntimeConfigurable wrapper)
183     {
184         if (!AntX.ANT_PRE17) {//Ant 1.7 hack: try calc how many calls to 'addTask' possible!
185
if (wrapper!=null) {
186                 int n=0;
187                 for (Iterator JavaDoc itr=CollectionUtils.asIterator(wrapper.getChildren());itr.hasNext();) {
188                     itr.next();
189                     n++;
190                 }
191                 if (n>0) {
192                     this.m_configureThreshold = n;
193                 }
194             }
195         }
196         super.setRuntimeConfigurableWrapper(wrapper);
197     }
198
199
200
201     /**
202      * Called by {@linkplain #maybeConfigure maybeConfigure} if
203      * configuration of nested tasks has been delayed. This allows
204      * subclasses to configure special nested tasks that <em>should</em>
205      * be configured at the same time as this especially if these
206      * tasks are not included in the list of tasks returned by
207      * {@linkplain #getTasks getTasks}
208      **/

209     protected void maybeConfigureSpecialTasks()
210     {
211         //no-op for this class.
212
}
213
214
215
216     /**
217      * Returns this taskset's list of nested tasks.
218      **/

219     protected List JavaDoc getTasksList()
220     {
221         return m_nestedTasks;
222     }
223
224
225
226     /**
227      * Returns <i>true</i> if this taskset considers itself empty.
228      * @since JWare/AntX 0.5
229      **/

230     protected boolean isEmpty()
231     {
232         return getTasksList().isEmpty();
233     }
234
235
236
237     /**
238      * Returns <i>true</i> if task inside handle is allowed to nest within
239      * this taskset. Returns <i>true</i> by default; all tasks are allowed.
240      * This method can also switch the task to be included by this taskset
241      * by updating the incoming handle. Warning: the task should never be
242      * set to <i>null</i> if this method returns <i>true</i>.
243      * @param taskH the task to be nested (as handle)
244      * @see #candidateTask candidateTask(TaskHandle,Class[])
245      **/

246     protected boolean includeTask(TaskHandle taskH)
247     {
248         return true;
249     }
250
251
252
253     /**
254      * Adds another task if allowed.
255      * @param task task to be added
256      * @throws BuildException if task cannot be nested here
257      * @see TaskExaminer
258      **/

259     public void addTask(Task task)
260     {
261         require_(task!=null,"addTsk- nonzro task");
262
263         TaskHandle taskH = new TaskHandle(task);
264
265         if (includeTask(taskH)) {
266             verify_(!taskH.isEmpty(),"addTsk- nonzro task");
267             getTasksList().add(taskH.getTask());
268         } else {
269             String JavaDoc ermsg = uistrs().get("taskset.nested.task.disallowed",
270                                     task.getTaskName(), this.getTaskName());
271             log(ermsg, Project.MSG_ERR);
272             throw new BuildException(ermsg,getLocation());
273         }
274         addedTask();
275     }
276
277
278
279     /**
280      * Called after a task has been added to this task set's underlying
281      * set. For Ant 1&#46;7 or later ensures the task set's special tasks (if any)
282      * are properly configured before others. Only used if Ant 1&#46;7 or later.
283      * @since JWare/AntXtras 0.5.1
284      **/

285     protected final void addedTask()
286     {
287         if (!AntX.ANT_PRE17) {
288             m_configureThreshold--;
289             if (m_configureThreshold==0) {
290                 finishedAddingTasks();
291             }
292         }
293     }
294  
295
296
297     /**
298      * If Ant 1&#46;7 or later runtime, this method is called after this task
299      * set's children have all been added to esure the task set's special tasks
300      * (if any) are properly configured before others.
301      * Only used if Ant 1&#46;7 or later.
302      * @since JWare/AntXtras 0.5.1
303      **/

304     private void finishedAddingTasks()
305     {
306         m_configureThreshold = INFINITE_TASKS;
307         maybeConfigureSpecialTasks();
308     }
309
310
311
312     /**
313      * An {@linkplain #includeTask includeTask()} helper that ensures
314      * an Ant 1.6+ placeholder task is replaced if AntX's strict script
315      * loading property is turned on. The handle should be updated with
316      * the true task.
317      * @param taskH the task to be examined (non-null)
318      * @param coi classes of interest (non-null)
319      * @return the task to examine (might be flipped, might not)
320      * @see TaskExaminer#candidateTask TaskExaminer.candidateTask()
321      * @since JWare/AntX 0.4
322      **/

323     protected final Task candidateTask(TaskHandle taskH, Class JavaDoc[] coi)
324     {
325         return TaskExaminer.candidateTask(taskH,coi,this);
326     }
327
328
329
330     /**
331      * Returns a new array of this taskset's nested tasks. The array
332      * is new, the tasks are live references.
333      **/

334     public Task[] getTasks()
335     {
336         return (Task[])getTasksList().toArray(Empties.EMPTY_TASK_ARRAY);
337     }
338
339
340
341     /**
342      * Runs this task's nested tasks in order. Each task's '<i>perform</i>'
343      * method is called.
344      **/

345     protected final void performTheTasksList() throws BuildException
346     {
347         Iterator JavaDoc itr = getTasksList().listIterator();
348         while (itr.hasNext()) {
349             Task nestedTask = (Task)itr.next();
350             nestedTask.perform();
351         }
352     }
353
354
355
356     /**
357      * Runs a <em>new copy</em> of this task's nested tasks in order in
358      * targetted project. Each new task instance's
359      * <span class="src">perform</span> method is called. Expects this
360      * taskset's internals have not been resolved and contain the original
361      * proxies installed by Ant parsing process.
362      * @see TaskExaminer#copyUEProxy TaskExaminer.copyUEProxy(&#8230;)
363      * @throws BuildException if any nested task does.
364      * @since JWare/AntX 0.5
365      * @.safety multiple if tasklist is frozen.
366      **/

367     protected final void performIterationOfTheTasksList(final Project theProject,
368         final Target parent) throws BuildException
369     {
370         require_(theProject!=null,"preformIterOfItems- nonzro project");
371         require_(parent!=null,"preformIterOfItems- nonzro parent target");
372         
373         Iterator JavaDoc itr = getTasksList().listIterator();
374
375         while (itr.hasNext()) {
376             UnknownElement template = (UnknownElement)itr.next();
377             UnknownElement instance = TaskExaminer.copyUEProxy(template,theProject,parent);
378             instance.perform();
379             instance = null;
380         }
381     }
382
383
384
385     /**
386      * Runs a <em>new copy</em> of this task's nested tasks in order.
387      * Like {@linkplain #performIterationOfTheTasksList(Project,Target)
388      * performIterationOfTheTasksList(&#8230;)} but for this taskset's
389      * own project.
390      * @since JWare/AntX 0.5
391      **/

392     protected final void performIterationOfTheTasksList() throws BuildException
393     {
394         performIterationOfTheTasksList(getProject(),getOwningTarget());
395     }
396
397
398
399     /**
400      * Runs nested tasks in order. Each task's '<i>perform</i>' method
401      * is called. Subclasses can override this method to decorate the
402      * central {@linkplain #performTheTasksList} method which actually
403      * performs each task in this container.
404      * @throws BuildException if any nested task does
405      **/

406     protected void performNestedTasks() throws BuildException
407     {
408         performTheTasksList();
409     }
410
411
412
413     /**
414      * Same as {@linkplain #performNestedTasks performNestedTasks} after
415      * execution verification.
416      * @throws BuildException if unable to execute for any reason
417      **/

418     public void execute() throws BuildException
419     {
420         verifyCanExecute_("execute");
421
422         performNestedTasks();
423     }
424
425
426
427     /**
428      * Helper that ensures one and only one of a particular strict nested
429      * task is defined for this taskset at any time.
430      * @throws BuildException if current task is defined
431      **/

432     protected final void verifyIsUndefined_(Task currentTask, Task newTask)
433         throws BuildException
434     {
435         if (currentTask!=null) {
436             String JavaDoc ermsg = uistrs().get("taskset.only.one.specialtask",
437                                         newTask.getTaskName(),
438                                         currentTask.getTaskName());
439             log(ermsg, Project.MSG_ERR);
440             throw new BuildException(ermsg,getLocation());
441         }
442     }
443
444
445     private boolean m_delayConfigure= DEFAULT_DELAY_CONFIGURE;
446     private List JavaDoc m_nestedTasks= AntXFixture.newList(10);//NB: only access thru getTasksList()!
447
private int m_configureThreshold= INFINITE_TASKS;
448 }
449
450 /* end-of-TaskSet.java */
451
Popular Tags