001package com.hfg.util;
002
003import java.util.concurrent.Callable;
004import java.util.concurrent.FutureTask;
005
006import com.hfg.exception.InvalidValueException;
007
008//------------------------------------------------------------------------------
009/**
010 * A FutureTask that allows a priority to be specified.
011 *
012 * @author J. Alex Taylor, hairyfatguy.com
013 */
014//------------------------------------------------------------------------------
015// com.hfg XML/HTML Coding Library
016//
017// This library is free software; you can redistribute it and/or
018// modify it under the terms of the GNU Lesser General Public
019// License as published by the Free Software Foundation; either
020// version 2.1 of the License, or (at your option) any later version.
021//
022// This library is distributed in the hope that it will be useful,
023// but WITHOUT ANY WARRANTY; without even the implied warranty of
024// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
025// Lesser General Public License for more details.
026//
027// You should have received a copy of the GNU Lesser General Public
028// License along with this library; if not, write to the Free Software
029// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030//
031// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
032// jataylor@hairyfatguy.com
033//------------------------------------------------------------------------------
034
035public class PrioritizedFutureTask<V> extends FutureTask<V> implements Comparable<PrioritizedFutureTask<V>>
036{
037   private Priority mPriority = Priority.MEDIUM;
038   private long mSubmissionTime;
039
040   //--------------------------------------------------------------------------
041   /**
042    * Creates a {@code PrioritizedFutureTask} that will, upon running, execute the
043    * given {@code Callable}.
044    *
045    * @param  inCallable the callable task
046    * @throws NullPointerException if the callable is null
047    */
048   public PrioritizedFutureTask(Callable<V> inCallable)
049   {
050      super(inCallable);
051      init();
052   }
053
054   //--------------------------------------------------------------------------
055   /**
056    * Creates a {@code PrioritizedFutureTask} that will, upon running, execute the
057    * given {@code Runnable}, and arrange that {@code get} will return the
058    * given result on successful completion.
059    *
060    * @param inRunnable the runnable task
061    * @param inResult the result to return on successful completion. If
062    * you don't need a particular result, consider using
063    * constructions of the form:
064    * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
065    * @throws NullPointerException if the runnable is null
066    */
067   public PrioritizedFutureTask(Runnable inRunnable, V inResult)
068   {
069      super(inRunnable, inResult);
070      init();
071   }
072
073   private void init()
074   {
075      mSubmissionTime = System.currentTimeMillis();
076   }
077
078   //--------------------------------------------------------------------------
079   public PrioritizedFutureTask<V> setPriority(Priority inValue)
080   {
081      if (null == inValue)
082      {
083         throw new InvalidValueException("The priority cannot be set to null!");
084      }
085
086      mPriority = inValue;
087      return this;
088   }
089
090   //--------------------------------------------------------------------------
091   public Priority getPriority()
092   {
093      return mPriority;
094   }
095
096   //--------------------------------------------------------------------------
097   public long getSubmissionTime()
098   {
099      return mSubmissionTime;
100   }
101
102   //--------------------------------------------------------------------------
103   @Override
104   public boolean equals(Object inObj2)
105   {
106      return (inObj2 instanceof PrioritizedFutureTask
107              && 0 == compareTo((PrioritizedFutureTask) inObj2));
108   }
109
110   //--------------------------------------------------------------------------
111   @Override
112   public int hashCode()
113   {
114      return getPriority().hashCode() + Long.hashCode(getSubmissionTime());
115   }
116
117   //--------------------------------------------------------------------------
118   @Override
119   public int compareTo(PrioritizedFutureTask<V> inObj2)
120   {
121      int result = -1;
122
123      if (inObj2 != null)
124      {
125         result = CompareUtil.compare(getPriority().ordinal(), inObj2.getPriority().ordinal());
126
127         if (0 == result)
128         {
129            // This will maintain the FIFO ordering within a priority grouping
130            result = CompareUtil.compare(getSubmissionTime(), inObj2.getSubmissionTime());
131         }
132      }
133
134      return result;
135   }
136}