dnet-core/dnet-core-components/src/main/java/eu/dnetlib/enabling/tools/AbstractSchedulable.java

192 lines
4.4 KiB
Java

package eu.dnetlib.enabling.tools;
import java.text.ParseException;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.quartz.*;
import org.quartz.Trigger.TriggerState;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Required;
/**
* Common implementation for schedulable beans.
*
* @author claudio
*
*/
public abstract class AbstractSchedulable implements Schedulable, Job, BeanNameAware {
private static final String THIS = "this";
private final static String GROUP = "schedulableJobs";
private boolean enabled;
private CronExpression cronExpression;
private String beanName;
@Resource(name = "dnetJobScheduler")
private Scheduler jobScheduler;
@PostConstruct
protected void init() {
try {
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put(THIS, this);
JobDetailImpl jd = new JobDetailImpl();
jd.setName(getBeanName());
jd.setGroup(GROUP);
jd.setJobDataMap(jobDataMap);
jd.setJobClass(this.getClass());
jobScheduler.scheduleJob(jd, createTrigger());
} catch (SchedulerException e) {
throw new RuntimeException(e);
}
}
private Trigger createTrigger() {
try {
CronTriggerImpl trigger = new CronTriggerImpl(getBeanName(), GROUP, getCronExpression());
trigger.setMisfireInstruction(Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY);
trigger.setJobGroup(GROUP);
trigger.setJobName(getBeanName());
return trigger;
} catch (ParseException e) {
throw new IllegalArgumentException("invalid cron expression: " + cronExpression, e);
}
}
protected abstract void doExecute();
@Override
public void execute() {
// bean represents the quartz instance of this object
if (isEnabled()) {
doExecute();
}
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
AbstractSchedulable bean = (AbstractSchedulable) context.getJobDetail().getJobDataMap().get(THIS);
// bean represents the quartz instance of this object
if (bean.isEnabled()) {
bean.doExecute();
}
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Override
public String getCronExpression() {
return cronExpression.getCronExpression();
}
@Required
public void setCronExpression(String cronExpression) {
try {
this.cronExpression = new CronExpression(cronExpression);
} catch (ParseException e) {
throw new IllegalArgumentException("invalid cron expression: " + cronExpression, e);
}
}
@Override
public void updateCronExpression(String cronExpression) {
if (!cronExpression.equals(getCronExpression())) {
setCronExpression(cronExpression);
try {
final TriggerKey tk = new TriggerKey(getBeanName());
jobScheduler.rescheduleJob(tk, createTrigger());
} catch (SchedulerException e) {
throw new RuntimeException("unable to reschedule trigger", e);
}
}
}
@Override
public String getNextFireTime() {
try {
if (isPaused()) {
return "";
}
if (!isEnabled()) {
return "";
}
final TriggerKey tk = new TriggerKey(getBeanName());
final Trigger t = jobScheduler.getTrigger(tk);
return t != null ? t.getNextFireTime().toString() : "";
} catch (SchedulerException e) {
throw new RuntimeException("unable to get trigger", e);
}
}
@Override
public boolean isPaused() {
try {
final TriggerKey tk = new TriggerKey(getBeanName());
final TriggerState state = jobScheduler.getTriggerState(tk);
switch (state) {
case PAUSED:
case NONE:
case ERROR:
return true;
default:
return false;
}
} catch (SchedulerException e) {
throw new RuntimeException("unable to get trigger", e);
}
}
@Override
public void pause() {
try {
final TriggerKey tk = new TriggerKey(getBeanName());
jobScheduler.pauseTrigger(tk);
} catch (SchedulerException e) {
throw new RuntimeException("unable to pause trigger", e);
}
}
@Override
public void resume() {
try {
final TriggerKey tk = new TriggerKey(getBeanName());
jobScheduler.resumeTrigger(tk);
} catch (SchedulerException e) {
throw new RuntimeException("unable to resume trigger", e);
}
}
public String getBeanName() {
return beanName;
}
@Override
@Required
public void setBeanName(String beanName) {
this.beanName = beanName;
}
}