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   
6   import java.util.Date;
7   import java.util.Map;
8   import java.util.concurrent.ConcurrentHashMap;
9   import java.util.concurrent.Executors;
10  import java.util.concurrent.Future;
11  import java.util.concurrent.ScheduledExecutorService;
12  import java.util.concurrent.TimeUnit;
13  
14  /**
15   * Plugin scheduler that uses java.util.concurrent.Executor.
16   */
17  public class ExecutorPluginScheduler implements PluginScheduler
18  {
19  
20      public static final int DEFAULT_POOL_SIZE = 5;
21      private final ScheduledExecutorService jobExecutor;
22      private final Map<String, Future<?>> jobs;
23  
24      public ExecutorPluginScheduler()
25      {
26          this(Executors.newScheduledThreadPool(DEFAULT_POOL_SIZE));
27      }
28  
29      public ExecutorPluginScheduler(ScheduledExecutorService executor)
30      {
31          this.jobExecutor = executor;
32          this.jobs = new ConcurrentHashMap<String, Future<?>>();
33      }
34  
35      @Override
36      public synchronized void scheduleJob(String jobKey, Class<? extends PluginJob> jobClass, Map<String, Object> jobDataMap, Date startTime, long repeatInterval)
37      {
38          final Future<?> job = jobs.get(jobKey);
39          if (job != null)
40          {
41              cancelJob(job);
42          }
43  
44          jobs.put(jobKey, jobExecutor.scheduleAtFixedRate(new Job(jobClass, jobDataMap), getDelay(startTime), repeatInterval, TimeUnit.MILLISECONDS));
45      }
46  
47      @Override
48      public synchronized void unscheduleJob(String jobKey)
49      {
50          final Future<?> job = jobs.remove(jobKey);
51          if (job != null)
52          {
53              cancelJob(job);
54          }
55          else
56          {
57              throw new IllegalArgumentException("Attempted to unschedule unknown job: " + jobKey);
58          }
59      }
60  
61      protected void cancelJob(Future<?> job)
62      {
63          job.cancel(false);
64      }
65  
66      private long getDelay(Date startTime)
67      {
68          final long time = startTime.getTime() - System.currentTimeMillis();
69          return time > 0 ? time : 0;
70      }
71  
72      private static class Job implements Runnable
73      {
74  
75          private final Class<? extends PluginJob> jobClass;
76          private final Map<String, Object> jobDataMap;
77  
78          private Job(Class<? extends PluginJob> jobClass, Map<String, Object> jobDataMap)
79          {
80              this.jobClass = jobClass;
81              this.jobDataMap = jobDataMap;
82          }
83  
84          @Override
85          public void run()
86          {
87              PluginJob job;
88              try
89              {
90                  job = jobClass.newInstance();
91              } catch (final InstantiationException ie)
92              {
93                  throw new IllegalStateException("Error instantiating job", ie);
94              } catch (final IllegalAccessException iae)
95              {
96                  throw new IllegalStateException("Cannot access job class", iae);
97              }
98              job.execute(jobDataMap);
99          }
100     }
101 
102 }