View Javadoc

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   * Plugin scheduler that uses java.util.Timer
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<String, Timer>()), 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          // Use one timer per task, this will allow us to remove them if that functionality is wanted in future
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       * TimerTask that executes a PluginJob
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 }