1 |
|
---|
2 | /*
|
---|
3 | * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved.
|
---|
4 | *
|
---|
5 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
6 | * you may not use this file except in compliance with the License.
|
---|
7 | * 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 | package ise.antelope.tasks;
|
---|
18 |
|
---|
19 |
|
---|
20 | import java.util.Enumeration;
|
---|
21 | import java.util.Hashtable;
|
---|
22 | import java.util.Vector;
|
---|
23 |
|
---|
24 |
|
---|
25 | import org.apache.tools.ant.BuildException;
|
---|
26 | import org.apache.tools.ant.Task;
|
---|
27 | import org.apache.tools.ant.TaskContainer;
|
---|
28 | import org.apache.tools.ant.types.EnumeratedAttribute;
|
---|
29 |
|
---|
30 | import ise.antelope.tasks.typedefs.TimeUnit;
|
---|
31 |
|
---|
32 |
|
---|
33 | /**
|
---|
34 | * Limits the amount of time that a task or set of tasks can run. This is useful
|
---|
35 | * for tasks that may "hang" or otherwise not complete in a timely fashion. This
|
---|
36 | * task is done when either the maxwait time has expired or all nested tasks are
|
---|
37 | * complete, whichever is first.
|
---|
38 | *
|
---|
39 | * <p>Developed for use with Antelope, migrated to ant-contrib Oct 2003.
|
---|
40 | *
|
---|
41 | * @author Dale Anson
|
---|
42 | * @author Robert D. Rice
|
---|
43 | * @version $Revision: 1.4 $
|
---|
44 | * @since Ant 1.5
|
---|
45 | */
|
---|
46 | public class Limit extends Task implements TaskContainer {
|
---|
47 |
|
---|
48 |
|
---|
49 | // storage for nested tasks
|
---|
50 | private Vector tasks = new Vector();
|
---|
51 |
|
---|
52 |
|
---|
53 | // time units, default value is 3 minutes.
|
---|
54 | private long maxwait = 180;
|
---|
55 | protected TimeUnit unit = TimeUnit.SECOND_UNIT;
|
---|
56 |
|
---|
57 | // property to set if time limit is reached
|
---|
58 | private String timeoutProperty = null;
|
---|
59 | private String timeoutValue = "true";
|
---|
60 |
|
---|
61 |
|
---|
62 | // storage for task currently executing
|
---|
63 | private Task currentTask = null;
|
---|
64 |
|
---|
65 |
|
---|
66 | // used to control thread stoppage
|
---|
67 | private Thread taskRunner = null;
|
---|
68 |
|
---|
69 |
|
---|
70 | // should the build fail if the time limit has expired? Default is no.
|
---|
71 | private boolean failOnError = false;
|
---|
72 |
|
---|
73 |
|
---|
74 | private Exception exception = null;
|
---|
75 |
|
---|
76 |
|
---|
77 |
|
---|
78 |
|
---|
79 | /**
|
---|
80 | * Add a task to wait on.
|
---|
81 | *
|
---|
82 | * @param task A task to execute
|
---|
83 | * @exception BuildException won't happen
|
---|
84 | */
|
---|
85 | public void addTask( Task task ) throws BuildException {
|
---|
86 | tasks.addElement( task );
|
---|
87 | }
|
---|
88 |
|
---|
89 |
|
---|
90 |
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * How long to wait for all nested tasks to complete, in units.
|
---|
94 | * Default is to wait 3 minutes.
|
---|
95 | *
|
---|
96 | * @param wait time to wait, set to 0 to wait forever.
|
---|
97 | */
|
---|
98 | public void setMaxwait( int wait ) {
|
---|
99 | maxwait = wait;
|
---|
100 | }
|
---|
101 |
|
---|
102 | /**
|
---|
103 | * Sets the unit for the max wait. Default is minutes.
|
---|
104 |
|
---|
105 | * @param unit valid values are "millisecond", "second", "minute", "hour", "day", and "week".
|
---|
106 |
|
---|
107 | */
|
---|
108 | public void setUnit( String unit ) {
|
---|
109 | if ( unit == null )
|
---|
110 | return ;
|
---|
111 | if ( unit.equals( TimeUnit.SECOND ) ) {
|
---|
112 | setMaxWaitUnit( TimeUnit.SECOND_UNIT );
|
---|
113 | return ;
|
---|
114 | }
|
---|
115 | if ( unit.equals( TimeUnit.MILLISECOND ) ) {
|
---|
116 | setMaxWaitUnit( TimeUnit.MILLISECOND_UNIT );
|
---|
117 | return ;
|
---|
118 | }
|
---|
119 | if ( unit.equals( TimeUnit.MINUTE ) ) {
|
---|
120 | setMaxWaitUnit( TimeUnit.MINUTE_UNIT );
|
---|
121 | return ;
|
---|
122 | }
|
---|
123 | if ( unit.equals( TimeUnit.HOUR ) ) {
|
---|
124 | setMaxWaitUnit( TimeUnit.HOUR_UNIT );
|
---|
125 | return ;
|
---|
126 | }
|
---|
127 | if ( unit.equals( TimeUnit.DAY ) ) {
|
---|
128 | setMaxWaitUnit( TimeUnit.DAY_UNIT );
|
---|
129 | return ;
|
---|
130 | }
|
---|
131 | if ( unit.equals( TimeUnit.WEEK ) ) {
|
---|
132 | setMaxWaitUnit( TimeUnit.WEEK_UNIT );
|
---|
133 | return ;
|
---|
134 | }
|
---|
135 |
|
---|
136 | }
|
---|
137 |
|
---|
138 | /**
|
---|
139 | * Set a millisecond wait value.
|
---|
140 | * @param value the number of milliseconds to wait.
|
---|
141 | */
|
---|
142 | public void setMilliseconds( int value ) {
|
---|
143 | setMaxwait( value );
|
---|
144 | setMaxWaitUnit( TimeUnit.MILLISECOND_UNIT );
|
---|
145 | }
|
---|
146 |
|
---|
147 | /**
|
---|
148 | * Set a second wait value.
|
---|
149 | * @param value the number of seconds to wait.
|
---|
150 | */
|
---|
151 | public void setSeconds( int value ) {
|
---|
152 | setMaxwait( value );
|
---|
153 | setMaxWaitUnit( TimeUnit.SECOND_UNIT );
|
---|
154 | }
|
---|
155 |
|
---|
156 | /**
|
---|
157 | * Set a minute wait value.
|
---|
158 | * @param value the number of milliseconds to wait.
|
---|
159 | */
|
---|
160 | public void setMinutes( int value ) {
|
---|
161 | setMaxwait( value );
|
---|
162 | setMaxWaitUnit( TimeUnit.MINUTE_UNIT );
|
---|
163 | }
|
---|
164 |
|
---|
165 | /**
|
---|
166 | * Set an hours wait value.
|
---|
167 | * @param value the number of hours to wait.
|
---|
168 | */
|
---|
169 | public void setHours( int value ) {
|
---|
170 | setMaxwait( value );
|
---|
171 | setMaxWaitUnit( TimeUnit.HOUR_UNIT );
|
---|
172 | }
|
---|
173 |
|
---|
174 | /**
|
---|
175 | * Set a day wait value.
|
---|
176 | * @param value the number of days to wait.
|
---|
177 | */
|
---|
178 | public void setDays( int value ) {
|
---|
179 | setMaxwait( value );
|
---|
180 | setMaxWaitUnit( TimeUnit.DAY_UNIT );
|
---|
181 | }
|
---|
182 |
|
---|
183 | /**
|
---|
184 | * Set a week wait value.
|
---|
185 | * @param value the number of weeks to wait.
|
---|
186 | */
|
---|
187 | public void setWeeks( int value ) {
|
---|
188 | setMaxwait( value );
|
---|
189 | setMaxWaitUnit( TimeUnit.WEEK_UNIT );
|
---|
190 | }
|
---|
191 |
|
---|
192 | /**
|
---|
193 | * Set the max wait time unit, default is minutes.
|
---|
194 | */
|
---|
195 | public void setMaxWaitUnit( TimeUnit unit ) {
|
---|
196 | this.unit = unit;
|
---|
197 | }
|
---|
198 |
|
---|
199 |
|
---|
200 | /**
|
---|
201 | * Determines whether the build should fail if the time limit has
|
---|
202 | * expired on this task.
|
---|
203 | * Default is no.
|
---|
204 | *
|
---|
205 | * @param fail if true, fail the build if the time limit has been reached.
|
---|
206 | */
|
---|
207 | public void setFailonerror( boolean fail ) {
|
---|
208 | failOnError = fail;
|
---|
209 | }
|
---|
210 |
|
---|
211 |
|
---|
212 | /**
|
---|
213 | * Name the property to set after a timeout.
|
---|
214 | *
|
---|
215 | * @param p of property to set if the time limit has been reached.
|
---|
216 | */
|
---|
217 | public void setProperty( String p ) {
|
---|
218 | timeoutProperty = p;
|
---|
219 | }
|
---|
220 |
|
---|
221 |
|
---|
222 | /**
|
---|
223 | * The value for the property to set after a timeout, defaults to true.
|
---|
224 | *
|
---|
225 | * @param v for the property to set if the time limit has been reached.
|
---|
226 | */
|
---|
227 | public void setValue( String v ) {
|
---|
228 | timeoutValue = v;
|
---|
229 | }
|
---|
230 |
|
---|
231 |
|
---|
232 | /**
|
---|
233 | * Execute all nested tasks, but stopping execution of nested tasks after
|
---|
234 | * maxwait or when all tasks are done, whichever is first.
|
---|
235 | *
|
---|
236 | * @exception BuildException Description of the Exception
|
---|
237 | */
|
---|
238 | public void execute() throws BuildException {
|
---|
239 | try {
|
---|
240 | // start executing nested tasks
|
---|
241 | final Thread runner =
|
---|
242 | new Thread() {
|
---|
243 | public void run() {
|
---|
244 | Enumeration e = tasks.elements();
|
---|
245 | while ( e.hasMoreElements() ) {
|
---|
246 | if ( taskRunner != this ) {
|
---|
247 | break;
|
---|
248 | }
|
---|
249 | currentTask = ( Task ) e.nextElement();
|
---|
250 | try {
|
---|
251 | currentTask.perform();
|
---|
252 | }
|
---|
253 | catch ( Exception ex ) {
|
---|
254 | if ( failOnError ) {
|
---|
255 | exception = ex;
|
---|
256 | return ;
|
---|
257 | }
|
---|
258 | else {
|
---|
259 | exception = ex;
|
---|
260 | }
|
---|
261 | }
|
---|
262 | }
|
---|
263 | }
|
---|
264 | };
|
---|
265 | taskRunner = runner;
|
---|
266 | runner.start();
|
---|
267 | runner.join( unit.toMillis( maxwait ) );
|
---|
268 |
|
---|
269 |
|
---|
270 | // stop executing the nested tasks
|
---|
271 | if ( runner.isAlive() ) {
|
---|
272 | taskRunner = null;
|
---|
273 | runner.interrupt();
|
---|
274 | int index = tasks.indexOf( currentTask );
|
---|
275 | StringBuffer not_ran = new StringBuffer();
|
---|
276 | for ( int i = index + 1; i < tasks.size(); i++ ) {
|
---|
277 | not_ran.append( '<' ).append( ( ( Task ) tasks.get( i ) ).getTaskName() ).append( '>' );
|
---|
278 | if ( i < tasks.size() - 1 ) {
|
---|
279 | not_ran.append( ", " );
|
---|
280 | }
|
---|
281 | }
|
---|
282 |
|
---|
283 |
|
---|
284 | // maybe set timeout property
|
---|
285 | if ( timeoutProperty != null ) {
|
---|
286 | getProject().setNewProperty( timeoutProperty, timeoutValue );
|
---|
287 | }
|
---|
288 |
|
---|
289 |
|
---|
290 | // create output message
|
---|
291 | StringBuffer msg = new StringBuffer();
|
---|
292 | msg.append( "Interrupted task <" )
|
---|
293 | .append( currentTask.getTaskName() )
|
---|
294 | .append( ">. Waited " )
|
---|
295 | .append( ( maxwait ) ).append( " " ).append( unit.getValue() )
|
---|
296 | .append( ", but this task did not complete." )
|
---|
297 | .append( ( not_ran.length() > 0 ?
|
---|
298 | " The following tasks did not execute: " + not_ran.toString() + "." :
|
---|
299 | "" ) );
|
---|
300 |
|
---|
301 |
|
---|
302 | // deal with it
|
---|
303 | if ( failOnError ) {
|
---|
304 | throw new BuildException( msg.toString() );
|
---|
305 | }
|
---|
306 | else {
|
---|
307 | log( msg.toString() );
|
---|
308 | }
|
---|
309 | }
|
---|
310 | else if ( failOnError && exception != null ) {
|
---|
311 | throw new BuildException( exception );
|
---|
312 | }
|
---|
313 | }
|
---|
314 | catch ( Exception e ) {
|
---|
315 | throw new BuildException( e );
|
---|
316 | }
|
---|
317 | }
|
---|
318 |
|
---|
319 |
|
---|
320 | }
|
---|
321 |
|
---|
322 |
|
---|
323 |
|
---|