001 /*
002 * jDTAUS Core API
003 * Copyright (c) 2005 Christian Schulte
004 *
005 * Christian Schulte, Haldener Strasse 72, 58095 Hagen, Germany
006 * <schulte2005@users.sourceforge.net> (+49 2331 3543887)
007 *
008 * This library is free software; you can redistribute it and/or
009 * modify it under the terms of the GNU Lesser General Public
010 * License as published by the Free Software Foundation; either
011 * version 2.1 of the License, or any later version.
012 *
013 * This library is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016 * Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public
019 * License along with this library; if not, write to the Free Software
020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
021 *
022 */
023 package org.jdtaus.core.monitor;
024
025 import java.io.Serializable;
026 import java.rmi.server.UID;
027 import java.util.Comparator;
028 import org.jdtaus.core.text.Message;
029
030 /**
031 * A task of execution.
032 * <p>A task is a sequence of operations taking time. This class defines
033 * properties to be used by applications to query a task for information and for
034 * cancelling a task. Property {@code indeterminate} indicates if a task
035 * supports properties {@code minimum}, {@code maximum} and {@code progress}.
036 * Property {@code cancelable} indicates if a task may be cancelled by an
037 * application by setting property {@code cancelled} to {@code true}.
038 * Properties {@code description} and {@code progressDescription} hold
039 * presentation descriptions of a task itself and of the work currently
040 * performed by a task.</p>
041 *
042 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
043 * @version $Id: Task.java 8044 2009-07-02 01:29:05Z schulte2005 $
044 *
045 * @see TaskEvent
046 */
047 public abstract class Task implements Cloneable, Serializable
048 {
049 //--Constants---------------------------------------------------------------
050
051 /**
052 * Comparator for sorting tasks in ascending order of creation time.
053 * <p><b>Note:</b><br/>
054 * This comparator imposes orderings that are inconsistent with equals.</p>
055 */
056 public static final Comparator ASCENDING = new AscendingTaskComparator();
057
058 /**
059 * Comparator for sorting tasks in descending order of creation time.
060 * <p><b>Note:</b><br/>
061 * This comparator imposes orderings that are inconsistent with equals.</p>
062 */
063 public static final Comparator DESCENDING =
064 new DescendingTaskComparator();
065
066 /** Serial version UID for backwards compatibility with 1.0.x classes. */
067 private static final long serialVersionUID = -3919376355708819307L;
068
069 //---------------------------------------------------------------Constants--
070 //--Constructors------------------------------------------------------------
071
072 /** Creates a new {@code Task} instance. */
073 public Task()
074 {
075 super();
076 this.uid = new UID();
077 this.indeterminate = true;
078 this.timestamp = System.currentTimeMillis();
079 }
080
081 //------------------------------------------------------------Constructors--
082 //--Task--------------------------------------------------------------------
083
084 /**
085 * Unique task identifier.
086 * @serial
087 */
088 private UID uid;
089
090 /**
091 * The timestamp this task got created.
092 * @serial
093 */
094 private long timestamp;
095
096 /**
097 * Flag indicating that an application cancelled the task.
098 * @serial
099 */
100 private boolean cancelled;
101
102 /**
103 * Description of the {@code Task}.
104 * @serial
105 */
106 protected Message description;
107
108 /**
109 * Description of the progress of the {@code Task}.
110 * @serial
111 */
112 protected Message progressDescription;
113
114 /**
115 * The lower bound of the range.
116 * @serial
117 */
118 protected int minimum;
119
120 /**
121 * The upper bound of the range.
122 * @serial
123 */
124 protected int maximum;
125
126 /**
127 * Indicates the progress of the task.
128 * @serial
129 */
130 protected int progress;
131
132 /**
133 * Flag indicating if the operations performed by the task are of unknown
134 * length.
135 * @serial
136 */
137 protected boolean indeterminate;
138
139 /**
140 * Flag indicating that an application may cancel the task.
141 * @serial
142 */
143 protected boolean cancelable;
144
145 /**
146 * Getter for property {@code timestamp}.
147 *
148 * @return the timestamp this task got created.
149 */
150 synchronized public final long getTimestamp()
151 {
152 return this.timestamp;
153 }
154
155 /**
156 * Getter for property {@code description}.
157 *
158 * @return description of the task.
159 */
160 synchronized public final Message getDescription()
161 {
162 return this.description;
163 }
164
165 /**
166 * Getter for property {@code progressDescription}.
167 *
168 * @return description of the progress of the task or {@code null}.
169 */
170 synchronized public final Message getProgressDescription()
171 {
172 return this.progressDescription;
173 }
174
175 /**
176 * Gets the lower end of the progress value.
177 *
178 * @return an int representing the minimum value.
179 *
180 * @throws IllegalStateException if the task is indeterminate.
181 */
182 synchronized public final int getMinimum()
183 {
184 if ( this.isIndeterminate() )
185 {
186 throw new IllegalStateException();
187 }
188
189 return this.minimum;
190 }
191
192 /**
193 * Gets the higher end of the progress value.
194 *
195 * @return an int representing the maximum value.
196 *
197 * @throws IllegalStateException if the task is indeterminate.
198 */
199 synchronized public final int getMaximum()
200 {
201 if ( this.isIndeterminate() )
202 {
203 throw new IllegalStateException();
204 }
205
206 return this.maximum;
207 }
208
209 /**
210 * Gets the progress of the task.
211 *
212 * @return the progress of the task.
213 *
214 * @throws IllegalStateException if the task is indeterminate.
215 */
216 synchronized public final int getProgress()
217 {
218 if ( this.isIndeterminate() )
219 {
220 throw new IllegalStateException();
221 }
222
223 return this.progress;
224 }
225
226 /**
227 * Flag indicating if the task supports properties {@code minimum},
228 * {@code maximum} and {@code progress}.
229 *
230 * @return {@code true} if the operations performed by the task are of
231 * unknown length; {@code false} if properties {@code minimum},
232 * {@code maximum} and {@code progress} hold progress information.
233 */
234 synchronized public final boolean isIndeterminate()
235 {
236 return this.indeterminate;
237 }
238
239 /**
240 * Flag indicating that the task supports property {@code cancelled}.
241 *
242 * @return {@code true} if the task supports property {@code cancelled};
243 * {@code false} if property {@code cancelled} is ignored by the task.
244 */
245 synchronized public final boolean isCancelable()
246 {
247 return this.cancelable;
248 }
249
250 /**
251 * Flag indicating that the task is cancelled.
252 *
253 * @return {@code true} if the task is cancelled; {@code false} else.
254 *
255 * @throws IllegalStateException if the task is not cancelable.
256 */
257 synchronized public final boolean isCancelled()
258 {
259 if ( !this.isCancelable() )
260 {
261 throw new IllegalStateException();
262 }
263
264 return this.cancelled;
265 }
266
267 /**
268 * Setter for property {@code cancelled}.
269 * <p>Applications may request cancellation of a {@code Task} by setting
270 * property {@code cancelled} to {@code true}. Implementations indicate
271 * theire support for task cancellation by property {@code cancelable}.</p>
272 *
273 * @param value {@code true} to cancel the task; {@code false} else.
274 *
275 * @throws IllegalStateException if the task is not cancelable or is already
276 * cancelled.
277 */
278 synchronized public final void setCancelled( final boolean value )
279 {
280 if ( !this.isCancelable() || this.isCancelled() )
281 {
282 throw new IllegalStateException();
283 }
284
285 this.cancelled = value;
286 }
287
288 /**
289 * Creates a string representing the properties of the instance.
290 *
291 * @return a string representing the properties of the instance.
292 */
293 private String internalString()
294 {
295 return new StringBuffer( 500 ).append( '{' ).
296 append( "uid=" ).append( this.uid ).
297 append( ", indeterminate=" ).append( this.indeterminate ).
298 append( ", cancelable=" ).append( this.cancelable ).
299 append( ", cancelled=" ).append( this.cancelled ).
300 append( ", maximum=" ).append( this.maximum ).
301 append( ", minimum=" ).append( this.minimum ).
302 append( ", progress=" ).append( this.progress ).
303 append( ", description=" ).append( this.description ).
304 append( ", progressDescription=" ).
305 append( this.progressDescription ).
306 append( ", timestamp=" ).append( this.timestamp ).
307 append( '}' ).toString();
308
309 }
310
311 //--------------------------------------------------------------------Task--
312 //--Object------------------------------------------------------------------
313
314 /**
315 * Returns a string representation of the object.
316 *
317 * @return a string representation of the object.
318 */
319 public String toString()
320 {
321 return super.toString() + this.internalString();
322 }
323
324 /**
325 * Returns a hash code value for this object.
326 *
327 * @return a hash code value for this object.
328 */
329 public final int hashCode()
330 {
331 return this.uid.hashCode();
332 }
333
334 /**
335 * Indicates whether some other object is equal to this one.
336 * <p>Tasks internally cary a UID which is created during instantiation.
337 * This UID is used for comparing {@code o} with the instance.</p>
338 *
339 * @param o the reference object with which to compare.
340 *
341 * @return {@code true} if this object is the same as {@code o};
342 * {@code false} otherwise.
343 *
344 * @see UID
345 */
346 public final boolean equals( final Object o )
347 {
348 return o == this || ( o instanceof Task &&
349 ( (Task) o ).uid.equals( this.uid ) );
350
351 }
352
353 /**
354 * Creates and returns a copy of this object.
355 *
356 * @return a clone of this instance.
357 */
358 public Object clone()
359 {
360 try
361 {
362 return super.clone();
363 }
364 catch ( CloneNotSupportedException e )
365 {
366 throw new AssertionError( e );
367 }
368 }
369
370 //------------------------------------------------------------------Object--
371 }
372
373 /**
374 * Comparator for sorting tasks in ascending order of creation time.
375 * <p><b>Note:</b><br/>
376 * This comparator imposes orderings that are inconsistent with equals.</p>
377 *
378 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
379 * @version $Id: Task.java 8044 2009-07-02 01:29:05Z schulte2005 $
380 */
381 class AscendingTaskComparator implements Comparator, Serializable
382 {
383 //--Comparator--------------------------------------------------------------
384
385 /**
386 * {@inheritDoc}
387 *
388 * @throws NullPointerException if either {@code o1} or {@code o2} is
389 * {@code null}.
390 * @throws ClassCastException if either {@code o1} or {@code o2} is not an
391 * instance of {@code Task}.
392 */
393 public int compare( final Object o1, final Object o2 )
394 {
395 if ( o1 == null )
396 {
397 throw new NullPointerException( "o1" );
398 }
399 if ( o2 == null )
400 {
401 throw new NullPointerException( "o2" );
402 }
403 if ( !( o1 instanceof Task ) )
404 {
405 throw new ClassCastException( o1.getClass().getName() );
406 }
407 if ( !( o2 instanceof Task ) )
408 {
409 throw new ClassCastException( o2.getClass().getName() );
410 }
411
412 // TODO JDK 1.5 Long.valueOf(long)
413 final Long l1 = new Long( ( (Task) o1 ).getTimestamp() );
414 final Long l2 = new Long( ( (Task) o2 ).getTimestamp() );
415 return l1.compareTo( l2 );
416 }
417
418 //--------------------------------------------------------------Comparator--
419 }
420
421 /**
422 * Comparator for sorting tasks in descending order of creation time.
423 * <p><b>Note:</b><br/>
424 * This comparator imposes orderings that are inconsistent with equals.</p>
425 *
426 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
427 * @version $Id: Task.java 8044 2009-07-02 01:29:05Z schulte2005 $
428 */
429 class DescendingTaskComparator
430 extends AscendingTaskComparator
431 {
432 //--Comparator--------------------------------------------------------------
433
434 /**
435 * {@inheritDoc}
436 *
437 * @throws NullPointerException if either {@code o1} or {@code o2} is
438 * {@code null}.
439 * @throws ClassCastException if either {@code o1} or {@code o2} is not an
440 * instance of {@code Task}.
441 */
442 public int compare( final Object o1, final Object o2 )
443 {
444 return super.compare( o2, o1 );
445 }
446
447 //--------------------------------------------------------------Comparator--
448 }