org.n3r.quartz.glass.job.GlassJobFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quartz-glass Show documentation
Show all versions of quartz-glass Show documentation
A web user interface for quartz
package org.n3r.quartz.glass.job;
import org.n3r.quartz.glass.configuration.Configuration;
import org.n3r.quartz.glass.configuration.InjectionType;
import org.n3r.quartz.glass.util.GlassConstants;
import org.n3r.quartz.glass.web.util.PojoJobMeta;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.AbstractPropertyAccessor;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean.MethodInvokingJob;
@Component
@SuppressWarnings("unchecked")
public class GlassJobFactory implements JobFactory {
@Autowired
private Configuration configuration;
@Autowired
AutowireCapableBeanFactory beanFactory;
@Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException {
try {
Job job = createJob(bundle);
populateTriggerDataMapTargetObject(bundle, job);
return job;
} catch (Exception e) {
throw new SchedulerException(e);
}
}
private synchronized Job createJob(TriggerFiredBundle bundle) throws Exception {
Class extends Job> jobClass = bundle.getJobDetail().getJobClass();
try {
Job job = beanFactory.getBean(jobClass);
setTargetObject(job, bundle, false);
return job;
} catch (NoSuchBeanDefinitionException e) {
// ignore
}
try {
Job job = jobClass.newInstance();
beanFactory.autowireBean(job);
setTargetObject(job, bundle, true);
return job;
} catch (Exception e) {
throw new SchedulerException("Problem instantiating class '" + bundle.getJobDetail().getJobClass().getName() + "'", e);
}
}
private void setTargetObject(Job job, TriggerFiredBundle bundle, boolean forceCreateObject) throws Exception {
PojoJobMeta pojoJobMeta = getPojoJobMeta(bundle.getJobDetail());
if (pojoJobMeta == null) return;
if (pojoJobMeta.getTargetObject() != null && !forceCreateObject) return;
Object targetObject;
Class targetClass = pojoJobMeta.getTargetClass();
try {
targetObject = beanFactory.getBean(targetClass);
} catch (NoSuchBeanDefinitionException e) {
targetObject = targetClass.newInstance();
beanFactory.autowireBean(targetObject);
}
populateJobDataMapTargetObject(bundle, targetObject);
pojoJobMeta.setTargetObject(targetObject);
MethodInvokingJobDetailFactoryBean methodInvoker = createMethodInvoker(pojoJobMeta);
methodInvoker.setTargetObject(targetObject);
MethodInvokingJob methodInvokingJob = (MethodInvokingJob) job;
methodInvokingJob.setMethodInvoker(methodInvoker);
}
private void populateJobDataMapTargetObject(TriggerFiredBundle bundle, Object targetObject) {
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
buildAccessor(targetObject).setPropertyValues(pvs, true);
}
private void populateTriggerDataMapTargetObject(TriggerFiredBundle bundle, Job job) {
PojoJobMeta pojoJobMeta = getPojoJobMeta(bundle.getJobDetail());
Object targetObject = pojoJobMeta == null ? job : pojoJobMeta.getTargetObject();
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
buildAccessor(targetObject).setPropertyValues(pvs, true);
}
private MethodInvokingJobDetailFactoryBean createMethodInvoker(PojoJobMeta pojoJobMeta) throws Exception {
MethodInvokingJobDetailFactoryBean factoryBean = new MethodInvokingJobDetailFactoryBean();
factoryBean.setGroup(pojoJobMeta.getGroup());
factoryBean.setName(pojoJobMeta.getName());
factoryBean.setTargetClass(pojoJobMeta.getTargetClass());
factoryBean.setTargetMethod(pojoJobMeta.getTargetMethod());
factoryBean.setConcurrent(pojoJobMeta.isConcurrent());
factoryBean.afterPropertiesSet();
return factoryBean;
}
private PojoJobMeta getPojoJobMeta(JobDetail jobDetail) {
return (PojoJobMeta) jobDetail.getJobDataMap().get(GlassConstants.POJO_JOB_META);
}
private AbstractPropertyAccessor buildAccessor(Object job) {
boolean injectType = configuration.getInjectionType() == InjectionType.FIELD;
AbstractPropertyAccessor accessor = injectType ? new DirectFieldAccessor(job) : new BeanWrapperImpl(job);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(configuration.getDateFormat());
CustomDateEditor customDateEditor = new CustomDateEditor(simpleDateFormat, true);
accessor.registerCustomEditor(Date.class, customDateEditor);
return accessor;
}
}