1 package com.atlassian.sal.core.scheduling;
2
3 import com.atlassian.sal.api.scheduling.PluginJob;
4 import com.atlassian.sal.api.scheduling.PluginScheduler;
5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory;
7 import org.springframework.beans.factory.DisposableBean;
8
9 import java.util.Collections;
10 import java.util.Date;
11 import java.util.HashMap;
12 import java.util.Map;
13 import java.util.Timer;
14 import java.util.TimerTask;
15
16
17
18
19 public class TimerPluginScheduler implements PluginScheduler, DisposableBean
20 {
21
22 private final Map<String, Timer> tasks;
23 private final boolean useDaemons;
24
25 public TimerPluginScheduler()
26 {
27 this(Collections.synchronizedMap(new HashMap<String, Timer>()), false);
28 }
29
30 protected TimerPluginScheduler(Map<String, Timer> tasks, boolean useDaemons)
31 {
32 this.tasks = tasks;
33 this.useDaemons = useDaemons;
34 }
35
36 public synchronized void scheduleJob(final String name, final Class<? extends PluginJob> job, final Map<String, Object> jobDataMap, final Date startTime, final long repeatInterval)
37 {
38
39 Timer timer = tasks.get(name);
40 PluginTimerTask task;
41 if (timer != null)
42 {
43 timer.cancel();
44 }
45 timer = new Timer("PluginSchedulerTask-" + name, useDaemons);
46 tasks.put(name, timer);
47 task = new PluginTimerTask();
48 task.setJobClass(job);
49 task.setJobDataMap(jobDataMap);
50 timer.scheduleAtFixedRate(task, startTime, repeatInterval);
51 }
52
53 @Override
54 public void destroy() throws Exception
55 {
56 for (Timer timer : tasks.values())
57 {
58 timer.cancel();
59 }
60 }
61
62
63
64
65 private static class PluginTimerTask extends TimerTask
66 {
67 private Class<? extends PluginJob> jobClass;
68 private Map<String, Object> jobDataMap;
69 private static final Logger log = LoggerFactory.getLogger(PluginTimerTask.class);
70
71 @Override
72 public void run()
73 {
74 PluginJob job;
75 try
76 {
77 job = jobClass.newInstance();
78 }
79 catch (final InstantiationException ie)
80 {
81 log.error("Error instantiating job", ie);
82 return;
83 }
84 catch (final IllegalAccessException iae)
85 {
86 log.error("Cannot access job class", iae);
87 return;
88 }
89 job.execute(jobDataMap);
90 }
91
92 public Class<? extends PluginJob> getJobClass()
93 {
94 return jobClass;
95 }
96
97 public void setJobClass(final Class<? extends PluginJob> jobClass)
98 {
99 this.jobClass = jobClass;
100 }
101
102 public Map<String, Object> getJobDataMap()
103 {
104 return jobDataMap;
105 }
106
107 public void setJobDataMap(final Map<String, Object> jobDataMap)
108 {
109 this.jobDataMap = jobDataMap;
110 }
111 }
112
113 public void unscheduleJob(final String name)
114 {
115 final Timer timer = tasks.remove(name);
116 if (timer != null)
117 {
118 timer.cancel();
119 }
120 else
121 {
122 throw new IllegalArgumentException("Attempted to unschedule unknown job: " + name);
123 }
124 }
125 }