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 private final Map<String, Timer> tasks;
22 private final boolean useDaemons;
23
24 public TimerPluginScheduler() {
25 this(Collections.synchronizedMap(new HashMap<>()), false);
26 }
27
28 protected TimerPluginScheduler(Map<String, Timer> tasks, boolean useDaemons) {
29 this.tasks = tasks;
30 this.useDaemons = useDaemons;
31 }
32
33 public synchronized void scheduleJob(final String name, final Class<? extends PluginJob> job, final Map<String, Object> jobDataMap, final Date startTime, final long repeatInterval) {
34
35 Timer timer = tasks.get(name);
36 PluginTimerTask task;
37 if (timer != null) {
38 timer.cancel();
39 }
40 timer = new Timer("PluginSchedulerTask-" + name, useDaemons);
41 tasks.put(name, timer);
42 task = new PluginTimerTask();
43 task.setJobClass(job);
44 task.setJobDataMap(jobDataMap);
45 timer.scheduleAtFixedRate(task, startTime, repeatInterval);
46 }
47
48 @Override
49 public void destroy() throws Exception {
50 for (Timer timer : tasks.values()) {
51 timer.cancel();
52 }
53 }
54
55
56
57
58 private static class PluginTimerTask extends TimerTask {
59 private Class<? extends PluginJob> jobClass;
60 private Map<String, Object> jobDataMap;
61 private static final Logger log = LoggerFactory.getLogger(PluginTimerTask.class);
62
63 @Override
64 public void run() {
65 PluginJob job;
66 try {
67 job = jobClass.newInstance();
68 } catch (final InstantiationException ie) {
69 log.error("Error instantiating job", ie);
70 return;
71 } catch (final IllegalAccessException iae) {
72 log.error("Cannot access job class", iae);
73 return;
74 }
75 job.execute(jobDataMap);
76 }
77
78 public Class<? extends PluginJob> getJobClass() {
79 return jobClass;
80 }
81
82 public void setJobClass(final Class<? extends PluginJob> jobClass) {
83 this.jobClass = jobClass;
84 }
85
86 public Map<String, Object> getJobDataMap() {
87 return jobDataMap;
88 }
89
90 public void setJobDataMap(final Map<String, Object> jobDataMap) {
91 this.jobDataMap = jobDataMap;
92 }
93 }
94
95 public void unscheduleJob(final String name) {
96 final Timer timer = tasks.remove(name);
97 if (timer != null) {
98 timer.cancel();
99 } else {
100 throw new IllegalArgumentException("Attempted to unschedule unknown job: " + name);
101 }
102 }
103 }