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  
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          // Use one timer per task, this will allow us to remove them if that functionality is wanted in future
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       * TimerTask that executes a PluginJob
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 }