📄 jobschedulingdataprocessor.java
字号:
/* * Copyright James House (c) 2001-2004 * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: 1. * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. 2. Redistributions in * binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */package org.quartz.xml;import java.beans.PropertyDescriptor;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.TimeZone;import javax.xml.parsers.ParserConfigurationException;import org.apache.commons.beanutils.ConversionException;import org.apache.commons.beanutils.Converter;import org.apache.commons.beanutils.DynaBean;import org.apache.commons.beanutils.DynaProperty;import org.apache.commons.beanutils.PropertyUtils;import org.apache.commons.digester.BeanPropertySetterRule;import org.apache.commons.digester.Digester;import org.apache.commons.digester.RuleSetBase;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.quartz.CronTrigger;import org.quartz.JobDataMap;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SimpleTrigger;import org.quartz.Trigger;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import org.xml.sax.helpers.DefaultHandler;/** * Parses an XML file that declares Jobs and their schedules (Triggers). * * The xml document must conform to the format defined in * "job_scheduling_data_1_0.dtd" or "job_scheduling_data_1_1.xsd" * * After creating an instance of this class, you should call one of the <code>processFile()</code> * functions, after which you may call the <code>getScheduledJobs()</code> * function to get a handle to the defined Jobs and Triggers, which can then be * scheduled with the <code>Scheduler</code>. Alternatively, you could call * the <code>processFileAndScheduleJobs()</code> function to do all of this * in one step. * * The same instance can be used again and again, with the list of defined Jobs * being cleared each time you call a <code>processFile</code> method, * however a single instance is not thread-safe. * * @author <a href="mailto:bonhamcm@thirdeyeconsulting.com">Chris Bonham</a> * @author James House */public class JobSchedulingDataProcessor extends DefaultHandler { /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constants. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ public static final String QUARTZ_PUBLIC_ID = "-//Quartz Enterprise Job Scheduler//DTD Job Scheduling Data 1.0//EN"; public static final String QUARTZ_SYSTEM_ID = "http://www.quartzscheduler.org/dtd/job_scheduling_data_1_0.dtd"; public static final String QUARTZ_DTD = "/org/quartz/xml/job_scheduling_data_1_0.dtd"; public static final String QUARTZ_NS = "http://www.quartzscheduler.org/ns/quartz"; public static final String QUARTZ_SCHEMA = "http://www.quartzscheduler.org/ns/quartz/job_scheduling_data_1_1.xsd"; public static final String QUARTZ_XSD = "/org/quartz/xml/job_scheduling_data_1_1.xsd"; public static final String QUARTZ_SYSTEM_ID_DIR_PROP = "quartz.system.id.dir"; public static final String QUARTZ_XML_FILE_NAME = "quartz_jobs.xml"; public static final String QUARTZ_SYSTEM_ID_PREFIX = "jar:"; protected static final String TAG_QUARTZ = "quartz"; protected static final String TAG_OVERWRITE_EXISTING_JOBS = "overwrite-existing-jobs"; protected static final String TAG_CALENDAR = "calendar"; protected static final String TAG_CLASS_NAME = "class-name"; protected static final String TAG_DESCRIPTION = "description"; protected static final String TAG_BASE_CALENDAR = "base-calendar"; protected static final String TAG_MISFIRE_INSTRUCTION = "misfire-instruction"; protected static final String TAG_CALENDAR_NAME = "calendar-name"; protected static final String TAG_JOB = "job"; protected static final String TAG_JOB_DETAIL = "job-detail"; protected static final String TAG_NAME = "name"; protected static final String TAG_GROUP = "group"; protected static final String TAG_JOB_CLASS = "job-class"; protected static final String TAG_VOLATILITY = "volatility"; protected static final String TAG_DURABILITY = "durability"; protected static final String TAG_RECOVER = "recover"; protected static final String TAG_JOB_DATA_MAP = "job-data-map"; protected static final String TAG_ENTRY = "entry"; protected static final String TAG_KEY = "key"; protected static final String TAG_ALLOWS_TRANSIENT_DATA = "allows-transient-data"; protected static final String TAG_VALUE = "value"; protected static final String TAG_TRIGGER = "trigger"; protected static final String TAG_SIMPLE = "simple"; protected static final String TAG_CRON = "cron"; protected static final String TAG_JOB_NAME = "job-name"; protected static final String TAG_JOB_GROUP = "job-group"; protected static final String TAG_START_TIME = "start-time"; protected static final String TAG_END_TIME = "end-time"; protected static final String TAG_REPEAT_COUNT = "repeat-count"; protected static final String TAG_REPEAT_INTERVAL = "repeat-interval"; protected static final String TAG_CRON_EXPRESSION = "cron-expression"; protected static final String TAG_TIME_ZONE = "time-zone"; /** * XML Schema dateTime datatype format. * <p> * See <a href="http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#dateTime"> * http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#dateTime</a> */ protected static final String XSD_DATE_FORMAT = "yyyy-MM-dd'T'hh:mm:ss"; /** * Legacy DTD version 1.0 date format. */ protected static final String DTD_DATE_FORMAT = "yyyy-MM-dd hh:mm:ss a"; /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Data members. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ protected Map scheduledJobs = new HashMap(); protected List jobsToSchedule = new LinkedList(); protected List calsToSchedule = new LinkedList(); protected Collection validationExceptions = new ArrayList(); protected Digester digester; private boolean overWriteExistingJobs = true; private ThreadLocal schedLocal = new ThreadLocal(); /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Constructors. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * Constructor for QuartzMetaDataProcessor. */ public JobSchedulingDataProcessor() { this(true, true, true); } /** * Constructor for QuartzMetaDataProcessor. * * @param useContextClassLoader whether or not to use the context class loader. * @param validating whether or not to validate XML. * @param validatingSchema whether or not to validate XML schema. */ public JobSchedulingDataProcessor(boolean useContextClassLoader, boolean validating, boolean validatingSchema) { initDigester(useContextClassLoader, validating, validatingSchema); } /** * Initializes the digester. * * @param useContextClassLoader whether or not to use the context class loader. * @param validating whether or not to validate XML. * @param validatingSchema whether or not to validate XML schema. */ protected void initDigester(boolean useContextClassLoader, boolean validating, boolean validatingSchema) { digester = new Digester(); digester.setNamespaceAware(true); digester.setUseContextClassLoader(useContextClassLoader); digester.setValidating(validating); initSchemaValidation(validatingSchema); digester.setEntityResolver(this); digester.setErrorHandler(this); digester.addSetProperties(TAG_QUARTZ, TAG_OVERWRITE_EXISTING_JOBS, "overWriteExistingJobs"); digester.addRuleSet(new CalendarRuleSet(TAG_QUARTZ + "/" + TAG_CALENDAR, "addCalendarToSchedule")); digester.addRuleSet(new CalendarRuleSet("*/" + TAG_BASE_CALENDAR, "setBaseCalendar")); digester.addObjectCreate(TAG_QUARTZ + "/" + TAG_JOB, JobSchedulingBundle.class); digester.addObjectCreate(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL, JobDetail.class); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_NAME, "name"); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_GROUP, "group"); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_CLASS, "jobClass"); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_VOLATILITY, "volatility"); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_DURABILITY, "durability"); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_RECOVER, "requestsRecovery"); digester.addObjectCreate(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_DATA_MAP, JobDataMap.class); digester.addSetProperties(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_DATA_MAP, TAG_ALLOWS_TRANSIENT_DATA, "allowsTransientData"); digester.addCallMethod(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_DATA_MAP + "/" + TAG_ENTRY, "put", 2, new Class[] { Object.class, Object.class }); digester.addCallParam(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_DATA_MAP + "/" + TAG_ENTRY + "/" + TAG_KEY, 0); digester.addCallParam(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_DATA_MAP + "/" + TAG_ENTRY + "/" + TAG_VALUE, 1); digester.addSetNext(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_DATA_MAP, "setJobDataMap"); digester.addSetNext(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL, "setJobDetail"); digester.addRuleSet(new TriggerRuleSet(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_SIMPLE, SimpleTrigger.class)); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_SIMPLE + "/" + TAG_REPEAT_COUNT, "repeatCount"); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_SIMPLE + "/" + TAG_REPEAT_INTERVAL, "repeatInterval"); digester.addSetNext(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_SIMPLE, "addTrigger"); digester.addRuleSet(new TriggerRuleSet(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_CRON, CronTrigger.class)); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_CRON + "/" + TAG_CRON_EXPRESSION, "cronExpression"); digester.addRule(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_CRON + "/" + TAG_TIME_ZONE, new SimpleConverterRule("timeZone", new TimeZoneConverter(), TimeZone.class)); digester.addSetNext(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_TRIGGER + "/" + TAG_CRON, "addTrigger"); digester.addSetNext(TAG_QUARTZ + "/" + TAG_JOB, "addJobToSchedule"); } /** * Initializes the digester for XML Schema validation. * * @param validating whether or not to validate XML. */ protected void initSchemaValidation(boolean validatingSchema) { if (validatingSchema) { String schemaUri = null; URL url = getClass().getResource(QUARTZ_XSD); if (url != null) { schemaUri = url.toExternalForm(); } else { schemaUri = QUARTZ_SCHEMA; } digester.setSchema(schemaUri); } } protected static Log getLog() { return LogFactory.getLog(JobSchedulingDataProcessor.class); } /** * Returns whether to use the context class loader. * * @return whether to use the context class loader. */ public boolean getUseContextClassLoader() { return digester.getUseContextClassLoader(); } /** * Sets whether to use the context class loader. * * @param useContextClassLoader boolean. */ public void setUseContextClassLoader(boolean useContextClassLoader) { digester.setUseContextClassLoader(useContextClassLoader); } /** * Returns whether to overwrite existing jobs. * * @return whether to overwrite existing jobs. */ public boolean getOverWriteExistingJobs() { return overWriteExistingJobs; } /** * Sets whether to overwrite existing jobs. * * @param overWriteExistingJobs boolean. */ public void setOverWriteExistingJobs(boolean overWriteExistingJobs) { this.overWriteExistingJobs = overWriteExistingJobs; } /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * Process the xml file in the default location (a file named * "quartz_jobs.xml" in the current working directory). * */ public void processFile() throws Exception { processFile(QUARTZ_XML_FILE_NAME); } /** * Process the xml file named <code>fileName</code>. * * @param fileName * meta data file name. */ public void processFile(String fileName) throws Exception { processFile(fileName, fileName); } /** * Process the xmlfile named <code>fileName</code> with the given system * ID. * * @param fileName * meta data file name. * @param systemId * system ID. */ public void processFile(String fileName, String systemId) throws ValidationException, ParserConfigurationException, SAXException, IOException, SchedulerException, ClassNotFoundException, ParseException { clearValidationExceptions(); scheduledJobs.clear(); jobsToSchedule.clear(); calsToSchedule.clear(); getLog().info("Parsing XML file: " + fileName + " with systemId: " + systemId + " validating: " + digester.getValidating() + " validating schema: " + digester.getSchema()); InputSource is = new InputSource(getInputStream(fileName)); is.setSystemId(systemId); digester.push(this); digester.parse(is);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -