1 /*
2 * jDTAUS Core API
3 * Copyright (C) 2005 Christian Schulte
4 * <cs@schulte.it>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21 package org.jdtaus.core.monitor;
22
23 import java.io.Serializable;
24 import java.rmi.server.UID;
25 import java.util.Comparator;
26 import org.jdtaus.core.text.Message;
27
28 /**
29 * A task of execution.
30 * <p>A task is a sequence of operations taking time. This class defines
31 * properties to be used by applications to query a task for information and for
32 * canceling a task. Property {@code indeterminate} indicates if a task
33 * supports properties {@code minimum}, {@code maximum} and {@code progress}.
34 * Property {@code cancelable} indicates if a task may be canceled by an
35 * application by setting property {@code cancelled} to {@code true}.
36 * Properties {@code description} and {@code progressDescription} hold
37 * presentation descriptions of a task itself and of the work currently
38 * performed by a task.</p>
39 *
40 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
41 * @version $JDTAUS: Task.java 8743 2012-10-07 03:06:20Z schulte $
42 *
43 * @see TaskEvent
44 */
45 public abstract class Task implements Cloneable, Serializable
46 {
47 //--Constants---------------------------------------------------------------
48
49 /**
50 * Comparator for sorting tasks in ascending order of creation time.
51 * <p><b>Note:</b><br/>
52 * This comparator imposes orderings that are inconsistent with equals.</p>
53 */
54 public static final Comparator ASCENDING = new AscendingTaskComparator();
55
56 /**
57 * Comparator for sorting tasks in descending order of creation time.
58 * <p><b>Note:</b><br/>
59 * This comparator imposes orderings that are inconsistent with equals.</p>
60 */
61 public static final Comparator DESCENDING =
62 new DescendingTaskComparator();
63
64 /** Serial version UID for backwards compatibility with 1.0.x classes. */
65 private static final long serialVersionUID = -3919376355708819307L;
66
67 //---------------------------------------------------------------Constants--
68 //--Constructors------------------------------------------------------------
69
70 /** Creates a new {@code Task} instance. */
71 public Task()
72 {
73 super();
74 this.uid = new UID();
75 this.indeterminate = true;
76 this.timestamp = System.currentTimeMillis();
77 }
78
79 //------------------------------------------------------------Constructors--
80 //--Task--------------------------------------------------------------------
81
82 /**
83 * Unique task identifier.
84 * @serial
85 */
86 private UID uid;
87
88 /**
89 * The timestamp this task got created.
90 * @serial
91 */
92 private long timestamp;
93
94 /**
95 * Flag indicating that an application cancelled the task.
96 * @serial
97 */
98 private boolean cancelled;
99
100 /**
101 * Description of the {@code Task}.
102 * @serial
103 */
104 protected Message description;
105
106 /**
107 * Description of the progress of the {@code Task}.
108 * @serial
109 */
110 protected Message progressDescription;
111
112 /**
113 * The lower bound of the range.
114 * @serial
115 */
116 protected int minimum;
117
118 /**
119 * The upper bound of the range.
120 * @serial
121 */
122 protected int maximum;
123
124 /**
125 * Indicates the progress of the task.
126 * @serial
127 */
128 protected int progress;
129
130 /**
131 * Flag indicating if the operations performed by the task are of unknown
132 * length.
133 * @serial
134 */
135 protected boolean indeterminate;
136
137 /**
138 * Flag indicating that an application may cancel the task.
139 * @serial
140 */
141 protected boolean cancelable;
142
143 /**
144 * Getter for property {@code timestamp}.
145 *
146 * @return the timestamp this task got created.
147 */
148 public final synchronized long getTimestamp()
149 {
150 return this.timestamp;
151 }
152
153 /**
154 * Getter for property {@code description}.
155 *
156 * @return description of the task.
157 */
158 public final synchronized Message getDescription()
159 {
160 return this.description;
161 }
162
163 /**
164 * Getter for property {@code progressDescription}.
165 *
166 * @return description of the progress of the task or {@code null}.
167 */
168 public final synchronized Message getProgressDescription()
169 {
170 return this.progressDescription;
171 }
172
173 /**
174 * Gets the lower end of the progress value.
175 *
176 * @return an int representing the minimum value.
177 *
178 * @throws IllegalStateException if the task is indeterminate.
179 */
180 public final synchronized int getMinimum()
181 {
182 if ( this.isIndeterminate() )
183 {
184 throw new IllegalStateException();
185 }
186
187 return this.minimum;
188 }
189
190 /**
191 * Gets the higher end of the progress value.
192 *
193 * @return an int representing the maximum value.
194 *
195 * @throws IllegalStateException if the task is indeterminate.
196 */
197 public final synchronized int getMaximum()
198 {
199 if ( this.isIndeterminate() )
200 {
201 throw new IllegalStateException();
202 }
203
204 return this.maximum;
205 }
206
207 /**
208 * Gets the progress of the task.
209 *
210 * @return the progress of the task.
211 *
212 * @throws IllegalStateException if the task is indeterminate.
213 */
214 public final synchronized int getProgress()
215 {
216 if ( this.isIndeterminate() )
217 {
218 throw new IllegalStateException();
219 }
220
221 return this.progress;
222 }
223
224 /**
225 * Flag indicating if the task supports properties {@code minimum},
226 * {@code maximum} and {@code progress}.
227 *
228 * @return {@code true} if the operations performed by the task are of
229 * unknown length; {@code false} if properties {@code minimum},
230 * {@code maximum} and {@code progress} hold progress information.
231 */
232 public final synchronized boolean isIndeterminate()
233 {
234 return this.indeterminate;
235 }
236
237 /**
238 * Flag indicating that the task supports property {@code cancelled}.
239 *
240 * @return {@code true} if the task supports property {@code cancelled};
241 * {@code false} if property {@code cancelled} is ignored by the task.
242 */
243 public final synchronized boolean isCancelable()
244 {
245 return this.cancelable;
246 }
247
248 /**
249 * Flag indicating that the task is canceled.
250 *
251 * @return {@code true} if the task is canceled; {@code false} else.
252 *
253 * @throws IllegalStateException if the task is not cancelable.
254 */
255 public final synchronized boolean isCancelled()
256 {
257 if ( !this.isCancelable() )
258 {
259 throw new IllegalStateException();
260 }
261
262 return this.cancelled;
263 }
264
265 /**
266 * Setter for property {@code cancelled}.
267 * <p>Applications may request cancellation of a {@code Task} by setting
268 * property {@code cancelled} to {@code true}. Implementations indicate
269 * support for task cancellation by property {@code cancelable}.</p>
270 *
271 * @param value {@code true} to cancel the task; {@code false} else.
272 *
273 * @throws IllegalStateException if the task is not cancelable or is already
274 * canceled.
275 */
276 public final synchronized void setCancelled( final boolean value )
277 {
278 if ( !this.isCancelable() || this.isCancelled() )
279 {
280 throw new IllegalStateException();
281 }
282
283 this.cancelled = value;
284 }
285
286 /**
287 * Creates a string representing the properties of the instance.
288 *
289 * @return a string representing the properties of the instance.
290 */
291 private String internalString()
292 {
293 return new StringBuffer( 500 ).append( '{' ).
294 append( "uid=" ).append( this.uid ).
295 append( ", indeterminate=" ).append( this.indeterminate ).
296 append( ", cancelable=" ).append( this.cancelable ).
297 append( ", cancelled=" ).append( this.cancelled ).
298 append( ", maximum=" ).append( this.maximum ).
299 append( ", minimum=" ).append( this.minimum ).
300 append( ", progress=" ).append( this.progress ).
301 append( ", description=" ).append( this.description ).
302 append( ", progressDescription=" ).
303 append( this.progressDescription ).
304 append( ", timestamp=" ).append( this.timestamp ).
305 append( '}' ).toString();
306
307 }
308
309 //--------------------------------------------------------------------Task--
310 //--Object------------------------------------------------------------------
311
312 /**
313 * Returns a string representation of the object.
314 *
315 * @return a string representation of the object.
316 */
317 public String toString()
318 {
319 return super.toString() + this.internalString();
320 }
321
322 /**
323 * Returns a hash code value for this object.
324 *
325 * @return a hash code value for this object.
326 */
327 public final int hashCode()
328 {
329 return this.uid.hashCode();
330 }
331
332 /**
333 * Indicates whether some other object is equal to this one.
334 * <p>Tasks internally cary a UID which is created during instantiation.
335 * This UID is used for comparing {@code o} with the instance.</p>
336 *
337 * @param o the reference object with which to compare.
338 *
339 * @return {@code true} if this object is the same as {@code o};
340 * {@code false} otherwise.
341 *
342 * @see UID
343 */
344 public final boolean equals( final Object o )
345 {
346 return o == this || ( o instanceof Task &&
347 ( (Task) o ).uid.equals( this.uid ) );
348
349 }
350
351 /**
352 * Creates and returns a copy of this object.
353 *
354 * @return a clone of this instance.
355 */
356 public Object clone()
357 {
358 try
359 {
360 return super.clone();
361 }
362 catch ( final CloneNotSupportedException e )
363 {
364 throw new AssertionError( e );
365 }
366 }
367
368 //------------------------------------------------------------------Object--
369 }
370
371 /**
372 * Comparator for sorting tasks in ascending order of creation time.
373 * <p><b>Note:</b><br/>
374 * This comparator imposes orderings that are inconsistent with equals.</p>
375 *
376 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
377 * @version $JDTAUS: Task.java 8743 2012-10-07 03:06:20Z schulte $
378 */
379 class AscendingTaskComparator implements Comparator, Serializable
380 {
381 /** Creates a new {@code AscendingTaskComparator} instance. */
382 AscendingTaskComparator()
383 {
384 super();
385 }
386
387 //--Comparator--------------------------------------------------------------
388
389 /**
390 * {@inheritDoc}
391 *
392 * @throws NullPointerException if either {@code o1} or {@code o2} is
393 * {@code null}.
394 * @throws ClassCastException if either {@code o1} or {@code o2} is not an
395 * instance of {@code Task}.
396 */
397 public int compare( final Object o1, final Object o2 )
398 {
399 if ( o1 == null )
400 {
401 throw new NullPointerException( "o1" );
402 }
403 if ( o2 == null )
404 {
405 throw new NullPointerException( "o2" );
406 }
407 if ( !( o1 instanceof Task ) )
408 {
409 throw new ClassCastException( o1.getClass().getName() );
410 }
411 if ( !( o2 instanceof Task ) )
412 {
413 throw new ClassCastException( o2.getClass().getName() );
414 }
415
416 // TODO JDK 1.5 Long.valueOf(long)
417 final Long l1 = new Long( ( (Task) o1 ).getTimestamp() );
418 final Long l2 = new Long( ( (Task) o2 ).getTimestamp() );
419 return l1.compareTo( l2 );
420 }
421
422 //--------------------------------------------------------------Comparator--
423 }
424
425 /**
426 * Comparator for sorting tasks in descending order of creation time.
427 * <p><b>Note:</b><br/>
428 * This comparator imposes orderings that are inconsistent with equals.</p>
429 *
430 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
431 * @version $JDTAUS: Task.java 8743 2012-10-07 03:06:20Z schulte $
432 */
433 class DescendingTaskComparator
434 extends AscendingTaskComparator
435 {
436
437 /** Creates a new {@code DescendingTaskComparator} instance. */
438 DescendingTaskComparator()
439 {
440 super();
441 }
442
443 //--Comparator--------------------------------------------------------------
444
445 /**
446 * {@inheritDoc}
447 *
448 * @throws NullPointerException if either {@code o1} or {@code o2} is
449 * {@code null}.
450 * @throws ClassCastException if either {@code o1} or {@code o2} is not an
451 * instance of {@code Task}.
452 */
453 public int compare( final Object o1, final Object o2 )
454 {
455 return super.compare( o2, o1 );
456 }
457
458 //--------------------------------------------------------------Comparator--
459 }