Clover coverage report - JFox Service-Oriented Application Framework - 1.0-RC1
Coverage timestamp: 星期五 八月 19 2005 13:21:55 CST
file stats: LOC: 278   Methods: 13
NCLOC: 127   Classes: 2
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
SimpleTimerServiceImpl.java 0% 0% 0% 0%
coverage
 1   
 /**
 2   
  * @(#)TaskScheduler.java
 3   
  * 
 4   
  * JFoxSOAF, Service-Oriented Application Framework
 5   
  * 
 6   
  * Copyright(c) JFoxSOAF Team
 7   
  * 
 8   
  * Licensed under the GNU LGPL, Version 2.1 (the "License"); 
 9   
  * you may not use this file except in compliance with the License. 
 10   
  * You may obtain a copy of the License at  
 11   
  * 
 12   
  * http://www.gnu.org/copyleft/lesser.html
 13   
  * 
 14   
  * Unless required by applicable law or agreed to in writing, software
 15   
  * distributed under the License is distributed on an "AS IS" BASIS, 
 16   
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 17   
  * See the License for the specific language governing permissions and 
 18   
  * limitations under the License. 
 19   
  * 
 20   
  * For more information, please visit:
 21   
  * http://www.jfox.cn/confluence/display/JFoxSOAF/Home
 22   
  * http://www.huihoo.org/jfox/jfoxsoaf
 23   
  */
 24   
 
 25   
 package org.huihoo.jfox.soaf.services.timer;
 26   
 
 27   
 import java.util.ArrayList;
 28   
 import java.util.Date;
 29   
 import java.util.Timer;
 30   
 import java.util.TimerTask;
 31   
 
 32   
 /**
 33   
  * Class for running Tasks with scheduling/thread pooling etc. <br>
 34   
  * <p>
 35   
  * The tasks are Task objects. A user would extend the Task class and override
 36   
  * the abstract methods ( e.g. its run() method ).
 37   
  * </p>
 38   
  * <p>
 39   
  * Persistence of the Task objects allows the TaskScheduler to be shutdown and
 40   
  * restarted with all the scheduled tasks read from storage.
 41   
  * </p>
 42   
  * 
 43   
  * @author <a href="mailto:founder_chen@yahoo.com.cn">Peter Cheng </a>
 44   
  * @author <a href="mailto:berkovichnyc@hotmail.com">Efraim Berkovich </a>
 45   
  * @version $Revision: 1.1 $ $Date: 2005/05/22 06:52:07 $
 46   
  * @version Revision: 1.0
 47   
  */
 48   
 
 49   
 public class SimpleTimerServiceImpl implements SimpleTimerService {
 50   
 
 51   
     // instance variables
 52   
     private Timer schedulerThread;
 53   
 
 54   
     private ArrayList taskList;
 55   
 
 56   
     private long initTime;
 57   
 
 58   
     private TaskPersistStrategy persistStrategy = null;
 59   
 
 60   
     //  static variables
 61   
     private static Boolean semaphore = new Boolean(true);
 62   
 
 63   
     /**
 64   
      * Shutdown the scheduler
 65   
      */
 66  0
     public void shutdown() {
 67  0
         synchronized (semaphore) {
 68  0
             this.schedulerThread.cancel();
 69   
         }
 70   
     }
 71   
 
 72   
     /**
 73   
      * Create a task scheduler with a default thread pool size.
 74   
      */
 75  0
     public SimpleTimerServiceImpl() {
 76  0
         schedulerThread = new Timer(false);
 77  0
         initTime = System.currentTimeMillis();
 78  0
         taskList = new ArrayList();
 79   
     }
 80   
 
 81   
     /**
 82   
      * Set the particular methodology for persisting Tasks
 83   
      * 
 84   
      * @param strategy The TaskPersistStrategy to use
 85   
      */
 86  0
     public void setPersistStrategy(TaskPersistStrategy strategy) {
 87  0
         synchronized (this) {
 88  0
             persistStrategy = strategy;
 89   
         }
 90   
     }
 91   
 
 92   
     /**
 93   
      * Get the time the TaskScheduler was started.
 94   
      * 
 95   
      * @return the time (in millis) when the Scheduler was started.
 96   
      */
 97  0
     public long getSchedulerStartTime() {
 98  0
         return initTime;
 99   
     }
 100   
 
 101   
     /**
 102   
      * Schedules the specified task for execution according to the task's
 103   
      * scheduling properties.
 104   
      * 
 105   
      * @param task The task to schedule for execution.
 106   
      * @exception IllegalStateException if task was already scheduled or
 107   
      *                cancelled, timer was cancelled, or timer thread
 108   
      *                terminated.
 109   
      * @exception Exception if cannot persist task
 110   
      */
 111  0
     public void schedule(Task task) throws IllegalStateException, Exception {
 112  0
         synchronized (this) {
 113  0
             cleanupAll();
 114  0
             if (taskList.contains(task))
 115  0
                 throw new IllegalStateException("Task was already scheduled");
 116   
 
 117  0
             Date time = new Date(task.getScheduledFirstTime());
 118   
 
 119  0
             RunTask runTask = new RunTask(task);
 120   
 
 121  0
             if (task.getScheduledInterval() <= 0) {
 122  0
                 schedulerThread.schedule(runTask, time);
 123   
             } else {
 124  0
                 schedulerThread.scheduleAtFixedRate(runTask, time, task
 125   
                         .getScheduledInterval());
 126   
             }
 127   
 
 128  0
             task.scheduler = this;
 129  0
             taskList.add(task);
 130   
 
 131  0
             this.persist(task);
 132   
         }
 133   
     }
 134   
 
 135   
     /**
 136   
      * Cancel all executing tasks and timer threads.
 137   
      * 
 138   
      * @param withRestart if true, all timer threads will restart; however, all
 139   
      *            scheduled task will have been cancelled.
 140   
      */
 141  0
     public void cancelAll(boolean withRestart) {
 142  0
         synchronized (this) {
 143  0
             taskList.clear();
 144  0
             schedulerThread.cancel();
 145   
 
 146  0
             if (withRestart)
 147  0
                 schedulerThread = new Timer(false);
 148   
         }
 149   
     }
 150   
 
 151   
     /**
 152   
      * Fetch all non-cancelled tasks at the time the method is called. If tasks
 153   
      * are cancelling during this time, some cancelled tasks may be returned.
 154   
      * 
 155   
      * @return array of Tasks which are not cancelled
 156   
      */
 157  0
     public Task[] getRunningTasks() {
 158  0
         ArrayList list = new ArrayList();
 159  0
         cleanupAll();
 160   
 
 161  0
         synchronized (this) {
 162  0
             for (int i = 0; i < taskList.size(); i++) {
 163  0
                 Task task = (Task) taskList.get(i);
 164  0
                 if (!task.isCancelled()) {
 165  0
                     list.add(task);
 166   
                 }
 167   
             }
 168   
         }
 169  0
         Task[] out = new Task[list.size()];
 170  0
         for (int i = 0; i < out.length; i++)
 171  0
             out[i] = (Task) list.get(i);
 172   
 
 173  0
         return out;
 174   
     }
 175   
 
 176   
     /**
 177   
      * Find a particular task by its ID
 178   
      * 
 179   
      * @param taskID The task to find
 180   
      * @return Task for this ID or null if not found
 181   
      */
 182  0
     public Task findTaskByID(long taskID) {
 183  0
         synchronized (this) {
 184  0
             for (int i = 0; i < taskList.size(); i++) {
 185  0
                 Task task = (Task) taskList.get(i);
 186  0
                 if (task.getID() == taskID) {
 187  0
                     return task;
 188   
                 }
 189   
             }
 190   
         }
 191  0
         return null;
 192   
     }
 193   
 
 194   
     /**
 195   
      * Check and remove a particular task
 196   
      * 
 197   
      * @param Task the potentially cancelled task to remove
 198   
      */
 199  0
     void cleanup(Task task) {
 200  0
         synchronized (this) {
 201  0
             if (taskList.contains(task)) {
 202  0
                 if (task.isCancelled()) {
 203  0
                     taskList.remove(task);
 204  0
                     if (persistStrategy != null)
 205  0
                         persistStrategy.delete(task);
 206   
                 }
 207   
             }
 208   
         }
 209   
     }
 210   
 
 211   
     /**
 212   
      * Persists the task by telling the persist strategy to do so
 213   
      * 
 214   
      * @exception various possible depending on strategy
 215   
      */
 216  0
     void persist(Task task) throws Exception {
 217  0
         synchronized (this) {
 218  0
             if (persistStrategy != null)
 219  0
                 persistStrategy.write(task);
 220   
         }
 221   
     }
 222   
 
 223   
     /**
 224   
      * Go through the taskList and eliminate cancelled tasks
 225   
      */
 226  0
     private void cleanupAll() {
 227  0
         synchronized (this) {
 228  0
             for (int i = 0; i < taskList.size(); i++) {
 229  0
                 Task task = (Task) taskList.get(i);
 230  0
                 if (task.isCancelled()) {
 231  0
                     taskList.remove(i);
 232  0
                     if (persistStrategy != null)
 233  0
                         persistStrategy.delete(task);
 234  0
                     i--;
 235   
                 }
 236   
             }
 237   
         }
 238   
     }
 239   
 
 240   
     /**
 241   
      * RunTask class is scheduler to on the Timer and is associated with a Task
 242   
      * which it runs.
 243   
      */
 244   
     private class RunTask extends TimerTask {
 245   
         // instance variables
 246   
         private Task task;
 247   
 
 248   
         /**
 249   
          * Create a new RunTask
 250   
          * 
 251   
          * @param task The Task to run
 252   
          */
 253  0
         public RunTask(Task task) {
 254  0
             this.task = task;
 255   
         }
 256   
 
 257   
         /**
 258   
          * Run the Task
 259   
          */
 260  0
         public void run() {
 261  0
             if (task.isCancelled()) {
 262  0
                 this.cancel();
 263  0
                 return;
 264   
             }
 265   
 
 266   
             // NOTE: TBD
 267   
             //    For now we just launch a thread to do the task.
 268   
             //    This is potentially not scaleable. In the future,
 269   
             //    we will pick threads from a pool.
 270   
 
 271  0
             Thread runner = new Thread(task);
 272  0
             runner.start();
 273  0
             task.setLastRunTime(System.currentTimeMillis());
 274   
         }
 275   
 
 276   
     }
 277   
 
 278   
 }