?? jobschedulingdataprocessor.java
字號:
/* * Copyright 2004-2005 OpenSymphony * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * *//* * Previously Copyright (c) 2001-2004 James House */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.JobListener;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_2.dtd" or "job_scheduling_data_1_2.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.5//EN"; public static final String QUARTZ_SYSTEM_ID = "http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.dtd"; public static final String QUARTZ_DTD = "/org/quartz/xml/job_scheduling_data_1_5.dtd"; public static final String QUARTZ_NS = "http://www.opensymphony.com/quartz/JobSchedulingData"; public static final String QUARTZ_SCHEMA = "http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd"; public static final String QUARTZ_XSD = "/org/quartz/xml/job_scheduling_data_1_5.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_JOB_LISTENER = "job-listener"; 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_JOB_LISTENER_REF = "job-listener-ref"; 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 List listenersToSchedule = 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); if(addCustomDigesterRules(digester)) addDefaultDigesterRules(digester); } /** * Add the default set of digest rules */ protected void addDefaultDigesterRules(Digester digester) { digester.addSetProperties(TAG_QUARTZ, TAG_OVERWRITE_EXISTING_JOBS, "overWriteExistingJobs"); digester.addObjectCreate(TAG_QUARTZ + "/" + TAG_JOB_LISTENER, "jobListener","class-name"); digester.addCallMethod(TAG_QUARTZ + "/" + TAG_JOB_LISTENER,"setName",1); digester.addCallParam(TAG_QUARTZ + "/" + TAG_JOB_LISTENER,0,"name"); digester.addSetNext(TAG_QUARTZ + "/" + TAG_JOB_LISTENER,"addListenerToSchedule"); 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_DESCRIPTION, "description"); digester.addBeanPropertySetter(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_CLASS, "jobClass"); digester.addCallMethod(TAG_QUARTZ + "/" + TAG_JOB + "/" + TAG_JOB_DETAIL + "/" + TAG_JOB_LISTENER_REF,"addJobListener",0 ); 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"); } /** * Template method provided as a hook for those who wish to extend this * class and add more functionality. * * This method is invoked after the Digester is instantiated, and before * the default set of rules are added. * * @param digester * @return false, if the default rules should NOT be added */ protected boolean addCustomDigesterRules(Digester digester) { // do nothing in base impl return true; } /** * Initializes the digester for XML Schema validation. *
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -