All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.n3r.quartz.glass.job.GlassJobFactory Maven / Gradle / Ivy

There is a newer version: 0.0.9
Show newest version
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 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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy