/** * Copyright (c)2010-2011 Enterprise Website Content Management System(EWCMS), All rights reserved. * EWCMS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * http://www.ewcms.com */ package com.ewcms.scheduling.generate.quartz; import static org.quartz.JobBuilder.newJob; import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.TriggerBuilder.newTrigger; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.TimeZone; import org.quartz.DateBuilder; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobKey; import org.quartz.Matcher; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerListener; import org.quartz.SimpleTrigger; import org.quartz.Trigger; import org.quartz.Trigger.CompletedExecutionInstruction; import org.quartz.Trigger.TriggerState; import org.quartz.TriggerKey; import org.quartz.TriggerListener; import org.quartz.impl.matchers.KeyMatcher; import org.quartz.impl.triggers.AbstractTrigger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import com.ewcms.scheduling.BaseException; import com.ewcms.scheduling.BaseRuntimeException; import com.ewcms.scheduling.BaseRuntimeExceptionWrapper; import com.ewcms.scheduling.generate.common.ValidationError; import com.ewcms.scheduling.generate.common.ValidationErrorsable; import com.ewcms.scheduling.generate.vo.JobInfoRuntimeInformation; import com.ewcms.scheduling.model.JobCalendarTrigger; import com.ewcms.scheduling.model.JobInfo; import com.ewcms.scheduling.model.JobSimpleTrigger; import com.ewcms.scheduling.model.JobTrigger; /** * @author 吴智俊 */ public class JobsQuartzScheduler implements JobsQuartzSchedulerable, InitializingBean { protected static final Logger logger = LoggerFactory.getLogger(JobsQuartzScheduler.class); private static final String GROUP = "jobs"; private static final String TRIGGER_LISTENER_NAME = "schedulerTriggerListener"; private static final String JOB_DATA_KEY_DETAILS_ID = "jobDetailsID"; private static final Long COEFFICIENT_MINUTE = 60L * 1000L; private static final Long COEFFICIENT_HOUR = 60L * COEFFICIENT_MINUTE; private static final Long COEFFICIENT_DAY = 24L * COEFFICIENT_HOUR; private static final Long COEFFICIENT_WEEK = 7L * COEFFICIENT_DAY; private static final Integer COUNT_WEEKDAYS = 7; private static final Integer COUNT_MONTHS = 12; private Scheduler scheduler; private final Set<SchedulerListenerable> listeners; private final SchedulerListener schedulerListener; private final TriggerListener triggerListener; public JobsQuartzScheduler() { listeners = new HashSet<SchedulerListenerable>(); schedulerListener = new SchedulerQuartzListener(); triggerListener = new SchedulerTriggerListener(TRIGGER_LISTENER_NAME); } public Scheduler getScheduler() { return scheduler; } public void setScheduler(Scheduler scheduler) { this.scheduler = scheduler; } public void afterPropertiesSet() throws Exception { try { //注册为非全局的SchedulerListener getScheduler().getListenerManager().addSchedulerListener(schedulerListener); //注册为非全局的TriggerListener getScheduler().getListenerManager().addTriggerListener(triggerListener, (List<Matcher<TriggerKey>>)null); } catch (SchedulerException e) { logger.error("注册Quartz监听时出现错误", e); throw new BaseRuntimeExceptionWrapper(e); } } public void scheduleJob(JobInfo job) throws BaseException { JobDetail jobDetail = createJobDetail(job); Trigger trigger = createTrigger(job); try { scheduler.scheduleJob(jobDetail, trigger); if (logger.isDebugEnabled()){ logger.debug("Created job " + jobDetail.getKey().getName() + " and trigger " + trigger.getKey().getName() + " for job " + job.getId()); } } catch (SchedulerException e) { logger.error("调度Quartz任务时错误", e); throw new BaseException(e.toString(), "调度Quartz任务时错误"); } } /** * 建立调度器任务明细 * * @param job 调度器任务 * @return JobDetail */ @SuppressWarnings("unchecked") protected JobDetail createJobDetail(JobInfo job) { String jobName = jobName(job.getId()); String jobClassEntity = job.getJobClass().getClassEntity().trim(); try { if (jobClassEntity != null && jobClassEntity.length() > 0) { //TODO 未测试 //ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); //Class<Job> classEntity = (Class<Job>) ClassUtils.forName(jobClassEntity, beanClassLoader); Class<Job> classEntity = (Class<Job>) Class.forName(jobClassEntity); JobDetail jobDetail = newJob(classEntity). withIdentity(jobName, GROUP). requestRecovery(true). build(); return jobDetail; }else{ logger.info("必须选择一个执行的调度器作业任务"); throw new BaseRuntimeException("必须选择一个执行的调度器作业任务"); } } catch (ClassNotFoundException e) { logger.error("调度器作业不是一个有效的作业任务",e); throw new BaseRuntimeException("调度器作业不是一个有效的作业任务", new Object[]{jobClassEntity}); } } public void rescheduleJob(JobInfo job) throws BaseException { try { Trigger oldTrigger = getJobTrigger(job.getId()); Trigger trigger = createTrigger(job); if (oldTrigger == null) { JobDetail jobDetail = createJobDetail(job); scheduler.scheduleJob(jobDetail, trigger); if (logger.isDebugEnabled()) { logger.debug("Scheduled trigger " + trigger.getKey().getName() + " for job " + job.getId()); } } else { scheduler.rescheduleJob(oldTrigger.getKey(), trigger); if (logger.isDebugEnabled()) { logger.debug("Trigger " + oldTrigger.getKey().getName() + " rescheduled by " + trigger.getKey().getName() + " for job " + job.getId()); } } } catch (SchedulerException e) { logger.error("调度Quartz任务错误", e); throw new BaseException(e.toString(), "调度Quartz任务错误"); } } /** * 查询调度器任务的触发器 * * @param jobId 调度器任务编号 * @return Trigger * @throws SchedulerException * @throws BaseException */ protected Trigger getJobTrigger(long jobId) throws SchedulerException, BaseException { Trigger trigger; String jobName = jobName(jobId); List<? extends Trigger> triggers = scheduler.getTriggersOfJob(new JobKey(jobName, GROUP)); List<Trigger> filteredTriggersList = new ArrayList<Trigger>(); for (Trigger currTrigger : triggers) { if (GROUP.equals(currTrigger.getKey().getGroup())) { filteredTriggersList.add(currTrigger); } } triggers = filteredTriggersList; if (triggers == null || triggers.isEmpty()) { trigger = null; if (logger.isDebugEnabled()) { logger.debug("No trigger found for job " + jobId); } } else if (triggers.size() == 1) { trigger = triggers.get(0); if (logger.isDebugEnabled()) { logger.debug("Trigger " + trigger.getKey().getName() + " found for job " + jobId); } } else { logger.error("任务有一个以上的触发器", new Object[] {new Long(jobId)}); throw new BaseException("任务有一个以上的触发器", "任务有一个以上的触发器"); } return trigger; } /** * 设置调度器任务名称 * * @param jobId 调度器任务编号 * @return String */ protected String jobName(long jobId) { return "job_" + jobId; } /** * 设置触发器名称 * * @param jobTrigger 触发器 * @return String */ protected String triggerName(JobTrigger jobTrigger) { return "trigger_" + jobTrigger.getId() + "_" + jobTrigger.getVersion(); } /** * 建立触发器 * * @param jobInfo 触发器 * @return Trigger * @throws BaseException */ protected Trigger createTrigger(JobInfo jobInfo) throws BaseException { Trigger trigger; JobTrigger jobTrigger = jobInfo.getTrigger(); if (jobTrigger instanceof JobSimpleTrigger) { trigger = createTrigger((JobSimpleTrigger) jobTrigger); } else if (jobTrigger instanceof JobCalendarTrigger) { trigger = createTrigger((JobCalendarTrigger) jobTrigger); } else { String quotedJobTrigger = "\"" + jobTrigger.getClass().getName() + "\""; logger.error("任务触发类型没有命名", new Object[] {quotedJobTrigger}); throw new BaseException("任务触发类型没有命名", "任务触发类型没有命名"); } JobDataMap jobDataMap = trigger.getJobDataMap(); jobDataMap.put(JOB_DATA_KEY_DETAILS_ID, jobInfo.getId()); TriggerKey tk = getTriggerKey(jobTrigger); Matcher<TriggerKey> matcher = KeyMatcher.keyEquals(tk); try { getScheduler().getListenerManager().addTriggerListener(triggerListener, matcher); } catch (SchedulerException e) { logger.error("增加Quartz触发监听器错误", e.toString()); throw new BaseException(e); } return trigger; } //---------------------------------------简单型触发器--------------------------------------------------- /** * 建立触发器 * * @param jobTrigger 简单型触发器 * @return Trigger * @throws BaseException */ protected Trigger createTrigger(JobSimpleTrigger jobTrigger) throws BaseException { String triggerName = triggerName(jobTrigger); Date startDate = getStartDate(jobTrigger); Date endDate = getEndDate(jobTrigger); int repeatCount = repeatCount(jobTrigger); SimpleTrigger trigger; if (repeatCount == 0) { trigger = newTrigger().withIdentity(triggerName, GROUP). startAt(startDate). withSchedule(simpleSchedule(). withRepeatCount(0). withMisfireHandlingInstructionNextWithRemainingCount()). build(); } else { int recurrenceInterval = jobTrigger.getRecurrenceInterval().intValue(); long unitCoefficient = getIntervalUnitCoefficient(jobTrigger); long interval = recurrenceInterval * unitCoefficient; trigger = newTrigger().withIdentity(triggerName, GROUP). startAt(startDate). endAt(endDate). withSchedule(simpleSchedule(). withIntervalInMilliseconds(interval). withRepeatCount(repeatCount). withMisfireHandlingInstructionNextWithRemainingCount()). build(); } return trigger; } protected long getIntervalUnitCoefficient(JobSimpleTrigger jobTrigger) throws BaseException { long coefficient; int riu = jobTrigger.getRecurrenceIntervalUnit().intValue(); if (riu == JobSimpleTrigger.INTERVAL_MINUTE.intValue()){ coefficient = COEFFICIENT_MINUTE; }else if (riu == JobSimpleTrigger.INTERVAL_HOUR.intValue()){ coefficient = COEFFICIENT_HOUR; }else if (riu == JobSimpleTrigger.INTERVAL_DAY.intValue()){ coefficient = COEFFICIENT_DAY; }else if (riu == JobSimpleTrigger.INTERVAL_WEEK.intValue()){ coefficient = COEFFICIENT_WEEK; }else { logger.error("不能识别任务执行的间隔数", new Object[] {jobTrigger.getRecurrenceIntervalUnit()}); throw new BaseException("不能识别任务执行的间隔数", "不能识别任务执行的间隔数"); } return coefficient; } /** * 查询结束时间 * * @param jobTrigger 触发器 * @return Date * @throws BaseException */ protected Date getEndDate(JobTrigger jobTrigger) throws BaseException { return translateFromTriggerTimeZone(jobTrigger, jobTrigger.getEndDate()); } protected Date translateFromTriggerTimeZone(JobTrigger jobTrigger, Date date) throws BaseException { if (date != null) { TimeZone tz = getTriggerTimeZone(jobTrigger); if (tz != null) { date = DateBuilder.translateTime(date, TimeZone.getDefault(), tz); } } return date; } /** * 查询开始时间 * * @param jobTrigger 触发器 * @return Date * @throws BaseException */ protected Date getStartDate(JobTrigger jobTrigger) throws BaseException { Date startDate; if (jobTrigger.getStartType().intValue() == JobTrigger.START_TYPE_NOW.intValue()) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); startDate = calendar.getTime(); } else if (jobTrigger.getStartType().intValue() == JobTrigger.START_TYPE_SCHEDULE.intValue()) { startDate = translateFromTriggerTimeZone(jobTrigger, jobTrigger.getStartDate()); } else { logger.error("任务开始类型没有赋值", new Object[] {jobTrigger.getStartType()}); throw new BaseException("任务开始类型没有赋值", "任务开始类型没有赋值"); } return startDate; } /** * 执行次数 * * @param jobTrigger * @return int */ protected int repeatCount(JobSimpleTrigger jobTrigger) { Integer recurrenceCount = jobTrigger.getOccurrenceCount(); Integer repeatCount; if (recurrenceCount.intValue() == JobSimpleTrigger.RECUR_INDEFINITELY.intValue()) { repeatCount = SimpleTrigger.REPEAT_INDEFINITELY; } else { repeatCount = recurrenceCount - 1; } return repeatCount; } //---------------------------------------简单型触发器--------------------------------------------------- //---------------------------------------复杂型触发器--------------------------------------------------- /** * 建立触发器 * * @param jobTrigger 复杂型触发器 * @return Trigger * @throws BaseException */ protected Trigger createTrigger(JobCalendarTrigger jobTrigger) throws BaseException { String triggerName = triggerName(jobTrigger); Date startDate = getStartDate(jobTrigger); Date endDate = getEndDate(jobTrigger); String cronExpression = getCronExpression(jobTrigger); try { Trigger trigger = newTrigger().withIdentity(triggerName, GROUP). startAt(startDate). endAt(endDate). withSchedule(cronSchedule(cronExpression). inTimeZone(getTriggerTimeZone(jobTrigger)). // NULL input is OK withMisfireHandlingInstructionDoNothing()). build(); return trigger; } catch (Exception e) { logger.error("建立Quartz复杂触发器错误", e); throw new BaseException("建立Quartz复杂触发器错误", "建立Quartz复杂触发器错误"); } } /** * 查询触发器时区 * * @param jobTrigger 触发器 * @return TimeZone * @throws BaseException */ protected TimeZone getTriggerTimeZone(JobTrigger jobTrigger) throws BaseException { String tzId = jobTrigger.getTimeZone(); TimeZone tz; if (tzId == null || tzId.length() == 0) { tz = null; } else { tz = TimeZone.getTimeZone(tzId); if (tz == null) { String quotedTzId = "\"" + tzId + "\""; logger.error("时区(TimeZone)没有赋值", quotedTzId); throw new BaseException("时区(TimeZone)没有赋值", "时区(TimeZone)没有赋值"); } } return tz; } /** * 查询触发器表达式 * * @param jobTrigger 复杂型触发器 * @return String * @throws BaseException */ protected String getCronExpression(JobCalendarTrigger jobTrigger) throws BaseException { String minutes = jobTrigger.getMinutes(); String hours = jobTrigger.getHours(); String weekDays; String monthDays; if (jobTrigger.getDaysType().intValue() == JobCalendarTrigger.DAYS_TYPE_ALL.intValue()) { weekDays = "?"; monthDays = "*"; } else if (jobTrigger.getDaysType().intValue() == JobCalendarTrigger.DAYS_TYPE_WEEK.intValue()) { weekDays = enumerateCronVals(jobTrigger.getWeekDays(), COUNT_WEEKDAYS); monthDays = "?"; } else if (jobTrigger.getDaysType().intValue() == JobCalendarTrigger.DAYS_TYPE_MONTH.intValue()) { weekDays = "?"; monthDays = jobTrigger.getMonthDays(); } else { logger.error("未知的任务触发天类型", new Object[] {jobTrigger.getDaysType()}); throw new BaseException("未知的任务触发天类型", "未知的任务触发天类型"); } String months = enumerateCronVals(jobTrigger.getMonths(), COUNT_MONTHS); StringBuffer cronExpression = new StringBuffer(); cronExpression.append("0 "); cronExpression.append(minutes); cronExpression.append(' '); cronExpression.append(hours); cronExpression.append(' '); cronExpression.append(monthDays); cronExpression.append(' '); cronExpression.append(months); cronExpression.append(' '); cronExpression.append(weekDays); return cronExpression.toString(); } protected String enumerateCronVals(String vals, int totalCount) throws BaseException { if (vals == null || vals.length() == 0) { logger.error("未选择值"); throw new BaseException("未选择值", "未选择值"); } StringTokenizer tokenizer = new StringTokenizer(vals, ",", false); if (tokenizer.countTokens() == totalCount) { return "*"; } else { return vals; } } //---------------------------------------复杂型触发器--------------------------------------------------- public void removeScheduledJob(Long jobId) throws BaseException { try { String jobName = jobName(jobId); if (scheduler.deleteJob(new JobKey(jobName, GROUP))) { logger.info("JobsQuartzScheduler:任务 " + jobName + " 被删除"); } else { logger.info("JobsQuartzScheduler:Quartz任务 " + jobId + " 未查到不能删除"); } } catch (SchedulerException e) { logger.error("删除Quartz任务时错误", e); throw new BaseException("删除Quartz任务时错误", "删除Quartz任务时错误"); } } public List<JobInfo> getJobsRuntimeInformation(List<JobInfo> jobInfos) throws BaseException { if (jobInfos == null || jobInfos.size() == 0) { return new ArrayList<JobInfo>(); } try { Set<String> executingJobNames = getExecutingJobNames(); SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (JobInfo jobInfo : jobInfos) { JobInfoRuntimeInformation info = getJobRuntimeInformation(jobInfo.getId(), executingJobNames); jobInfo.setState(info.getState()); if (info.getStartTime() != null){ jobInfo.setStartTime(bartDateFormat.format(info.getStartTime())); }else{ try{ jobInfo.setStartTime(bartDateFormat.format(jobInfo.getTrigger().getStartDate())); }catch(Exception e){ } } if (info.getEndTime() != null){ jobInfo.setEndTime(bartDateFormat.format(info.getEndTime())); }else{ try{ jobInfo.setEndTime(bartDateFormat.format(jobInfo.getTrigger().getEndDate())); }catch(Exception e){ } } if (info.getPreviousFireTime() != null) { jobInfo.setPreviousFireTime(bartDateFormat.format(info.getPreviousFireTime())); } if (info.getNextFireTime() != null) { jobInfo.setNextFireTime(bartDateFormat.format(info.getNextFireTime())); } } return jobInfos; } catch (SchedulerException e) { logger.error("获得Quartz运行时信息错误", e); throw new BaseException("获得Quartz运行时信息错误", "获得Quartz运行时信息错误"); } } /** * 获取调度器任务运行时的状态 * * @param jobId 调度器任务编号 * @param executingJobNames 调度器任务名称 * @return JobRuntimeInformation * @throws SchedulerException * @throws BaseException */ protected JobInfoRuntimeInformation getJobRuntimeInformation(Long jobId, Set<String> executingJobNames) throws SchedulerException, BaseException { JobInfoRuntimeInformation info = new JobInfoRuntimeInformation(); Trigger trigger = getJobTrigger(jobId); if (trigger == null) { info.setState(JobInfoRuntimeInformation.STATE_UNKNOWN); } else { info.setStartTime(trigger.getStartTime()); info.setEndTime(trigger.getEndTime()); info.setPreviousFireTime(trigger.getPreviousFireTime()); if (trigger.mayFireAgain()) { info.setNextFireTime(trigger.getNextFireTime()); } String state = getJobState(trigger, executingJobNames); info.setState(state); } return info; } protected String getJobState(Trigger trigger, Set<String> executingJobNames) throws SchedulerException { String state; Trigger.TriggerState quartzState = scheduler.getTriggerState(trigger.getKey()); switch (quartzState) { case NORMAL: case BLOCKED: state = executingJobNames.contains(trigger.getKey().getName()) ? JobInfoRuntimeInformation.STATE_EXECUTING : JobInfoRuntimeInformation.STATE_NORMAL; break; case COMPLETE: state = JobInfoRuntimeInformation.STATE_COMPLETE; break; case PAUSED: state = JobInfoRuntimeInformation.STATE_PAUSED; break; case ERROR: state = JobInfoRuntimeInformation.STATE_ERROR; break; default: state = JobInfoRuntimeInformation.STATE_UNKNOWN; break; } return state; } protected Set<String> getExecutingJobNames() throws SchedulerException { List<JobExecutionContext> executingJobs = (List<JobExecutionContext>) scheduler.getCurrentlyExecutingJobs(); Set<String> executingJobNames = new HashSet<String>(); for (Iterator<JobExecutionContext> iter = executingJobs.iterator(); iter.hasNext();) { JobExecutionContext executionContext = (JobExecutionContext) iter.next(); JobDetail jobDetail = executionContext.getJobDetail(); if (jobDetail.getKey().getGroup().equals(GROUP)) { executingJobNames.add(jobDetail.getKey().getName()); } } return executingJobNames; } public void addSchedulerListener(SchedulerListenerable listener) { synchronized (listeners) { listeners.add(listener); } } public synchronized void removeSchedulerListener(SchedulerListenerable listener) { synchronized (listeners) { listeners.remove(listener); } } protected void notifyListenersOfFinalizedJob(Long jobId) throws BaseException { synchronized (listeners) { for (Iterator<SchedulerListenerable> it = listeners.iterator(); it.hasNext();) { SchedulerListenerable listener = (SchedulerListenerable) it.next(); listener.jobFinalized(jobId); } } } protected void getTriggerFinalized(Trigger trigger) throws BaseException { try{ long jobId = trigger.getJobDataMap().getIntegerFromString(JOB_DATA_KEY_DETAILS_ID); notifyListenersOfFinalizedJob(jobId); }catch(ClassCastException e){ } } protected TriggerKey getTriggerKey(JobTrigger jobTrigger) { return new TriggerKey(triggerName(jobTrigger), GROUP); } protected class SchedulerQuartzListener implements SchedulerListener { public SchedulerQuartzListener() { } @Override public void jobScheduled(Trigger trigger) { if (logger.isDebugEnabled()) { logger.debug("Quartz job " + trigger.getKey() + " scheduled by trigger " + trigger.getKey()); } } @Override public void jobUnscheduled(TriggerKey triggerKey) { if (logger.isDebugEnabled()) { logger.debug("Quartz job with triggerKey: " + triggerKey + " unscheduled"); } } @Override public void triggerFinalized(Trigger trigger) { if (logger.isDebugEnabled()) { logger.debug("Quartz trigger finalized " + trigger.getKey()); } if (trigger.getKey().getGroup().equals(GROUP)) { try { getTriggerFinalized(trigger); } catch (BaseException e) { e.printStackTrace(); } } } @Override public void triggerPaused(TriggerKey triggerKey) { if (logger.isDebugEnabled()) { logger.debug("Quartz job trigger" + triggerKey + " paused"); } } @Override public void triggersPaused(String triggerGroup) { if (logger.isDebugEnabled()) { logger.debug("Quartz job trigger group " + triggerGroup + " paused "); } } @Override public void triggerResumed(TriggerKey triggerKey) { if (logger.isDebugEnabled()) { logger.debug("Quartz job trigger " + triggerKey + " resumed "); } } @Override public void triggersResumed(String triggerGroup) { if (logger.isDebugEnabled()) { logger.debug("Quartz job trigger group" + triggerGroup + " resumed "); } } @Override public void jobAdded(JobDetail jobDetail) { if (logger.isDebugEnabled()) { logger.debug("Quartz job " + jobDetail.getKey() + " added. "); } } @Override public void jobDeleted(JobKey jobKey) { if (logger.isDebugEnabled()) { logger.debug("Quartz job " + jobKey + " deleted "); } } @Override public void jobPaused(JobKey jobKey) { if (logger.isDebugEnabled()) { logger.debug("Quartz job " + jobKey + " paused "); } } @Override public void jobsPaused(String jobGroup) { if (logger.isDebugEnabled()) { logger.debug("Quartz job Group " + jobGroup + " paused "); } } @Override public void jobResumed(JobKey jobKey) { if (logger.isDebugEnabled()) { logger.debug("Quartz job " + jobKey + " resumed "); } } @Override public void jobsResumed(String jobGroup) { if (logger.isDebugEnabled()) { logger.debug("Quartz job Group " + jobGroup +" resumed "); } } @Override public void schedulerError(String msg, SchedulerException cause) { if (logger.isInfoEnabled()) { logger.info("Quartz scheduler error: " + msg, cause); } } @Override public void schedulerInStandbyMode() { if (logger.isDebugEnabled()) { logger.debug("Quartz Scheduler in standby mode "); } } @Override public void schedulerStarted() { if (logger.isDebugEnabled()) { logger.debug("Quartz Scheduler started"); } } @Override public void schedulerShutdown() { if (logger.isDebugEnabled()) { logger.debug("Quartz Scheduler shutting down"); } } @Override public void schedulerShuttingdown() { if (logger.isInfoEnabled()) { logger.info("Quartz scheduler shutdown"); } } @Override public void schedulingDataCleared() { if (logger.isDebugEnabled()) { logger.debug("Quartz Scheduler Data Cleared"); } } } protected class SchedulerTriggerListener implements TriggerListener { private final String name; public SchedulerTriggerListener(String name) { this.name = name; } @Override public String getName() { return name; } @Override public void triggerFired(Trigger trigger, JobExecutionContext context) { if (logger.isDebugEnabled()) { logger.debug("Quartz trigger fired " + trigger.getKey()); } } @Override public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) { return false; } @Override public void triggerMisfired(Trigger trigger) { if (logger.isDebugEnabled()) { logger.debug("Quartz trigger misfired " + trigger.getKey()); } if (trigger.getKey().getGroup().equals(GROUP) && trigger.getFireTimeAfter(new Date()) == null) { try { getTriggerFinalized(trigger); } catch (BaseException e) { e.printStackTrace(); } } } @Override public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) { if (logger.isDebugEnabled()) { logger.debug("Quartz trigger complete " + trigger.getKey() + " triggerInstructionCode=" + triggerInstructionCode); } } } /* * 校验Job */ @SuppressWarnings("rawtypes") public void validate(JobInfo job, ValidationErrorsable errors) throws BaseException { Trigger quartzTrigger = createTrigger(job); AbstractTrigger abstrTrigger = (AbstractTrigger) quartzTrigger; Date firstFireTime = abstrTrigger.computeFirstFireTime(null); if (firstFireTime == null) { errors.add(new ValidationError("error.report.job.trigger.no.fire", null, null, "trigger")); } } @Override public void pauseJob(Long jobId) throws BaseException { try{ Trigger trigger = getJobTrigger(jobId); TriggerState quartzState = scheduler.getTriggerState(trigger.getKey()); if (quartzState == TriggerState.NORMAL){ scheduler.pauseTrigger(trigger.getKey()); if (logger.isDebugEnabled()){ logger.debug("暂停工作任务 " + GROUP + "." + jobId); } // }else{ // logger.error("暂停工作任务 " + GROUP + "." + jobId + " 必须处于正常状态"); // throw new BaseException("任务必须处于正常状态才能暂停","任务必须处于正常状态才能暂停"); } }catch (SchedulerException e) { logger.error("暂停Quartz任务时错误", e); throw new BaseException("暂停Quartz任务时错误", "暂停Quartz任务时错误"); } } @Override public void resumedJob(Long jobId) throws BaseException { try{ Trigger trigger = getJobTrigger(jobId); TriggerState quartzState = scheduler.getTriggerState(trigger.getKey()); if (quartzState == Trigger.TriggerState.PAUSED){ scheduler.resumeTrigger(trigger.getKey()); if (logger.isDebugEnabled()){ logger.info("恢复工作任务 " + GROUP + "." + jobId); } // }else{ // logger.error("恢复工作任务 " + GROUP + "." + jobId + " 必须处于暂停状态"); // throw new BaseException("任务必须处于暂停状态才能恢复" ,"任务必须处于暂停状态才能恢复"); } }catch (SchedulerException e) { logger.error("恢复Quartz任务时错误", e); throw new BaseException("恢复Quartz任务时错误", "恢复Quartz任务时错误"); } } }