package li.task; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.xml.xpath.XPathConstants; import li.util.Files; import li.util.Log; import li.util.Reflect; import org.quartz.CronTrigger; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.impl.JobDetailImpl; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.triggers.CronTriggerImpl; import org.w3c.dom.NodeList; /** * Quartz * * @author li (limingwei@mail.com) * @version 0.1.1 (2013-03-19) */ public class Quartz { private static final Log log = Log.init(); private static final String TASK_CONFIG_REGEX = "^.*(config|task|quartz)\\.xml$"; private static final Integer DELAY = Integer.valueOf(Files.config().getProperty("quartz_delay", "10")); private static Scheduler scheduler = null; /** * 初始化此类的时候启动Quartz,唯一的public方法 */ public Quartz() { log.debug("Quartz will be started in default ? seconds", DELAY); new Thread() {// 新开一个线程 public void run() { try { Thread.sleep(DELAY * 1000);// 延迟启动定时任务 log.debug("Starting Quartz ..."); _start(); } catch (Exception e) { log.error("Error when starting Quartz"); throw new RuntimeException(e); } }; }.start(); } /** * Quartz是否正在运行 */ public static Boolean isOn() { try { return null != scheduler && scheduler.isStarted(); } catch (SchedulerException e) { return false; } } /** * 启动Quartz,启动所有任务,synchronized方法 */ private synchronized static void _start() throws Exception { if (null == scheduler) {// 只开始一次 scheduler = getScheduler(); Set<Entry<Class<? extends Job>, String>> jobs = getJobs().entrySet(); for (Entry<Class<? extends Job>, String> entry : jobs) { String name = entry.getKey().getName();// 类名作为name,使用默认的GROUP JobDetail jobDetail = new JobDetailImpl(name, Scheduler.DEFAULT_GROUP, entry.getKey()); CronTrigger cronTrigger = new CronTriggerImpl(name, Scheduler.DEFAULT_GROUP, entry.getValue()); scheduler.scheduleJob(jobDetail, cronTrigger); log.info("Adding task ? , trigger ? ", entry.getKey(), entry.getValue()); } scheduler.start(); } else { throw new RuntimeException("已经启动Quartz,不要多次启动"); } } /** * 返回使用Ioc方式生成Job对象的Scheduler */ private static Scheduler getScheduler() throws SchedulerException { Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.setJobFactory(new LiJobFactory()); return scheduler; } /** * 扫描以config.xml或task.xml或quartz.xml结尾的Quartz配置文件返回所有任务 */ private static Map<Class<? extends Job>, String> getJobs() { Map<Class<? extends Job>, String> jobs = new HashMap<Class<? extends Job>, String>(); File rootFolder = Files.root(); List<String> fileList = Files.list(rootFolder, TASK_CONFIG_REGEX, true, 1);// 搜索配置文件 log.info("Found ? quartz task xml config files, at ?", fileList.size(), rootFolder); for (String filePath : fileList) { NodeList beanNodes = (NodeList) Files.xpath(Files.build(filePath), "//task", XPathConstants.NODESET); for (int length = (null == beanNodes ? -1 : beanNodes.getLength()), i = 0; i < length; i++) { String type = (String) Files.xpath(beanNodes.item(i), "@class", XPathConstants.STRING); String trigger = (String) Files.xpath(beanNodes.item(i), "@trigger", XPathConstants.STRING); jobs.put((Class<? extends Job>) Reflect.getType(type), trigger); } } return jobs; } }