1 package com.atlassian.sal.core.scheduling;
2
3 import com.atlassian.sal.api.component.ComponentLocator;
4 import com.atlassian.sal.api.scheduling.PluginJob;
5 import com.atlassian.sal.api.scheduling.PluginScheduler;
6 import org.quartz.Job;
7 import org.quartz.JobDataMap;
8 import org.quartz.JobDetail;
9 import org.quartz.JobExecutionContext;
10 import org.quartz.JobExecutionException;
11 import org.quartz.Scheduler;
12 import org.quartz.SchedulerException;
13 import org.quartz.SimpleTrigger;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16
17 import java.util.Arrays;
18 import java.util.Date;
19 import java.util.Map;
20
21
22
23
24 public class QuartzPluginScheduler implements PluginScheduler
25 {
26 private static final String JOB_CLASS_KEY = "pluginJobClass";
27 private static final String JOB_DATA_MAP_KEY = "pluginJobDataMap";
28 private static final Logger log = LoggerFactory.getLogger(QuartzPluginScheduler.class);
29 private static final String DEFAULT_GROUP = "pluginSchedulerJobGroup";
30
31 public void scheduleJob(final String name, final Class<? extends PluginJob> job, final Map<String, Object> jobDataMap, final Date startTime, final long repeatInterval)
32 {
33
34 final JobDetail jobDetail = new JobDetail();
35 jobDetail.setGroup(DEFAULT_GROUP);
36 jobDetail.setName(name);
37 jobDetail.setJobClass(QuartzPluginJob.class);
38 jobDetail.setJobDataMap(getJobMap(job, jobDataMap));
39
40
41 final SimpleTrigger trigger = new SimpleTrigger();
42 trigger.setGroup("pluginSchedulerTriggerGroup");
43 trigger.setName(name + "Trigger");
44 if (startTime != null)
45 {
46 trigger.setStartTime(startTime);
47 }
48 if (repeatInterval == 0)
49 {
50 trigger.setRepeatCount(0);
51 }
52 else
53 {
54 trigger.setRepeatInterval(repeatInterval);
55 trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
56 }
57
58
59 try
60 {
61 final Scheduler scheduler = getScheduler();
62 scheduler.scheduleJob(jobDetail, trigger);
63 }
64 catch (final SchedulerException se)
65 {
66 log.error("Error scheduling job " +name, se);
67 }
68 }
69
70
71
72
73 public static class QuartzPluginJob implements Job
74 {
75 @SuppressWarnings("unchecked")
76 public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException
77 {
78 final JobDataMap map = jobExecutionContext.getJobDetail().getJobDataMap();
79 final Class<? extends PluginJob> jobClass = (Class<? extends PluginJob>) map.get(JOB_CLASS_KEY);
80 final Map<String, Object> pluginJobMap = (Map<String, Object>) map.get(JOB_DATA_MAP_KEY);
81
82 PluginJob job;
83 try
84 {
85 job = jobClass.newInstance();
86 }
87 catch (final InstantiationException ie)
88 {
89 throw new JobExecutionException("Error instantiating job", ie, false);
90 }
91 catch (final IllegalAccessException iae)
92 {
93 throw new JobExecutionException("Cannot access job class", iae, false);
94 }
95 job.execute(pluginJobMap);
96 }
97 }
98
99 public void unscheduleJob(final String name)
100 {
101 try
102 {
103 final Scheduler scheduler = getScheduler();
104 if (!Arrays.asList(scheduler.getJobNames(DEFAULT_GROUP)).contains(name))
105 {
106 throw new IllegalArgumentException("Error unscheduling job. Job '" + name + "' is not scheduled ");
107 }
108 scheduler.deleteJob(name, DEFAULT_GROUP);
109 } catch (final SchedulerException e)
110 {
111 throw new IllegalArgumentException("Error unscheduling job " + name, e);
112 }
113 }
114
115 protected JobDataMap getJobMap(Class<? extends PluginJob> job, Map<String, Object> jobDataMap) {
116 final JobDataMap jobDetailMap = new JobDataMap();
117 jobDetailMap.put(JOB_CLASS_KEY, job);
118 jobDetailMap.put(JOB_DATA_MAP_KEY, jobDataMap);
119 return jobDetailMap;
120 }
121
122 protected Scheduler getScheduler() {
123 return ComponentLocator.getComponent(Scheduler.class);
124 }
125
126 }