Clover coverage report - JFox Service-Oriented Application Framework - 1.0-RC1 Coverage timestamp: 星期五 八月 19 2005 13:21:55 CST FRAMES NO FRAMES |
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% |

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 |  |
     }