001/* 002 * jDTAUS Core API 003 * Copyright (C) 2005 Christian Schulte 004 * <cs@schulte.it> 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 019 * 020 */ 021package org.jdtaus.core.monitor; 022 023import java.io.Serializable; 024import java.rmi.server.UID; 025import java.util.Comparator; 026import org.jdtaus.core.text.Message; 027 028/** 029 * A task of execution. 030 * <p>A task is a sequence of operations taking time. This class defines 031 * properties to be used by applications to query a task for information and for 032 * canceling a task. Property {@code indeterminate} indicates if a task 033 * supports properties {@code minimum}, {@code maximum} and {@code progress}. 034 * Property {@code cancelable} indicates if a task may be canceled by an 035 * application by setting property {@code cancelled} to {@code true}. 036 * Properties {@code description} and {@code progressDescription} hold 037 * presentation descriptions of a task itself and of the work currently 038 * performed by a task.</p> 039 * 040 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 041 * @version $JDTAUS: Task.java 8743 2012-10-07 03:06:20Z schulte $ 042 * 043 * @see TaskEvent 044 */ 045public abstract class Task implements Cloneable, Serializable 046{ 047 //--Constants--------------------------------------------------------------- 048 049 /** 050 * Comparator for sorting tasks in ascending order of creation time. 051 * <p><b>Note:</b><br/> 052 * This comparator imposes orderings that are inconsistent with equals.</p> 053 */ 054 public static final Comparator ASCENDING = new AscendingTaskComparator(); 055 056 /** 057 * Comparator for sorting tasks in descending order of creation time. 058 * <p><b>Note:</b><br/> 059 * This comparator imposes orderings that are inconsistent with equals.</p> 060 */ 061 public static final Comparator DESCENDING = 062 new DescendingTaskComparator(); 063 064 /** Serial version UID for backwards compatibility with 1.0.x classes. */ 065 private static final long serialVersionUID = -3919376355708819307L; 066 067 //---------------------------------------------------------------Constants-- 068 //--Constructors------------------------------------------------------------ 069 070 /** Creates a new {@code Task} instance. */ 071 public Task() 072 { 073 super(); 074 this.uid = new UID(); 075 this.indeterminate = true; 076 this.timestamp = System.currentTimeMillis(); 077 } 078 079 //------------------------------------------------------------Constructors-- 080 //--Task-------------------------------------------------------------------- 081 082 /** 083 * Unique task identifier. 084 * @serial 085 */ 086 private UID uid; 087 088 /** 089 * The timestamp this task got created. 090 * @serial 091 */ 092 private long timestamp; 093 094 /** 095 * Flag indicating that an application cancelled the task. 096 * @serial 097 */ 098 private boolean cancelled; 099 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 */ 379class 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 */ 433class 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}