001
014
015 package com.liferay.portal.scheduler.quartz;
016
017 import com.liferay.portal.kernel.annotation.BeanReference;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.messaging.Message;
021 import com.liferay.portal.kernel.scheduler.IntervalTrigger;
022 import com.liferay.portal.kernel.scheduler.SchedulerEngine;
023 import com.liferay.portal.kernel.scheduler.SchedulerException;
024 import com.liferay.portal.kernel.scheduler.TriggerType;
025 import com.liferay.portal.kernel.scheduler.messaging.SchedulerRequest;
026 import com.liferay.portal.kernel.util.ServerDetector;
027 import com.liferay.portal.kernel.util.StringPool;
028 import com.liferay.portal.kernel.util.Time;
029 import com.liferay.portal.scheduler.job.MessageSenderJob;
030 import com.liferay.portal.service.QuartzLocalService;
031 import com.liferay.portal.util.PropsUtil;
032 import com.liferay.portal.util.PropsValues;
033
034 import java.text.ParseException;
035
036 import java.util.ArrayList;
037 import java.util.Date;
038 import java.util.List;
039
040 import org.quartz.CronTrigger;
041 import org.quartz.JobDataMap;
042 import org.quartz.JobDetail;
043 import org.quartz.ObjectAlreadyExistsException;
044 import org.quartz.Scheduler;
045 import org.quartz.SimpleTrigger;
046 import org.quartz.Trigger;
047 import org.quartz.impl.StdSchedulerFactory;
048
049
055 public class QuartzSchedulerEngineImpl implements SchedulerEngine {
056
057 public void afterPropertiesSet() {
058 try {
059 if (!PropsValues.SCHEDULER_ENABLED) {
060 return;
061 }
062
063 StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
064
065 schedulerFactory.initialize(
066 PropsUtil.getProperties("org.quartz.", false));
067
068 quartzLocalService.checkQuartzTables();
069
070 _scheduler = schedulerFactory.getScheduler();
071 }
072 catch (Exception e) {
073 _log.error("Unable to initialize engine", e);
074 }
075 }
076
077 public List<SchedulerRequest> getScheduledJobs(String groupName)
078 throws SchedulerException {
079
080 if (!PropsValues.SCHEDULER_ENABLED) {
081 return new ArrayList<SchedulerRequest>();
082 }
083
084 try {
085 String[] jobNames = _scheduler.getJobNames(groupName);
086
087 List<SchedulerRequest> requests = new ArrayList<SchedulerRequest>();
088
089 for (String jobName : jobNames) {
090 JobDetail jobDetail = _scheduler.getJobDetail(
091 jobName, groupName);
092
093 if (jobDetail == null) {
094 continue;
095 }
096
097 JobDataMap jobDataMap = jobDetail.getJobDataMap();
098
099 String description = jobDataMap.getString(DESCRIPTION);
100 Message message = (Message)jobDataMap.get(MESSAGE);
101
102 SchedulerRequest schedulerRequest = null;
103
104 Trigger trigger = _scheduler.getTrigger(jobName, groupName);
105
106 if (CronTrigger.class.isAssignableFrom(trigger.getClass())) {
107 CronTrigger cronTrigger = CronTrigger.class.cast(trigger);
108
109 schedulerRequest =
110 SchedulerRequest.createRetrieveResponseRequest(
111 new com.liferay.portal.kernel.scheduler.CronTrigger(
112 jobName, groupName, cronTrigger.getStartTime(),
113 cronTrigger.getEndTime(),
114 cronTrigger.getCronExpression()),
115 description, message);
116 }
117 else if (SimpleTrigger.class.isAssignableFrom(
118 trigger.getClass())) {
119
120 SimpleTrigger simpleTrigger = SimpleTrigger.class.cast(
121 trigger);
122
123 schedulerRequest =
124 SchedulerRequest.createRetrieveResponseRequest(
125 new IntervalTrigger(
126 jobName, groupName,
127 simpleTrigger.getStartTime(),
128 simpleTrigger.getEndTime(),
129 simpleTrigger.getRepeatInterval()), description,
130 message);
131 }
132
133 if (schedulerRequest != null) {
134 requests.add(schedulerRequest);
135 }
136 }
137
138 return requests;
139 }
140 catch (org.quartz.SchedulerException se) {
141 throw new SchedulerException("Unable to retrieve job", se);
142 }
143 }
144
145 public void schedule(
146 com.liferay.portal.kernel.scheduler.Trigger trigger,
147 String description, String destination, Message message)
148 throws SchedulerException {
149
150 if (!PropsValues.SCHEDULER_ENABLED) {
151 return;
152 }
153
154 try {
155 String jobName = trigger.getJobName();
156 String groupName = trigger.getGroupName();
157
158 if (jobName.length() > JOB_NAME_MAX_LENGTH) {
159 jobName = jobName.substring(0, JOB_NAME_MAX_LENGTH);
160 }
161
162 if (groupName.length() > GROUP_NAME_MAX_LENGTH) {
163 groupName = groupName.substring(0, GROUP_NAME_MAX_LENGTH);
164 }
165
166 Trigger quartzTrigger = null;
167
168 if (trigger.getTriggerType() == TriggerType.CRON) {
169 try {
170 quartzTrigger = new CronTrigger(
171 jobName, groupName,
172 (String)trigger.getTriggerContent());
173 }
174 catch (ParseException pe) {
175 throw new SchedulerException(
176 "Unable to parse cron text " +
177 trigger.getTriggerContent());
178 }
179 }
180 else if (trigger.getTriggerType() == TriggerType.SIMPLE) {
181 long interval = (Long)trigger.getTriggerContent();
182
183 if (interval <= 0) {
184 if (_log.isDebugEnabled()) {
185 _log.debug(
186 "Not scheduling " + trigger.getJobName() +
187 " because interval is less than or equal to 0");
188 }
189
190 return;
191 }
192
193 quartzTrigger = new SimpleTrigger(
194 jobName, groupName, SimpleTrigger.REPEAT_INDEFINITELY,
195 interval);
196 }
197 else {
198 throw new SchedulerException(
199 "Unknown trigger type " + trigger.getTriggerType());
200 }
201
202 quartzTrigger.setJobName(jobName);
203 quartzTrigger.setJobGroup(groupName);
204
205 Date startDate = trigger.getStartDate();
206
207 if (startDate == null) {
208 if (ServerDetector.getServerId().equals(
209 ServerDetector.TOMCAT_ID)) {
210
211 quartzTrigger.setStartTime(
212 new Date(System.currentTimeMillis() + Time.MINUTE));
213 }
214 else {
215 quartzTrigger.setStartTime(
216 new Date(
217 System.currentTimeMillis() + Time.MINUTE * 3));
218 }
219 }
220 else {
221 quartzTrigger.setStartTime(startDate);
222 }
223
224 Date endDate = trigger.getEndDate();
225
226 if (endDate != null) {
227 quartzTrigger.setEndTime(endDate);
228 }
229
230 if ((description != null) &&
231 (description.length() > DESCRIPTION_MAX_LENGTH)) {
232
233 description = description.substring(0, DESCRIPTION_MAX_LENGTH);
234 }
235
236 if (message == null){
237 message = new Message();
238 }
239
240 message.put(
241 RECEIVER_KEY,
242 jobName.concat(StringPool.COLON).concat(groupName));
243
244 schedule(quartzTrigger, description, destination, message);
245 }
246 catch (RuntimeException re) {
247
248
249
250
251 }
252 }
253
254 public void shutdown() throws SchedulerException {
255 if (!PropsValues.SCHEDULER_ENABLED) {
256 return;
257 }
258
259 try {
260 _scheduler.shutdown(false);
261 }
262 catch (org.quartz.SchedulerException se) {
263 throw new SchedulerException("Unable to shutdown scheduler", se);
264 }
265 }
266
267 public void start() throws SchedulerException {
268 if (!PropsValues.SCHEDULER_ENABLED) {
269 return;
270 }
271
272 try {
273 _scheduler.start();
274 }
275 catch (org.quartz.SchedulerException se) {
276 throw new SchedulerException("Unable to start scheduler", se);
277 }
278 }
279
280 public void unschedule(
281 com.liferay.portal.kernel.scheduler.Trigger trigger)
282 throws SchedulerException {
283
284 if (!PropsValues.SCHEDULER_ENABLED) {
285 return;
286 }
287
288 String jobName = trigger.getJobName();
289 String groupName = trigger.getGroupName();
290
291 try {
292 _scheduler.unscheduleJob(jobName, groupName);
293 }
294 catch (org.quartz.SchedulerException se) {
295 throw new SchedulerException(
296 "Unable to unschedule job {jobName=" + jobName +
297 ", groupName=" + groupName + "}",
298 se);
299 }
300 }
301
302 protected void schedule(
303 Trigger trigger, String description,
304 String destination, Message message)
305 throws SchedulerException {
306
307 try {
308 String jobName = trigger.getName();
309 String groupName = trigger.getGroup();
310
311 JobDetail jobDetail = new JobDetail(
312 jobName, groupName, MessageSenderJob.class);
313
314 JobDataMap jobDataMap = jobDetail.getJobDataMap();
315
316 jobDataMap.put(DESCRIPTION, description);
317 jobDataMap.put(DESTINATION, destination);
318 jobDataMap.put(MESSAGE, message);
319
320 synchronized (this) {
321 _scheduler.unscheduleJob(jobName, groupName);
322 _scheduler.scheduleJob(jobDetail, trigger);
323 }
324 }
325 catch (ObjectAlreadyExistsException oare) {
326 if (_log.isInfoEnabled()) {
327 _log.info("Message is already scheduled");
328 }
329 }
330 catch (org.quartz.SchedulerException se) {
331 throw new SchedulerException("Unable to scheduled job", se);
332 }
333 }
334
335 @BeanReference(name = "com.liferay.portal.service.QuartzLocalService")
336 protected QuartzLocalService quartzLocalService;
337
338 private Log _log = LogFactoryUtil.getLog(QuartzSchedulerEngineImpl.class);
339
340 private Scheduler _scheduler;
341
342 }