1 package org.opensync.schedule;
2
3 import java.io.*;
4 import java.util.*;
5
6
7 /***
8 * The scheduler class is used to schedule <code>Runnable</code> object<p>
9 * It can schedule by date like the cron table of unix system
10 * It also can start a <code>Runnable</code> object on a http request
11 *
12 * @version 1.0
13 * @see SchedulerEntry
14 * @author SOFTMED
15 */
16
17 public class Scheduler implements Serializable, Runnable{
18
19 private boolean exitApp = false;
20
21 public void setExitApp(boolean exitApp) {
22 this.exitApp = exitApp;
23 }
24
25 /***
26 * All the <code>SchedulerEntry</code> schedule by time
27 *
28 */
29 protected TreeSet timeSchedulerEntries = new TreeSet();
30 /***
31 * All the <code>SchedulerEntry</code> schedule by http request
32 *
33 */
34 protected Hashtable schedulerEntries = new Hashtable();
35 /***
36 * The listening port for http request
37 *
38 */
39 protected int httpPort;
40 /***
41 * Construct the Scheduler
42 *
43 * @param httpPort the listening port for http schedule
44 */
45 public Scheduler(int httpPort) {
46 this.httpPort = httpPort;
47 }
48 /***
49 * Start scheduling
50 *
51 * @exception IOException
52 */
53 public void start() throws IOException{
54 new Thread(this).start();
55 new Thread(new HTTPScheduler(this,httpPort)).start();
56 }
57 /***
58 * Add a <code>SchedulerEntry</code>
59 *
60 * @param schedulerEntry the schedulerEntry to add
61 * @see SchedulerEntry
62 */
63 public void addSchedulerEntry(SchedulerEntry schedulerEntry){
64 if(schedulerEntry.isTimeSchedule()){
65 schedulerEntry.setNextTime();
66 synchronized(timeSchedulerEntries){
67 timeSchedulerEntries.add(schedulerEntry);
68 timeSchedulerEntries.notify();
69 }
70 }
71 else{
72 synchronized(schedulerEntries){
73 schedulerEntries.put(schedulerEntry.getName(), schedulerEntry);
74 }
75 }
76 }
77 /***
78 * Used for debug only
79 *
80 */
81 public String toString(){
82 return timeSchedulerEntries.toString();
83 }
84 /***
85 * Implements the <code>Runnable</code> interface
86 *
87 */
88 public void run() {
89 while(true && !exitApp){
90 try {
91 if(timeSchedulerEntries.isEmpty()){
92 synchronized(timeSchedulerEntries){
93 timeSchedulerEntries.wait();
94 }
95 }
96 else{
97 SchedulerEntry schedulerEntry = (SchedulerEntry)timeSchedulerEntries.first();
98 long milli = schedulerEntry.getTime() - System.currentTimeMillis();
99 if(milli <= 0){
100 execute(schedulerEntry.getRunnable());
101 if(schedulerEntry.isTimeSchedule()){
102 timeSchedulerEntries.remove(schedulerEntry);
103
104 addSchedulerEntry(schedulerEntry);
105 }
106 }
107 else{
108 synchronized(timeSchedulerEntries){
109 timeSchedulerEntries.wait(milli);
110 }
111 }
112 }
113 }
114 catch (Exception ex) {
115 ex.printStackTrace();
116 }
117 }
118 }
119 /***
120 * Execute the <code>Runnable</code> object of the a
121 * <code>SchedulerEntry</code> by its name, use for http schedule
122 *
123 * @param entry the name of the SchedulerEntry to execute
124 */
125 public void execute(String entry){
126 SchedulerEntry schedulerEntry = (SchedulerEntry)schedulerEntries.get(entry);
127 if(schedulerEntry == null){
128 throw new RuntimeException("Scheduler Entry " + entry + " not found");
129 }
130 execute(schedulerEntry.getRunnable());
131 }
132 /***
133 * Execute the <code>Runnable</code> object
134 *
135 * @param runnable
136 */
137 public void execute(Runnable runnable){
138 new Thread(runnable).start();
139 }
140 /***
141 * Use for debug only
142 *
143 * @param args the comman args
144 */
145 public static void main(String args[] ) {
146 try {
147 new Scheduler(80).start();
148 }
149 catch(Exception ex ) {
150 ex.printStackTrace();
151 }
152 }
153 }