KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > idaremedia > antx > flowcontrol > RepeatedTaskSet


1 /**
2  * $Id: RepeatedTaskSet.java 180 2007-03-15 12:56:38Z ssmc $
3  * Copyright 2004 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 (LGPL) as published
8  * by the Free Software Foundation; either version 2.1 of the License, or (at your option)
9  * any 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 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 GNU 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://www.jware.info EMAIL- inquiries@jware.info
26  *----------------------------------------------------------------------------------------*
27  **/

28
29 package com.idaremedia.antx.flowcontrol;
30
31 import org.apache.tools.ant.BuildException;
32 import org.apache.tools.ant.Project;
33 import org.apache.tools.ant.types.Reference;
34
35 import com.idaremedia.antx.AntX;
36 import com.idaremedia.antx.apis.Requester;
37 import com.idaremedia.antx.condition.solo.RulesTk;
38 import com.idaremedia.antx.helpers.GenericParameters;
39 import com.idaremedia.antx.helpers.Tk;
40 import com.idaremedia.antx.ownhelpers.ScopedProperties;
41 import com.idaremedia.antx.parameters.FeedbackLevel;
42 import com.idaremedia.antx.starters.TaskSet;
43
44 /**
45  * Taskset that is executed as long as a named condition evaluates true. Usually defined
46  * as <span class="src">&lt;dowhile&gt;</span>.
47  * <p>
48  * While the RepeatedTaskSet can provide a set of overlaid properties to its test,
49  * unlike the <span class="src">foreach</span> type loop tasks, a RepeatedTaskSet does
50  * not (optionally) isolate its sub-tasks' execution from the current project. This
51  * means that a RepeatedTaskSet nested tasks can always access (and alter) fixture
52  * elements created and/or modified by the loop criteria task. (Of course you can
53  * manually isolate the nested tasks inside an AntX
54  * <span class="src">&lt;isolate&gt;</span> taskset.)
55  * <p>
56  * Setting a RepeatedTaskSet quiet does not affect(ie&#46; default) the feedback
57  * levels of its nested tasks.
58  * <p>
59  * <b>Example Usage:</b><pre>
60  * &lt;criteria id="moreLogs"...&gt;
61  * ...
62  * &lt;<b>dowhile</b> test="moreLogs" maxloops="25" haltifmax="yes"&gt;
63  * ...<i>[Tasks to process each log (next in $var:nextlogfile)]</i>
64  * &lt;/<b>dowhile</b>&gt;
65  * </pre>
66  *
67  * @since JWare/AntX 0.5
68  * @author ssmc, &copy;2004 <a HREF="http://www.jware.info">iDare&nbsp;Media,&nbsp;Inc.</a>
69  * @version 0.5
70  * @.safety single
71  * @.group api,infra
72  **/

73
74 public class RepeatedTaskSet extends TaskSet implements HardLimitEnabled
75 {
76     /**
77      * Initializes a new RepeatedTaskSet instance.
78      **/

79     public RepeatedTaskSet()
80     {
81         super(AntX.flow+"RepeatedTaskSet");
82     }
83
84
85
86     /**
87      * Initializes a new RepeatedTaskSet subclassed instance.
88      * @param iam CV-label (non-null)
89      **/

90     protected RepeatedTaskSet(String JavaDoc iam)
91     {
92         super(iam);
93     }
94
95
96
97     /**
98      * Defines the test for this repeat task. The referred to
99      * object must implement either the <span class="src">Condition</span>
100      * or <span class="src">ShareableCondition</span> interface.
101      * The reference is verified when this task is executed.
102      * @param testRef reference of test definition (non-null)
103      **/

104     public void setCriteria(Reference testRef)
105     {
106         require_(testRef!=null,"setTest- nonzro test ref");
107         m_conditionId = testRef;
108     }
109
110
111
112     /**
113      * Synonym for {@linkplain #setCriteria(Reference) setCriteria}.
114      * @param testRef reference to test definition (non-null)
115      **/

116     public final void setTest(Reference testRef)
117     {
118         setCriteria(testRef);
119     }
120
121
122
123     /**
124      * Returns this task's test's reference. Will return
125      * <i>null</i> if never set explicitly. Must be defined before
126      * this task is executed.
127      **/

128     public final String JavaDoc getCriteria()
129     {
130         return m_conditionId.getRefId();
131     }
132
133
134
135     /**
136      * Gives this loop task a hard limit to the number of times
137      * it can execute. This attribute serves mostly as an error
138      * handling mechanism to prevent infinite loops.
139      **/

140     public void setMaxLoops(int maxLoops)
141     {
142         m_maxLoops = maxLoops>=0 ? maxLoops : Integer.MAX_VALUE;
143     }
144
145
146
147     /**
148      * Returns <i>true</i> if this loop tasks has a hard limit.
149      **/

150     public final boolean hasMax()
151     {
152         return m_maxLoops!=Integer.MAX_VALUE;
153     }
154
155
156
157     /**
158      * Returns this loop tasks hard limit or <span class="src">-1</span>
159      * if no such limit exists.
160      **/

161     public final int getMaxLoops()
162     {
163         return hasMax() ? m_maxLoops : -1;
164     }
165
166
167
168     /**
169      * Tells this tasks whether to fail if the hard limit is
170      * reached. Ignored if this loop task does not have a hard limit.
171      * @see #setMaxLoops setMaxLoops(LIMIT)
172      **/

173     public void setHaltIfMax(boolean halt)
174     {
175         m_haltIfMax = halt ? Boolean.TRUE : Boolean.FALSE;
176     }
177
178
179
180     /**
181      * Returns this task's fail-if-max option setting. Will
182      * return <i>null</i> if never set explicitly. By default this
183      * task will <em>not</em> fail if its hard limit is hit; it
184      * just stops.
185      **/

186     public final Boolean JavaDoc getHaltIfMax()
187     {
188         return m_haltIfMax;
189     }
190
191
192
193     /**
194      * Tells this task how much non-diagnostic feedback to generate.
195      * Really only has "loud" vs. "quiet-ish" interpretation. If
196      * set quiet, this task will not issue a warning if it hits a
197      * hard limit.
198      * @param level feedback level (non-null)
199      **/

200     public void setFeedback(String JavaDoc level)
201     {
202         require_(level!=null,"setFeedback- nonzro level");
203         FeedbackLevel fbl = FeedbackLevel.from(level);
204         if (fbl==null) {
205             String JavaDoc e = getAntXMsg("task.illegal.param.value",
206                            getTaskName(), level,"feedbacklevel");
207             log(e, Project.MSG_ERR);
208             throw new BuildException(e, getLocation());
209         }
210         m_fbLevel = fbl;
211     }
212
213
214
215     /**
216      * Returns this task's assigned feedback level. Will return
217      * <i>null</i> if never set explicitly.
218      **/

219     public final FeedbackLevel getFeedbackLevel()
220     {
221         return m_fbLevel;
222     }
223
224
225
226
227     /**
228      * Tells this loop task to overlay its current loop cursor value
229      * as a property with the given name when its test is called. Unlike
230      * the foreach type loops, this is <em>not</em> a required
231      * parameter for repeated tasksets.
232      * @param cursorName the loop cursor name (as seen by the test)
233      **/

234     public void setI(String JavaDoc cursorName)
235     {
236         require_(cursorName!=null,"setI- nonzro name");
237         m_iName = cursorName;
238     }
239
240
241
242     /**
243      * Returns this loop's cursor overlay property's name. Will
244      * return <i>null</i> if not set explicitly.
245      **/

246     public final String JavaDoc getCursorName()
247     {
248         return m_iName;
249     }
250
251
252
253     /**
254      * Assigns an evaluation context to this loop task. How the
255      * context is used by the test is unknown to this task.
256      * @param refid reference to collection of key-value settings
257      * @see com.idaremedia.antx.solo.PropertiesList PropertiesList
258      **/

259     public void setContext(Reference refid)
260     {
261         m_evalContext = refid;
262     }
263
264
265
266     /**
267      * Returns this task's evaluation context. Will return <i>null</i>
268      * if no context was assigned explicitly.
269      **/

270     public final Reference getContext()
271     {
272         return m_evalContext;
273     }
274
275
276
277     /**
278      * Ensures we have been given a test reference and that it is
279      * valid. Will also verify that we do not have a always fail
280      * situation.
281      * @throws BuildException if improperly configured.
282      **/

283     protected void verifyCanExecute_(String JavaDoc calr)
284     {
285         super.verifyCanExecute_(calr);
286
287         if (m_conditionId==null) {
288             String JavaDoc error = getAntXMsg("task.needs.this.attr",
289                 getTaskName(),"criteria");
290             log(error, Project.MSG_ERR);
291             throw new BuildException(error,getLocation());
292         }
293         String JavaDoc testId = m_conditionId.getRefId();
294         RulesTk.verifyTest(testId,m_rqlink);
295
296         if (m_maxLoops==0 && m_haltIfMax==Boolean.TRUE) {
297             if (getFeedbackLevel()!=FeedbackLevel.NONE) {//?always-warn?
298
String JavaDoc e = getAntXMsg("flow.loop.alwaysfail");
299                 log(e, Project.MSG_WARN);
300             }
301         }
302     }
303
304
305
306     /**
307      * Performs this task's nested elements until its named criteria
308      * is no longer met.
309      * @throws BuildException if verification fails.
310      * @throws BuildException if any nested task does.
311      * @throws BuildException if hard limit it and haltifmax is turned on.
312      **/

313     protected void performNestedTasks() throws BuildException
314     {
315         String JavaDoc testId = m_conditionId.getRefId();
316         int i=0;
317         final int n=m_maxLoops;
318
319         while (i<n) {
320             boolean continu;
321             ScopedProperties overlay = installOverlay(i,getContext());
322             try {
323                 continu = RulesTk.evalTest(testId,m_rqlink);
324             } finally {
325                 uninstallOverlay(overlay);
326                 overlay = null;
327             }
328             if (!continu) {
329                 break;
330             }
331             performIterationOfTheTasksList();
332             i++;
333         }
334
335         if (i==n) {
336             String JavaDoc msg = getMsg();
337             if (Tk.isWhitespace(msg)) {
338                 msg = getAntXMsg("flow.loop.overflow",String.valueOf(i));
339             }
340             if (m_haltIfMax==Boolean.TRUE) {
341                 log(msg, Project.MSG_ERR);
342                 throw new BuildException(msg, getLocation());
343             }
344             if (!FeedbackLevel.isQuietish(m_fbLevel,false)) {
345                 log(msg, Project.MSG_WARN);
346             }
347         }
348     }
349
350
351
352     /**
353      * Installs all of our context properties and switch value
354      * as an overlay before calling condition.
355      **/

356     private ScopedProperties installOverlay(int i, Reference context)
357     {
358         Project P= getProject();
359         ScopedProperties overlay=null;
360
361         //NB: Ordering is important; let the switch.value prevail!
362
if (context!=null) {
363             Object JavaDoc o = P.getReference(context.getRefId());
364             if (o instanceof GenericParameters) {
365                 overlay = new ScopedProperties(P,true);
366                 overlay.put((GenericParameters)o);
367             }
368         }
369         if (m_iName!=null) {
370             if (overlay==null) {
371                 overlay = new ScopedProperties(P,true);
372             }
373             overlay.put(m_iName, String.valueOf(i));
374         }
375         if (overlay!=null) {
376             overlay.install();
377         }
378         return overlay;
379     }
380
381
382
383
384     /**
385      * Undoes the effect of {@linkplain #installOverlay installOverlay}.
386      **/

387     private void uninstallOverlay(ScopedProperties overlay)
388     {
389         if (overlay!=null) {
390             overlay.uninstall(null);
391             overlay=null;
392         }
393     }
394
395
396
397     /**
398      * Resets this taskset as if never configured. Allows this taskset
399      * to be re-run with different parameters and nested elements.
400      **/

401     public void unconfigure()
402     {
403         super.unconfigure();
404         m_conditionId = null;
405         m_maxLoops = Integer.MAX_VALUE;
406         m_haltIfMax = null;
407         m_fbLevel = null;
408         m_iName = null;
409         m_evalContext = null;
410     }
411
412
413     private Requester m_rqlink = new Requester.ForComponent(this);
414     private Reference m_conditionId;
415     private int m_maxLoops = Integer.MAX_VALUE;
416     private Boolean JavaDoc m_haltIfMax;//NB: *NO*
417
private FeedbackLevel m_fbLevel;
418     private String JavaDoc m_iName;//NB: null => none
419
private Reference m_evalContext;
420 }
421
422
423 /* end-of-WhileTask.java */
Popular Tags