diff --git a/fine-quartz-old/pom.xml b/fine-quartz-old/pom.xml
index 01fca6b85..f42075c1d 100644
--- a/fine-quartz-old/pom.xml
+++ b/fine-quartz-old/pom.xml
@@ -14,5 +14,26 @@
fine-quartz-old
${revision}
-
+
+
+ com.fr.third
+ fine-commons-logging
+ ${revision}
+
+
+ com.fr.third
+ fine-javax-transaction
+ ${revision}
+
+
+ com.fr.third
+ fine-mail
+ ${revision}
+
+
+ com.fr.third
+ fine-druid
+ ${revision}
+
+
\ No newline at end of file
diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/plugins/xml/XMLSchedulingDataProcessorPlugin.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/plugins/xml/XMLSchedulingDataProcessorPlugin.java
deleted file mode 100644
index 9016c35b9..000000000
--- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/plugins/xml/XMLSchedulingDataProcessorPlugin.java
+++ /dev/null
@@ -1,426 +0,0 @@
-/*
- * Copyright 2001-2010 Terracotta, Inc.
- *
- * 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.
- *
- */
-
-package com.fr.third.v2.org.quartz.plugins.xml;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import javax.transaction.UserTransaction;
-
-import com.fr.third.v2.org.quartz.JobDetail;
-import com.fr.third.v2.org.quartz.Scheduler;
-import com.fr.third.v2.org.quartz.SchedulerConfigException;
-import com.fr.third.v2.org.quartz.SchedulerException;
-import com.fr.third.v2.org.quartz.SimpleTrigger;
-import com.fr.third.v2.org.quartz.plugins.SchedulerPluginWithUserTransactionSupport;
-import com.fr.third.v2.org.quartz.JobBuilder;
-import com.fr.third.v2.org.quartz.SimpleScheduleBuilder;
-import com.fr.third.v2.org.quartz.TriggerBuilder;
-import com.fr.third.v2.org.quartz.TriggerKey;
-import com.fr.third.v2.org.quartz.jobs.FileScanJob;
-import com.fr.third.v2.org.quartz.jobs.FileScanListener;
-import com.fr.third.v2.org.quartz.xml.XMLSchedulingDataProcessor;
-import com.fr.third.v2.org.quartz.spi.ClassLoadHelper;
-
-import static com.fr.third.v2.org.quartz.JobBuilder.newJob;
-
-/**
- * This plugin loads XML file(s) to add jobs and schedule them with triggers
- * as the scheduler is initialized, and can optionally periodically scan the
- * file for changes.
- *
- *
The XML schema definition can be found here:
- * http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd
- *
- *
- * The periodically scanning of files for changes is not currently supported in a
- * clustered environment.
- *
- *
- *
- * If using this plugin with JobStoreCMT, be sure to set the
- * plugin property wrapInUserTransaction to true. Also, if you have a
- * positive scanInterval be sure to set
- * org.quartz.scheduler.wrapJobExecutionInUserTransaction to true.
- *
- *
- * @see XMLSchedulingDataProcessor
- *
- * @author James House
- * @author Pierre Awaragi
- * @author pl47ypus
- */
-public class XMLSchedulingDataProcessorPlugin
- extends SchedulerPluginWithUserTransactionSupport
- implements FileScanListener {
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
- private static final int MAX_JOB_TRIGGER_NAME_LEN = 80;
- private static final String JOB_INITIALIZATION_PLUGIN_NAME = "JobSchedulingDataLoaderPlugin";
- private static final String FILE_NAME_DELIMITERS = ",";
-
- private boolean failOnFileNotFound = true;
-
- private String fileNames = XMLSchedulingDataProcessor.QUARTZ_XML_DEFAULT_FILE_NAME;
-
- // Populated by initialization
- private Map jobFiles = new LinkedHashMap();
-
- private long scanInterval = 0;
-
- boolean started = false;
-
- protected ClassLoadHelper classLoadHelper = null;
-
- private Set jobTriggerNameSet = new HashSet();
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- public XMLSchedulingDataProcessorPlugin() {
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- * Comma separated list of file names (with paths) to the XML files that should be read.
- */
- public String getFileNames() {
- return fileNames;
- }
-
- /**
- * The file name (and path) to the XML file that should be read.
- */
- public void setFileNames(String fileNames) {
- this.fileNames = fileNames;
- }
-
- /**
- * The interval (in seconds) at which to scan for changes to the file.
- * If the file has been changed, it is re-loaded and parsed. The default
- * value for the interval is 0, which disables scanning.
- *
- * @return Returns the scanInterval.
- */
- public long getScanInterval() {
- return scanInterval / 1000;
- }
-
- /**
- * The interval (in seconds) at which to scan for changes to the file.
- * If the file has been changed, it is re-loaded and parsed. The default
- * value for the interval is 0, which disables scanning.
- *
- * @param scanInterval The scanInterval to set.
- */
- public void setScanInterval(long scanInterval) {
- this.scanInterval = scanInterval * 1000;
- }
-
- /**
- * Whether or not initialization of the plugin should fail (throw an
- * exception) if the file cannot be found. Default is true
.
- */
- public boolean isFailOnFileNotFound() {
- return failOnFileNotFound;
- }
-
- /**
- * Whether or not initialization of the plugin should fail (throw an
- * exception) if the file cannot be found. Default is true
.
- */
- public void setFailOnFileNotFound(boolean failOnFileNotFound) {
- this.failOnFileNotFound = failOnFileNotFound;
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * SchedulerPlugin Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- *
- * Called during creation of the Scheduler
in order to give
- * the SchedulerPlugin
a chance to initialize.
- *
- *
- * @throws SchedulerConfigException
- * if there is an error initializing.
- */
- public void initialize(String name, final Scheduler scheduler, ClassLoadHelper schedulerFactoryClassLoadHelper)
- throws SchedulerException {
- super.initialize(name, scheduler);
- this.classLoadHelper = schedulerFactoryClassLoadHelper;
-
- getLog().info("Registering Quartz Job Initialization Plug-in.");
-
- // Create JobFile objects
- StringTokenizer stok = new StringTokenizer(fileNames, FILE_NAME_DELIMITERS);
- while (stok.hasMoreTokens()) {
- final String fileName = stok.nextToken();
- final JobFile jobFile = new JobFile(fileName);
- jobFiles.put(fileName, jobFile);
- }
- }
-
-
- @Override
- public void start(UserTransaction userTransaction) {
- try {
- if (jobFiles.isEmpty() == false) {
-
- if (scanInterval > 0) {
- getScheduler().getContext().put(JOB_INITIALIZATION_PLUGIN_NAME + '_' + getName(), this);
- }
-
- Iterator iterator = jobFiles.values().iterator();
- while (iterator.hasNext()) {
- JobFile jobFile = iterator.next();
-
- if (scanInterval > 0) {
- String jobTriggerName = buildJobTriggerName(jobFile.getFileBasename());
- TriggerKey tKey = new TriggerKey(jobTriggerName, JOB_INITIALIZATION_PLUGIN_NAME);
-
- // remove pre-existing job/trigger, if any
- getScheduler().unscheduleJob(tKey);
-
- JobDetail job = JobBuilder.newJob().withIdentity(jobTriggerName, JOB_INITIALIZATION_PLUGIN_NAME).ofType(FileScanJob.class)
- .usingJobData(FileScanJob.FILE_NAME, jobFile.getFileName())
- .usingJobData(FileScanJob.FILE_SCAN_LISTENER_NAME, JOB_INITIALIZATION_PLUGIN_NAME + '_' + getName())
- .build();
-
- SimpleTrigger trig = TriggerBuilder.newTrigger().withIdentity(tKey).withSchedule(
- SimpleScheduleBuilder.simpleSchedule().repeatForever().withIntervalInMilliseconds(scanInterval))
- .forJob(job)
- .build();
-
- getScheduler().scheduleJob(job, trig);
- getLog().debug("Scheduled file scan job for data file: {}, at interval: {}", jobFile.getFileName(), scanInterval);
- }
-
- processFile(jobFile);
- }
- }
- } catch(SchedulerException se) {
- getLog().error("Error starting background-task for watching jobs file.", se);
- } finally {
- started = true;
- }
- }
-
- /**
- * Helper method for generating unique job/trigger name for the
- * file scanning jobs (one per FileJob). The unique names are saved
- * in jobTriggerNameSet.
- */
- private String buildJobTriggerName(
- String fileBasename) {
- // Name w/o collisions will be prefix + _ + filename (with '.' of filename replaced with '_')
- // For example: JobInitializationPlugin_jobInitializer_myjobs_xml
- String jobTriggerName = JOB_INITIALIZATION_PLUGIN_NAME + '_' + getName() + '_' + fileBasename.replace('.', '_');
-
- // If name is too long (DB column is 80 chars), then truncate to max length
- if (jobTriggerName.length() > MAX_JOB_TRIGGER_NAME_LEN) {
- jobTriggerName = jobTriggerName.substring(0, MAX_JOB_TRIGGER_NAME_LEN);
- }
-
- // Make sure this name is unique in case the same file name under different
- // directories is being checked, or had a naming collision due to length truncation.
- // If there is a conflict, keep incrementing a _# suffix on the name (being sure
- // not to get too long), until we find a unique name.
- int currentIndex = 1;
- while (jobTriggerNameSet.add(jobTriggerName) == false) {
- // If not our first time through, then strip off old numeric suffix
- if (currentIndex > 1) {
- jobTriggerName = jobTriggerName.substring(0, jobTriggerName.lastIndexOf('_'));
- }
-
- String numericSuffix = "_" + currentIndex++;
-
- // If the numeric suffix would make the name too long, then make room for it.
- if (jobTriggerName.length() > (MAX_JOB_TRIGGER_NAME_LEN - numericSuffix.length())) {
- jobTriggerName = jobTriggerName.substring(0, (MAX_JOB_TRIGGER_NAME_LEN - numericSuffix.length()));
- }
-
- jobTriggerName += numericSuffix;
- }
-
- return jobTriggerName;
- }
-
- /**
- * Overriden to ignore wrapInUserTransaction because shutdown()
- * does not interact with the Scheduler
.
- */
- @Override
- public void shutdown() {
- // Since we have nothing to do, override base shutdown so don't
- // get extranious UserTransactions.
- }
-
- private void processFile(JobFile jobFile) {
- if (jobFile == null || !jobFile.getFileFound()) {
- return;
- }
-
-
- try {
- XMLSchedulingDataProcessor processor =
- new XMLSchedulingDataProcessor(this.classLoadHelper);
-
- processor.addJobGroupToNeverDelete(JOB_INITIALIZATION_PLUGIN_NAME);
- processor.addTriggerGroupToNeverDelete(JOB_INITIALIZATION_PLUGIN_NAME);
-
- processor.processFileAndScheduleJobs(
- jobFile.getFileName(),
- jobFile.getFileName(), // systemId
- getScheduler());
- } catch (Exception e) {
- getLog().error("Error scheduling jobs: " + e.getMessage(), e);
- }
- }
-
- public void processFile(String filePath) {
- processFile((JobFile)jobFiles.get(filePath));
- }
-
- /**
- * @see FileScanListener#fileUpdated(java.lang.String)
- */
- public void fileUpdated(String fileName) {
- if (started) {
- processFile(fileName);
- }
- }
-
- class JobFile {
- private String fileName;
-
- // These are set by initialize()
- private String filePath;
- private String fileBasename;
- private boolean fileFound;
-
- protected JobFile(String fileName) throws SchedulerException {
- this.fileName = fileName;
- initialize();
- }
-
- protected String getFileName() {
- return fileName;
- }
-
- protected boolean getFileFound() {
- return fileFound;
- }
-
- protected String getFilePath() {
- return filePath;
- }
-
- protected String getFileBasename() {
- return fileBasename;
- }
-
- private void initialize() throws SchedulerException {
- InputStream f = null;
- try {
- String furl = null;
-
- File file = new File(getFileName()); // files in filesystem
- if (!file.exists()) {
- URL url = classLoadHelper.getResource(getFileName());
- if(url != null) {
- try {
- furl = URLDecoder.decode(url.getPath(), "UTF-8");
- } catch (UnsupportedEncodingException e) {
- furl = url.getPath();
- }
- file = new File(furl);
- try {
- f = url.openStream();
- } catch (IOException ignor) {
- // Swallow the exception
- }
- }
- } else {
- try {
- f = new java.io.FileInputStream(file);
- }catch (FileNotFoundException e) {
- // ignore
- }
- }
-
- if (f == null) {
- if (isFailOnFileNotFound()) {
- throw new SchedulerException(
- "File named '" + getFileName() + "' does not exist.");
- } else {
- getLog().warn("File named '" + getFileName() + "' does not exist.");
- }
- } else {
- fileFound = true;
- }
- filePath = (furl != null) ? furl : file.getAbsolutePath();
- fileBasename = file.getName();
- } finally {
- try {
- if (f != null) {
- f.close();
- }
- } catch (IOException ioe) {
- getLog().warn("Error closing jobs file " + getFileName(), ioe);
- }
- }
- }
- }
-}
-
-// EOF
diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/ValidationException.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/ValidationException.java
deleted file mode 100644
index 3bb4b63ba..000000000
--- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/ValidationException.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2001-2009 Terracotta, Inc.
- *
- * 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.
- *
- */
-
-package com.fr.third.v2.org.quartz.xml;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-
-/**
- * Reports JobSchedulingDataLoader validation exceptions.
- *
- * @author Chris Bonham
- */
-public class ValidationException extends Exception {
-
- private static final long serialVersionUID = -1697832087051681357L;
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- private Collection validationExceptions = new ArrayList();
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- * Constructor for ValidationException.
- */
- public ValidationException() {
- super();
- }
-
- /**
- * Constructor for ValidationException.
- *
- * @param message
- * exception message.
- */
- public ValidationException(String message) {
- super(message);
- }
-
- /**
- * Constructor for ValidationException.
- *
- * @param errors
- * collection of validation exceptions.
- */
- public ValidationException(Collection errors) {
- this();
- this.validationExceptions = Collections
- .unmodifiableCollection(validationExceptions);
- initCause(errors.iterator().next());
- }
-
-
- /**
- * Constructor for ValidationException.
- *
- * @param message
- * exception message.
- * @param errors
- * collection of validation exceptions.
- */
- public ValidationException(String message, Collection errors) {
- this(message);
- this.validationExceptions = Collections
- .unmodifiableCollection(validationExceptions);
- initCause(errors.iterator().next());
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- * Returns collection of errors.
- *
- * @return collection of errors.
- */
- public Collection getValidationExceptions() {
- return validationExceptions;
- }
-
- /**
- * Returns the detail message string.
- *
- * @return the detail message string.
- */
- @Override
- public String getMessage() {
- if (getValidationExceptions().size() == 0) { return super.getMessage(); }
-
- StringBuffer sb = new StringBuffer();
-
- boolean first = true;
-
- for (Iterator iter = getValidationExceptions().iterator(); iter
- .hasNext(); ) {
- Exception e = iter.next();
-
- if (!first) {
- sb.append('\n');
- first = false;
- }
-
- sb.append(e.getMessage());
- }
-
- return sb.toString();
- }
-
-
-}
diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/XMLSchedulingDataProcessor.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/XMLSchedulingDataProcessor.java
deleted file mode 100644
index 8bd0e53fa..000000000
--- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/XMLSchedulingDataProcessor.java
+++ /dev/null
@@ -1,1234 +0,0 @@
-/*
- * Copyright 2001-2010 Terracotta, Inc.
- *
- * 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.
- *
- */
-
-package com.fr.third.v2.org.quartz.xml;
-
-import static com.fr.third.v2.org.quartz.CronScheduleBuilder.cronSchedule;
-import static com.fr.third.v2.org.quartz.JobBuilder.newJob;
-import static com.fr.third.v2.org.quartz.TriggerKey.triggerKey;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.text.ParseException;
-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.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathException;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import com.fr.third.v2.org.quartz.DateBuilder;
-import com.fr.third.v2.org.quartz.Job;
-import com.fr.third.v2.org.quartz.JobDetail;
-import com.fr.third.v2.org.quartz.JobKey;
-import com.fr.third.v2.org.quartz.JobPersistenceException;
-import com.fr.third.v2.org.quartz.ScheduleBuilder;
-import com.fr.third.v2.org.quartz.Scheduler;
-import com.fr.third.v2.org.quartz.SchedulerException;
-import com.fr.third.v2.org.quartz.Trigger;
-import com.fr.third.v2.org.quartz.impl.matchers.GroupMatcher;
-import com.fr.third.v2.org.quartz.CalendarIntervalScheduleBuilder;
-import com.fr.third.v2.org.quartz.CronScheduleBuilder;
-import com.fr.third.v2.org.quartz.JobBuilder;
-import com.fr.third.v2.org.quartz.ObjectAlreadyExistsException;
-import com.fr.third.v2.org.quartz.SimpleScheduleBuilder;
-import com.fr.third.v2.org.quartz.TriggerBuilder;
-import com.fr.third.v2.org.quartz.TriggerKey;
-import com.fr.third.v2.org.quartz.spi.MutableTrigger;
-import com.fr.third.v2.org.quartz.spi.ClassLoadHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import javax.xml.bind.DatatypeConverter;
-
-
-/**
- * Parses an XML file that declares Jobs and their schedules (Triggers), and processes the related data.
- *
- * The xml document must conform to the format defined in
- * "job_scheduling_data_2_0.xsd"
- *
- * The same instance can be used again and again, however a single instance is not thread-safe.
- *
- * @author James House
- * @author Past contributions from Chris Bonham
- * @author Past contributions from pl47ypus
- *
- * @since Quartz 1.8
- */
-public class XMLSchedulingDataProcessor implements ErrorHandler {
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constants.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- public static final String QUARTZ_NS = "http://www.quartz-scheduler.org/xml/JobSchedulingData";
-
- public static final String QUARTZ_SCHEMA_WEB_URL = "http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd";
-
- public static final String QUARTZ_XSD_PATH_IN_JAR = "com/fr/third/v2/org/quartz/xml/job_scheduling_data_2_0.xsd";
-
- public static final String QUARTZ_XML_DEFAULT_FILE_NAME = "quartz_data.xml";
-
- public static final String QUARTZ_SYSTEM_ID_JAR_PREFIX = "jar:";
-
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data members.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- // pre-processing commands
- protected List jobGroupsToDelete = new LinkedList();
- protected List triggerGroupsToDelete = new LinkedList();
- protected List jobsToDelete = new LinkedList();
- protected List triggersToDelete = new LinkedList();
-
- // scheduling commands
- protected List loadedJobs = new LinkedList();
- protected List loadedTriggers = new LinkedList();
-
- // directives
- private boolean overWriteExistingData = true;
- private boolean ignoreDuplicates = false;
-
- protected Collection validationExceptions = new ArrayList();
-
-
- protected ClassLoadHelper classLoadHelper;
- protected List jobGroupsToNeverDelete = new LinkedList();
- protected List triggerGroupsToNeverDelete = new LinkedList();
-
- private DocumentBuilder docBuilder = null;
- private XPath xpath = null;
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- /**
- * Constructor for JobSchedulingDataLoader.
- *
- * @param clh class-loader helper to share with digester.
- * @throws ParserConfigurationException if the XML parser cannot be configured as needed.
- */
- public XMLSchedulingDataProcessor(ClassLoadHelper clh) throws ParserConfigurationException {
- this.classLoadHelper = clh;
- initDocumentParser();
- }
-
- /**
- * Initializes the XML parser.
- * @throws ParserConfigurationException
- */
- protected void initDocumentParser() throws ParserConfigurationException {
-
- DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
-
- docBuilderFactory.setNamespaceAware(true);
- docBuilderFactory.setValidating(true);
-
- docBuilderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
-
- docBuilderFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", resolveSchemaSource());
-
- docBuilder = docBuilderFactory.newDocumentBuilder();
-
- docBuilder.setErrorHandler(this);
-
- NamespaceContext nsContext = new NamespaceContext()
- {
- public String getNamespaceURI(String prefix)
- {
- if (prefix == null)
- throw new IllegalArgumentException("Null prefix");
- if (XMLConstants.XML_NS_PREFIX.equals(prefix))
- return XMLConstants.XML_NS_URI;
- if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix))
- return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
-
- if ("q".equals(prefix))
- return QUARTZ_NS;
-
- return XMLConstants.NULL_NS_URI;
- }
-
- public Iterator getPrefixes(String namespaceURI)
- {
- // This method isn't necessary for XPath processing.
- throw new UnsupportedOperationException();
- }
-
- public String getPrefix(String namespaceURI)
- {
- // This method isn't necessary for XPath processing.
- throw new UnsupportedOperationException();
- }
-
- };
-
- xpath = XPathFactory.newInstance().newXPath();
- xpath.setNamespaceContext(nsContext);
- }
-
- protected Object resolveSchemaSource() {
- InputSource inputSource;
-
- InputStream is = null;
-
- try {
- is = classLoadHelper.getResourceAsStream(QUARTZ_XSD_PATH_IN_JAR);
- } finally {
- if (is != null) {
- inputSource = new InputSource(is);
- inputSource.setSystemId(QUARTZ_SCHEMA_WEB_URL);
- log.debug("Utilizing schema packaged in local quartz distribution jar.");
- }
- else {
- log.info("Unable to load local schema packaged in quartz distribution jar. Utilizing schema online at " + QUARTZ_SCHEMA_WEB_URL);
- return QUARTZ_SCHEMA_WEB_URL;
- }
-
- }
-
- return inputSource;
- }
-
- /**
- * Whether the existing scheduling data (with same identifiers) will be
- * overwritten.
- *
- * If false, and IgnoreDuplicates
is not false, and jobs or
- * triggers with the same names already exist as those in the file, an
- * error will occur.
- *
- * @see #isIgnoreDuplicates()
- */
- public boolean isOverWriteExistingData() {
- return overWriteExistingData;
- }
-
- /**
- * Whether the existing scheduling data (with same identifiers) will be
- * overwritten.
- *
- * If false, and IgnoreDuplicates
is not false, and jobs or
- * triggers with the same names already exist as those in the file, an
- * error will occur.
- *
- * @see #setIgnoreDuplicates(boolean)
- */
- protected void setOverWriteExistingData(boolean overWriteExistingData) {
- this.overWriteExistingData = overWriteExistingData;
- }
-
- /**
- * If true (and OverWriteExistingData
is false) then any
- * job/triggers encountered in this file that have names that already exist
- * in the scheduler will be ignored, and no error will be produced.
- *
- * @see #isOverWriteExistingData()
- */
- public boolean isIgnoreDuplicates() {
- return ignoreDuplicates;
- }
-
- /**
- * If true (and OverWriteExistingData
is false) then any
- * job/triggers encountered in this file that have names that already exist
- * in the scheduler will be ignored, and no error will be produced.
- *
- * @see #setOverWriteExistingData(boolean)
- */
- public void setIgnoreDuplicates(boolean ignoreDuplicates) {
- this.ignoreDuplicates = ignoreDuplicates;
- }
-
- /**
- * Add the given group to the list of job groups that will never be
- * deleted by this processor, even if a pre-processing-command to
- * delete the group is encountered.
- */
- public void addJobGroupToNeverDelete(String group) {
- if(group != null)
- jobGroupsToNeverDelete.add(group);
- }
-
- /**
- * Remove the given group to the list of job groups that will never be
- * deleted by this processor, even if a pre-processing-command to
- * delete the group is encountered.
- */
- public boolean removeJobGroupToNeverDelete(String group) {
- return group != null && jobGroupsToNeverDelete.remove(group);
- }
-
- /**
- * Get the (unmodifiable) list of job groups that will never be
- * deleted by this processor, even if a pre-processing-command to
- * delete the group is encountered.
- */
- public List getJobGroupsToNeverDelete() {
- return Collections.unmodifiableList(jobGroupsToDelete);
- }
-
- /**
- * Add the given group to the list of trigger groups that will never be
- * deleted by this processor, even if a pre-processing-command to
- * delete the group is encountered.
- */
- public void addTriggerGroupToNeverDelete(String group) {
- if(group != null)
- triggerGroupsToNeverDelete.add(group);
- }
-
- /**
- * Remove the given group to the list of trigger groups that will never be
- * deleted by this processor, even if a pre-processing-command to
- * delete the group is encountered.
- */
- public boolean removeTriggerGroupToNeverDelete(String group) {
- if(group != null)
- return triggerGroupsToNeverDelete.remove(group);
- return false;
- }
-
- /**
- * Get the (unmodifiable) list of trigger groups that will never be
- * deleted by this processor, even if a pre-processing-command to
- * delete the group is encountered.
- */
- public List getTriggerGroupsToNeverDelete() {
- return Collections.unmodifiableList(triggerGroupsToDelete);
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-
- /**
- * Process the xml file in the default location (a file named
- * "quartz_jobs.xml" in the current working directory).
- *
- */
- protected void processFile() throws Exception {
- processFile(QUARTZ_XML_DEFAULT_FILE_NAME);
- }
-
- /**
- * Process the xml file named fileName
.
- *
- * @param fileName
- * meta data file name.
- */
- protected void processFile(String fileName) throws Exception {
- processFile(fileName, getSystemIdForFileName(fileName));
- }
-
- /**
- * For the given fileName
, attempt to expand it to its full path
- * for use as a system id.
- *
- * @see #getURL(String)
- * @see #processFile()
- * @see #processFile(String)
- * @see #processFileAndScheduleJobs(Scheduler, boolean)
- * @see #processFileAndScheduleJobs(String, Scheduler)
- */
- protected String getSystemIdForFileName(String fileName) {
- File file = new File(fileName); // files in filesystem
- if (file.exists()) {
- try {
- new FileInputStream(file).close();
- return file.toURI().toString();
- }catch (IOException ignore) {
- return fileName;
- }
- } else {
- URL url = getURL(fileName);
- if (url == null) {
- return fileName;
- } else {
- try {
- url.openStream().close();
- return url.toString();
- } catch (IOException ignore) {
- return fileName;
- }
- }
- }
- }
-
- /**
- * Returns an URL
from the fileName as a resource.
- *
- * @param fileName
- * file name.
- * @return an URL
from the fileName as a resource.
- */
- protected URL getURL(String fileName) {
- return classLoadHelper.getResource(fileName);
- }
-
- protected void prepForProcessing()
- {
- clearValidationExceptions();
-
- setOverWriteExistingData(true);
- setIgnoreDuplicates(false);
-
- jobGroupsToDelete.clear();
- jobsToDelete.clear();
- triggerGroupsToDelete.clear();
- triggersToDelete.clear();
-
- loadedJobs.clear();
- loadedTriggers.clear();
- }
-
- /**
- * Process the xmlfile named fileName
with the given system
- * ID.
- *
- * @param fileName
- * meta data file name.
- * @param systemId
- * system ID.
- */
- protected void processFile(String fileName, String systemId)
- throws ValidationException, ParserConfigurationException,
- SAXException, IOException, SchedulerException,
- ClassNotFoundException, ParseException, XPathException {
-
- prepForProcessing();
-
- log.info("Parsing XML file: " + fileName +
- " with systemId: " + systemId);
- InputSource is = new InputSource(getInputStream(fileName));
- is.setSystemId(systemId);
-
- process(is);
-
- maybeThrowValidationException();
- }
-
- /**
- * Process the xmlfile named fileName
with the given system
- * ID.
- *
- * @param stream
- * an input stream containing the xml content.
- * @param systemId
- * system ID.
- */
- public void processStreamAndScheduleJobs(InputStream stream, String systemId, Scheduler sched)
- throws ValidationException, ParserConfigurationException,
- SAXException, XPathException, IOException, SchedulerException,
- ClassNotFoundException, ParseException {
-
- prepForProcessing();
-
- log.info("Parsing XML from stream with systemId: " + systemId);
-
- InputSource is = new InputSource(stream);
- is.setSystemId(systemId);
-
- process(is);
- executePreProcessCommands(sched);
- scheduleJobs(sched);
-
- maybeThrowValidationException();
- }
-
- @SuppressWarnings("ConstantConditions")
- protected void process(InputSource is) throws SAXException, IOException, ParseException, XPathException, ClassNotFoundException {
-
- // load the document
- Document document = docBuilder.parse(is);
-
- //
- // Extract pre-processing commands
- //
-
- NodeList deleteJobGroupNodes = (NodeList) xpath.evaluate(
- "/q:job-scheduling-data/q:pre-processing-commands/q:delete-jobs-in-group",
- document, XPathConstants.NODESET);
-
- log.debug("Found " + deleteJobGroupNodes.getLength() + " delete job group commands.");
-
- for (int i = 0; i < deleteJobGroupNodes.getLength(); i++) {
- Node node = deleteJobGroupNodes.item(i);
- String t = node.getTextContent();
- if(t == null || (t = t.trim()).length() == 0)
- continue;
- jobGroupsToDelete.add(t);
- }
-
- NodeList deleteTriggerGroupNodes = (NodeList) xpath.evaluate(
- "/q:job-scheduling-data/q:pre-processing-commands/q:delete-triggers-in-group",
- document, XPathConstants.NODESET);
-
- log.debug("Found " + deleteTriggerGroupNodes.getLength() + " delete trigger group commands.");
-
- for (int i = 0; i < deleteTriggerGroupNodes.getLength(); i++) {
- Node node = deleteTriggerGroupNodes.item(i);
- String t = node.getTextContent();
- if(t == null || (t = t.trim()).length() == 0)
- continue;
- triggerGroupsToDelete.add(t);
- }
-
- NodeList deleteJobNodes = (NodeList) xpath.evaluate(
- "/q:job-scheduling-data/q:pre-processing-commands/q:delete-job",
- document, XPathConstants.NODESET);
-
- log.debug("Found " + deleteJobNodes.getLength() + " delete job commands.");
-
- for (int i = 0; i < deleteJobNodes.getLength(); i++) {
- Node node = deleteJobNodes.item(i);
-
- String name = getTrimmedToNullString(xpath, "q:name", node);
- String group = getTrimmedToNullString(xpath, "q:group", node);
-
- if(name == null)
- throw new ParseException("Encountered a 'delete-job' command without a name specified.", -1);
- jobsToDelete.add(new JobKey(name, group));
- }
-
- NodeList deleteTriggerNodes = (NodeList) xpath.evaluate(
- "/q:job-scheduling-data/q:pre-processing-commands/q:delete-trigger",
- document, XPathConstants.NODESET);
-
- log.debug("Found " + deleteTriggerNodes.getLength() + " delete trigger commands.");
-
- for (int i = 0; i < deleteTriggerNodes.getLength(); i++) {
- Node node = deleteTriggerNodes.item(i);
-
- String name = getTrimmedToNullString(xpath, "q:name", node);
- String group = getTrimmedToNullString(xpath, "q:group", node);
-
- if(name == null)
- throw new ParseException("Encountered a 'delete-trigger' command without a name specified.", -1);
- triggersToDelete.add(new TriggerKey(name, group));
- }
-
- //
- // Extract directives
- //
-
- Boolean overWrite = getBoolean(xpath,
- "/q:job-scheduling-data/q:processing-directives/q:overwrite-existing-data", document);
- if(overWrite == null) {
- log.debug("Directive 'overwrite-existing-data' not specified, defaulting to " + isOverWriteExistingData());
- }
- else {
- log.debug("Directive 'overwrite-existing-data' specified as: " + overWrite);
- setOverWriteExistingData(overWrite);
- }
-
- Boolean ignoreDupes = getBoolean(xpath,
- "/q:job-scheduling-data/q:processing-directives/q:ignore-duplicates", document);
- if(ignoreDupes == null) {
- log.debug("Directive 'ignore-duplicates' not specified, defaulting to " + isIgnoreDuplicates());
- }
- else {
- log.debug("Directive 'ignore-duplicates' specified as: " + ignoreDupes);
- setIgnoreDuplicates(ignoreDupes);
- }
-
- //
- // Extract Job definitions...
- //
-
- NodeList jobNodes = (NodeList) xpath.evaluate("/q:job-scheduling-data/q:schedule/q:job",
- document, XPathConstants.NODESET);
-
- log.debug("Found " + jobNodes.getLength() + " job definitions.");
-
- for (int i = 0; i < jobNodes.getLength(); i++) {
- Node jobDetailNode = jobNodes.item(i);
- String t = null;
-
- String jobName = getTrimmedToNullString(xpath, "q:name", jobDetailNode);
- String jobGroup = getTrimmedToNullString(xpath, "q:group", jobDetailNode);
- String jobDescription = getTrimmedToNullString(xpath, "q:description", jobDetailNode);
- String jobClassName = getTrimmedToNullString(xpath, "q:job-class", jobDetailNode);
- t = getTrimmedToNullString(xpath, "q:durability", jobDetailNode);
- boolean jobDurability = (t != null) && t.equals("true");
- t = getTrimmedToNullString(xpath, "q:recover", jobDetailNode);
- boolean jobRecoveryRequested = (t != null) && t.equals("true");
-
- Class extends Job> jobClass = classLoadHelper.loadClass(jobClassName, Job.class);
-
- JobDetail jobDetail = JobBuilder.newJob(jobClass)
- .withIdentity(jobName, jobGroup)
- .withDescription(jobDescription)
- .storeDurably(jobDurability)
- .requestRecovery(jobRecoveryRequested)
- .build();
-
- NodeList jobDataEntries = (NodeList) xpath.evaluate(
- "q:job-data-map/q:entry", jobDetailNode,
- XPathConstants.NODESET);
-
- for (int k = 0; k < jobDataEntries.getLength(); k++) {
- Node entryNode = jobDataEntries.item(k);
- String key = getTrimmedToNullString(xpath, "q:key", entryNode);
- String value = getTrimmedToNullString(xpath, "q:value", entryNode);
- jobDetail.getJobDataMap().put(key, value);
- }
-
- if(log.isDebugEnabled())
- log.debug("Parsed job definition: " + jobDetail);
-
- addJobToSchedule(jobDetail);
- }
-
- //
- // Extract Trigger definitions...
- //
-
- NodeList triggerEntries = (NodeList) xpath.evaluate(
- "/q:job-scheduling-data/q:schedule/q:trigger/*", document, XPathConstants.NODESET);
-
- log.debug("Found " + triggerEntries.getLength() + " trigger definitions.");
-
- for (int j = 0; j < triggerEntries.getLength(); j++) {
- Node triggerNode = triggerEntries.item(j);
- String triggerName = getTrimmedToNullString(xpath, "q:name", triggerNode);
- String triggerGroup = getTrimmedToNullString(xpath, "q:group", triggerNode);
- String triggerDescription = getTrimmedToNullString(xpath, "q:description", triggerNode);
- String triggerMisfireInstructionConst = getTrimmedToNullString(xpath, "q:misfire-instruction", triggerNode);
- String triggerPriorityString = getTrimmedToNullString(xpath, "q:priority", triggerNode);
- String triggerCalendarRef = getTrimmedToNullString(xpath, "q:calendar-name", triggerNode);
- String triggerJobName = getTrimmedToNullString(xpath, "q:job-name", triggerNode);
- String triggerJobGroup = getTrimmedToNullString(xpath, "q:job-group", triggerNode);
-
- int triggerPriority = Trigger.DEFAULT_PRIORITY;
- if(triggerPriorityString != null)
- triggerPriority = Integer.valueOf(triggerPriorityString);
-
- String startTimeString = getTrimmedToNullString(xpath, "q:start-time", triggerNode);
- String startTimeFutureSecsString = getTrimmedToNullString(xpath, "q:start-time-seconds-in-future", triggerNode);
- String endTimeString = getTrimmedToNullString(xpath, "q:end-time", triggerNode);
-
- //QTZ-273 : use of DatatypeConverter.parseDateTime() instead of SimpleDateFormat
- Date triggerStartTime;
- if(startTimeFutureSecsString != null)
- triggerStartTime = new Date(System.currentTimeMillis() + (Long.valueOf(startTimeFutureSecsString) * 1000L));
- else
- triggerStartTime = (startTimeString == null || startTimeString.length() == 0 ? new Date() : DatatypeConverter.parseDateTime(startTimeString).getTime());
- Date triggerEndTime = endTimeString == null || endTimeString.length() == 0 ? null : DatatypeConverter.parseDateTime(endTimeString).getTime();
-
- TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
-
- ScheduleBuilder> sched;
-
- if (triggerNode.getNodeName().equals("simple")) {
- String repeatCountString = getTrimmedToNullString(xpath, "q:repeat-count", triggerNode);
- String repeatIntervalString = getTrimmedToNullString(xpath, "q:repeat-interval", triggerNode);
-
- int repeatCount = repeatCountString == null ? 0 : Integer.parseInt(repeatCountString);
- long repeatInterval = repeatIntervalString == null ? 0 : Long.parseLong(repeatIntervalString);
-
- sched = SimpleScheduleBuilder.simpleSchedule()
- .withIntervalInMilliseconds(repeatInterval)
- .withRepeatCount(repeatCount);
-
- if (triggerMisfireInstructionConst != null && triggerMisfireInstructionConst.length() != 0) {
- if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_FIRE_NOW"))
- ((SimpleScheduleBuilder)sched).withMisfireHandlingInstructionFireNow();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT"))
- ((SimpleScheduleBuilder)sched).withMisfireHandlingInstructionNextWithExistingCount();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT"))
- ((SimpleScheduleBuilder)sched).withMisfireHandlingInstructionNextWithRemainingCount();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT"))
- ((SimpleScheduleBuilder)sched).withMisfireHandlingInstructionNowWithExistingCount();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT"))
- ((SimpleScheduleBuilder)sched).withMisfireHandlingInstructionNowWithRemainingCount();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_SMART_POLICY")) {
- // do nothing.... (smart policy is default)
- }
- else
- throw new ParseException("Unexpected/Unhandlable Misfire Instruction encountered '" + triggerMisfireInstructionConst + "', for trigger: " + triggerKey, -1);
- }
- } else if (triggerNode.getNodeName().equals("cron")) {
- String cronExpression = getTrimmedToNullString(xpath, "q:cron-expression", triggerNode);
- String timezoneString = getTrimmedToNullString(xpath, "q:time-zone", triggerNode);
-
- TimeZone tz = timezoneString == null ? null : TimeZone.getTimeZone(timezoneString);
-
- sched = CronScheduleBuilder.cronSchedule(cronExpression)
- .inTimeZone(tz);
-
- if (triggerMisfireInstructionConst != null && triggerMisfireInstructionConst.length() != 0) {
- if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_DO_NOTHING"))
- ((CronScheduleBuilder)sched).withMisfireHandlingInstructionDoNothing();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"))
- ((CronScheduleBuilder)sched).withMisfireHandlingInstructionFireAndProceed();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_SMART_POLICY")) {
- // do nothing.... (smart policy is default)
- }
- else
- throw new ParseException("Unexpected/Unhandlable Misfire Instruction encountered '" + triggerMisfireInstructionConst + "', for trigger: " + triggerKey, -1);
- }
- } else if (triggerNode.getNodeName().equals("calendar-interval")) {
- String repeatIntervalString = getTrimmedToNullString(xpath, "q:repeat-interval", triggerNode);
- String repeatUnitString = getTrimmedToNullString(xpath, "q:repeat-interval-unit", triggerNode);
-
- int repeatInterval = Integer.parseInt(repeatIntervalString);
-
- DateBuilder.IntervalUnit repeatUnit = DateBuilder.IntervalUnit.valueOf(repeatUnitString);
-
- sched = CalendarIntervalScheduleBuilder.calendarIntervalSchedule()
- .withInterval(repeatInterval, repeatUnit);
-
- if (triggerMisfireInstructionConst != null && triggerMisfireInstructionConst.length() != 0) {
- if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_DO_NOTHING"))
- ((CalendarIntervalScheduleBuilder)sched).withMisfireHandlingInstructionDoNothing();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"))
- ((CalendarIntervalScheduleBuilder)sched).withMisfireHandlingInstructionFireAndProceed();
- else if(triggerMisfireInstructionConst.equals("MISFIRE_INSTRUCTION_SMART_POLICY")) {
- // do nothing.... (smart policy is default)
- }
- else
- throw new ParseException("Unexpected/Unhandlable Misfire Instruction encountered '" + triggerMisfireInstructionConst + "', for trigger: " + triggerKey, -1);
- }
- } else {
- throw new ParseException("Unknown trigger type: " + triggerNode.getNodeName(), -1);
- }
-
-
- MutableTrigger trigger = (MutableTrigger) TriggerBuilder.newTrigger()
- .withIdentity(triggerName, triggerGroup)
- .withDescription(triggerDescription)
- .forJob(triggerJobName, triggerJobGroup)
- .startAt(triggerStartTime)
- .endAt(triggerEndTime)
- .withPriority(triggerPriority)
- .modifiedByCalendar(triggerCalendarRef)
- .withSchedule(sched)
- .build();
-
- NodeList jobDataEntries = (NodeList) xpath.evaluate(
- "q:job-data-map/q:entry", triggerNode,
- XPathConstants.NODESET);
-
- for (int k = 0; k < jobDataEntries.getLength(); k++) {
- Node entryNode = jobDataEntries.item(k);
- String key = getTrimmedToNullString(xpath, "q:key", entryNode);
- String value = getTrimmedToNullString(xpath, "q:value", entryNode);
- trigger.getJobDataMap().put(key, value);
- }
-
- if(log.isDebugEnabled())
- log.debug("Parsed trigger definition: " + trigger);
-
- addTriggerToSchedule(trigger);
- }
- }
-
- protected String getTrimmedToNullString(XPath xpathToElement, String elementName, Node parentNode) throws XPathExpressionException {
- String str = (String) xpathToElement.evaluate(elementName,
- parentNode, XPathConstants.STRING);
-
- if(str != null)
- str = str.trim();
-
- if(str != null && str.length() == 0)
- str = null;
-
- return str;
- }
-
- protected Boolean getBoolean(XPath xpathToElement, String elementName, Document document) throws XPathExpressionException {
-
- Node directive = (Node) xpathToElement.evaluate(elementName, document, XPathConstants.NODE);
-
- if(directive == null || directive.getTextContent() == null)
- return null;
-
- String val = directive.getTextContent();
- if(val.equalsIgnoreCase("true") || val.equalsIgnoreCase("yes") || val.equalsIgnoreCase("y"))
- return Boolean.TRUE;
-
- return Boolean.FALSE;
- }
-
- /**
- * Process the xml file in the default location, and schedule all of the
- * jobs defined within it.
- *
- * Note that we will set overWriteExistingJobs after the default xml is parsed.
- */
- public void processFileAndScheduleJobs(Scheduler sched,
- boolean overWriteExistingJobs) throws Exception {
- String fileName = QUARTZ_XML_DEFAULT_FILE_NAME;
- processFile(fileName, getSystemIdForFileName(fileName));
- // The overWriteExistingJobs flag was set by processFile() -> prepForProcessing(), then by xml parsing, and then now
- // we need to reset it again here by this method parameter to override it.
- setOverWriteExistingData(overWriteExistingJobs);
- executePreProcessCommands(sched);
- scheduleJobs(sched);
- }
-
- /**
- * Process the xml file in the given location, and schedule all of the
- * jobs defined within it.
- *
- * @param fileName
- * meta data file name.
- */
- public void processFileAndScheduleJobs(String fileName, Scheduler sched) throws Exception {
- processFileAndScheduleJobs(fileName, getSystemIdForFileName(fileName), sched);
- }
-
- /**
- * Process the xml file in the given location, and schedule all of the
- * jobs defined within it.
- *
- * @param fileName
- * meta data file name.
- */
- public void processFileAndScheduleJobs(String fileName, String systemId, Scheduler sched) throws Exception {
- processFile(fileName, systemId);
- executePreProcessCommands(sched);
- scheduleJobs(sched);
- }
-
- /**
- * Returns a List
of jobs loaded from the xml file.
- *
- *
- * @return a List
of jobs.
- */
- protected List getLoadedJobs() {
- return Collections.unmodifiableList(loadedJobs);
- }
-
- /**
- * Returns a List
of triggers loaded from the xml file.
- *
- *
- * @return a List
of triggers.
- */
- protected List getLoadedTriggers() {
- return Collections.unmodifiableList(loadedTriggers);
- }
-
- /**
- * Returns an InputStream
from the fileName as a resource.
- *
- * @param fileName
- * file name.
- * @return an InputStream
from the fileName as a resource.
- */
- protected InputStream getInputStream(String fileName) {
- return this.classLoadHelper.getResourceAsStream(fileName);
- }
-
- protected void addJobToSchedule(JobDetail job) {
- loadedJobs.add(job);
- }
-
- protected void addTriggerToSchedule(MutableTrigger trigger) {
- loadedTriggers.add(trigger);
- }
-
- private Map> buildTriggersByFQJobNameMap(List triggers) {
-
- Map> triggersByFQJobName = new HashMap>();
-
- for(MutableTrigger trigger: triggers) {
- List triggersOfJob = triggersByFQJobName.get(trigger.getJobKey());
- if(triggersOfJob == null) {
- triggersOfJob = new LinkedList();
- triggersByFQJobName.put(trigger.getJobKey(), triggersOfJob);
- }
- triggersOfJob.add(trigger);
- }
-
- return triggersByFQJobName;
- }
-
- protected void executePreProcessCommands(Scheduler scheduler)
- throws SchedulerException {
-
- for(String group: jobGroupsToDelete) {
- if(group.equals("*")) {
- log.info("Deleting all jobs in ALL groups.");
- for (String groupName : scheduler.getJobGroupNames()) {
- if (!jobGroupsToNeverDelete.contains(groupName)) {
- for (JobKey key : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
- scheduler.deleteJob(key);
- }
- }
- }
- }
- else {
- if(!jobGroupsToNeverDelete.contains(group)) {
- log.info("Deleting all jobs in group: {}", group);
- for (JobKey key : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(group))) {
- scheduler.deleteJob(key);
- }
- }
- }
- }
-
- for(String group: triggerGroupsToDelete) {
- if(group.equals("*")) {
- log.info("Deleting all triggers in ALL groups.");
- for (String groupName : scheduler.getTriggerGroupNames()) {
- if (!triggerGroupsToNeverDelete.contains(groupName)) {
- for (TriggerKey key : scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(groupName))) {
- scheduler.unscheduleJob(key);
- }
- }
- }
- }
- else {
- if(!triggerGroupsToNeverDelete.contains(group)) {
- log.info("Deleting all triggers in group: {}", group);
- for (TriggerKey key : scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(group))) {
- scheduler.unscheduleJob(key);
- }
- }
- }
- }
-
- for(JobKey key: jobsToDelete) {
- if(!jobGroupsToNeverDelete.contains(key.getGroup())) {
- log.info("Deleting job: {}", key);
- scheduler.deleteJob(key);
- }
- }
-
- for(TriggerKey key: triggersToDelete) {
- if(!triggerGroupsToNeverDelete.contains(key.getGroup())) {
- log.info("Deleting trigger: {}", key);
- scheduler.unscheduleJob(key);
- }
- }
- }
-
- /**
- * Schedules the given sets of jobs and triggers.
- *
- * @param sched
- * job scheduler.
- * @exception SchedulerException
- * if the Job or Trigger cannot be added to the Scheduler, or
- * there is an internal Scheduler error.
- */
- @SuppressWarnings("ConstantConditions")
- protected void scheduleJobs(Scheduler sched)
- throws SchedulerException {
-
- List jobs = new LinkedList(getLoadedJobs());
- List triggers = new LinkedList( getLoadedTriggers());
-
- log.info("Adding " + jobs.size() + " jobs, " + triggers.size() + " triggers.");
-
- Map> triggersByFQJobName = buildTriggersByFQJobNameMap(triggers);
-
- // add each job, and it's associated triggers
- Iterator itr = jobs.iterator();
- while(itr.hasNext()) {
- JobDetail detail = itr.next();
- itr.remove(); // remove jobs as we handle them...
-
- JobDetail dupeJ = null;
- try {
- // The existing job could have been deleted, and Quartz API doesn't allow us to query this without
- // loading the job class, so use try/catch to handle it.
- dupeJ = sched.getJobDetail(detail.getKey());
- } catch (JobPersistenceException e) {
- if (e.getCause() instanceof ClassNotFoundException && isOverWriteExistingData()) {
- // We are going to replace jobDetail anyway, so just delete it first.
- log.info("Removing job: " + detail.getKey());
- sched.deleteJob(detail.getKey());
- } else {
- throw e;
- }
- }
-
- if ((dupeJ != null)) {
- if(!isOverWriteExistingData() && isIgnoreDuplicates()) {
- log.info("Not overwriting existing job: " + dupeJ.getKey());
- continue; // just ignore the entry
- }
- if(!isOverWriteExistingData() && !isIgnoreDuplicates()) {
- throw new ObjectAlreadyExistsException(detail);
- }
- }
-
- if (dupeJ != null) {
- log.info("Replacing job: " + detail.getKey());
- } else {
- log.info("Adding job: " + detail.getKey());
- }
-
- List triggersOfJob = triggersByFQJobName.get(detail.getKey());
-
- if (!detail.isDurable() && (triggersOfJob == null || triggersOfJob.size() == 0)) {
- if (dupeJ == null) {
- throw new SchedulerException(
- "A new job defined without any triggers must be durable: " +
- detail.getKey());
- }
-
- if ((dupeJ.isDurable() &&
- (sched.getTriggersOfJob(
- detail.getKey()).size() == 0))) {
- throw new SchedulerException(
- "Can't change existing durable job without triggers to non-durable: " +
- detail.getKey());
- }
- }
-
-
- if(dupeJ != null || detail.isDurable()) {
- if (triggersOfJob != null && triggersOfJob.size() > 0)
- sched.addJob(detail, true, true); // add the job regardless is durable or not b/c we have trigger to add
- else
- sched.addJob(detail, true, false); // add the job only if a replacement or durable, else exception will throw!
- }
- else {
- boolean addJobWithFirstSchedule = true;
-
- // Add triggers related to the job...
- for (MutableTrigger trigger : triggersOfJob) {
- triggers.remove(trigger); // remove triggers as we handle them...
-
- if (trigger.getStartTime() == null) {
- trigger.setStartTime(new Date());
- }
-
- Trigger dupeT = sched.getTrigger(trigger.getKey());
- if (dupeT != null) {
- if (isOverWriteExistingData()) {
- if (log.isDebugEnabled()) {
- log.debug(
- "Rescheduling job: " + trigger.getJobKey() + " with updated trigger: " + trigger.getKey());
- }
- } else if (isIgnoreDuplicates()) {
- log.info("Not overwriting existing trigger: " + dupeT.getKey());
- continue; // just ignore the trigger (and possibly job)
- } else {
- throw new ObjectAlreadyExistsException(trigger);
- }
-
- if (!dupeT.getJobKey().equals(trigger.getJobKey())) {
- log.warn("Possibly duplicately named ({}) triggers in jobs xml file! ", trigger.getKey());
- }
-
- sched.rescheduleJob(trigger.getKey(), trigger);
- } else {
- if (log.isDebugEnabled()) {
- log.debug(
- "Scheduling job: " + trigger.getJobKey() + " with trigger: " + trigger.getKey());
- }
-
- try {
- if (addJobWithFirstSchedule) {
- sched.scheduleJob(detail, trigger); // add the job if it's not in yet...
- addJobWithFirstSchedule = false;
- } else {
- sched.scheduleJob(trigger);
- }
- } catch (ObjectAlreadyExistsException e) {
- if (log.isDebugEnabled()) {
- log.debug(
- "Adding trigger: " + trigger.getKey() + " for job: " + detail.getKey() +
- " failed because the trigger already existed. " +
- "This is likely due to a race condition between multiple instances " +
- "in the cluster. Will try to reschedule instead.");
- }
-
- // Let's try one more time as reschedule.
- sched.rescheduleJob(trigger.getKey(), trigger);
- }
- }
- }
- }
- }
-
- // add triggers that weren't associated with a new job... (those we already handled were removed above)
- for(MutableTrigger trigger: triggers) {
-
- if(trigger.getStartTime() == null) {
- trigger.setStartTime(new Date());
- }
-
- Trigger dupeT = sched.getTrigger(trigger.getKey());
- if (dupeT != null) {
- if(isOverWriteExistingData()) {
- if (log.isDebugEnabled()) {
- log.debug(
- "Rescheduling job: " + trigger.getJobKey() + " with updated trigger: " + trigger.getKey());
- }
- }
- else if(isIgnoreDuplicates()) {
- log.info("Not overwriting existing trigger: " + dupeT.getKey());
- continue; // just ignore the trigger
- }
- else {
- throw new ObjectAlreadyExistsException(trigger);
- }
-
- if(!dupeT.getJobKey().equals(trigger.getJobKey())) {
- log.warn("Possibly duplicately named ({}) triggers in jobs xml file! ", trigger.getKey());
- }
-
- sched.rescheduleJob(trigger.getKey(), trigger);
- } else {
- if (log.isDebugEnabled()) {
- log.debug(
- "Scheduling job: " + trigger.getJobKey() + " with trigger: " + trigger.getKey());
- }
-
- try {
- sched.scheduleJob(trigger);
- } catch (ObjectAlreadyExistsException e) {
- if (log.isDebugEnabled()) {
- log.debug(
- "Adding trigger: " + trigger.getKey() + " for job: " +trigger.getJobKey() +
- " failed because the trigger already existed. " +
- "This is likely due to a race condition between multiple instances " +
- "in the cluster. Will try to reschedule instead.");
- }
-
- // Let's rescheduleJob one more time.
- sched.rescheduleJob(trigger.getKey(), trigger);
- }
- }
- }
- }
-
- /**
- * ErrorHandler interface.
- *
- * Receive notification of a warning.
- *
- * @param e
- * The error information encapsulated in a SAX parse exception.
- * @exception SAXException
- * Any SAX exception, possibly wrapping another exception.
- */
- public void warning(SAXParseException e) throws SAXException {
- addValidationException(e);
- }
-
- /**
- * ErrorHandler interface.
- *
- * Receive notification of a recoverable error.
- *
- * @param e
- * The error information encapsulated in a SAX parse exception.
- * @exception SAXException
- * Any SAX exception, possibly wrapping another exception.
- */
- public void error(SAXParseException e) throws SAXException {
- addValidationException(e);
- }
-
- /**
- * ErrorHandler interface.
- *
- * Receive notification of a non-recoverable error.
- *
- * @param e
- * The error information encapsulated in a SAX parse exception.
- * @exception SAXException
- * Any SAX exception, possibly wrapping another exception.
- */
- public void fatalError(SAXParseException e) throws SAXException {
- addValidationException(e);
- }
-
- /**
- * Adds a detected validation exception.
- *
- * @param e
- * SAX exception.
- */
- protected void addValidationException(SAXException e) {
- validationExceptions.add(e);
- }
-
- /**
- * Resets the the number of detected validation exceptions.
- */
- protected void clearValidationExceptions() {
- validationExceptions.clear();
- }
-
- /**
- * Throws a ValidationException if the number of validationExceptions
- * detected is greater than zero.
- *
- * @exception ValidationException
- * DTD validation exception.
- */
- protected void maybeThrowValidationException() throws ValidationException {
- if (validationExceptions.size() > 0) {
- throw new ValidationException("Encountered " + validationExceptions.size() + " validation exceptions.", validationExceptions);
- }
- }
-}
diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/job_scheduling_data_1_8.xsd b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/job_scheduling_data_1_8.xsd
deleted file mode 100644
index e8d0d23c9..000000000
--- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/job_scheduling_data_1_8.xsd
+++ /dev/null
@@ -1,339 +0,0 @@
-
-
-
-
-
- Root level node
-
-
-
-
-
- Commands to be executed before scheduling the jobs and triggers in this file.
-
-
-
-
- Directives to be followed while scheduling the jobs and triggers in this file.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Version of the XML Schema instance
-
-
-
-
-
-
-
-
- Delete all jobs, if any, in the identified group. "*" can be used to identify all groups. Will also result in deleting all triggers related to the jobs.
-
-
- Delete all triggers, if any, in the identified group. "*" can be used to identify all groups. Will also result in deletion of related jobs that are non-durable.
-
-
- Delete the identified job if it exists (will also result in deleting all triggers related to it).
-
-
-
-
-
-
-
-
- Delete the identified trigger if it exists (will also result in deletion of related jobs that are non-durable).
-
-
-
-
-
-
-
-
-
-
-
-
-
- Whether the existing scheduling data (with same identifiers) will be overwritten. If false, and ignore-duplicates is not false, and jobs or triggers with the same names already exist as those in the file, an error will occur.
-
-
- If true (and overwrite-existing-data is false) then any job/triggers encountered in this file that have names that already exist in the scheduler will be ignored, and no error will be produced.
-
-
-
-
-
-
- Define a JobDetail
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a JobDataMap
-
-
-
-
-
-
-
-
- Define a JobDataMap entry
-
-
-
-
-
-
-
-
-
- Define a Trigger
-
-
-
-
-
-
-
-
-
-
- Common Trigger definitions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a SimpleTrigger
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a CronTrigger
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a DateIntervalTrigger
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cron expression (see JavaDoc for examples)
-
- Special thanks to Chris Thatcher (thatcher@butterfly.net) for the regular expression!
-
- Regular expressions are not my strong point but I believe this is complete,
- with the caveat that order for expressions like 3-0 is not legal but will pass,
- and month and day names must be capitalized.
- If you want to examine the correctness look for the [\s] to denote the
- seperation of individual regular expressions. This is how I break them up visually
- to examine them:
-
- SECONDS:
- (
- ((([0-9]|[0-5][0-9]),)*([0-9]|[0-5][0-9]))
- | (([\*]|[0-9]|[0-5][0-9])(/|-)([0-9]|[0-5][0-9]))
- | ([\?])
- | ([\*])
- ) [\s]
- MINUTES:
- (
- ((([0-9]|[0-5][0-9]),)*([0-9]|[0-5][0-9]))
- | (([\*]|[0-9]|[0-5][0-9])(/|-)([0-9]|[0-5][0-9]))
- | ([\?])
- | ([\*])
- ) [\s]
- HOURS:
- (
- ((([0-9]|[0-1][0-9]|[2][0-3]),)*([0-9]|[0-1][0-9]|[2][0-3]))
- | (([\*]|[0-9]|[0-1][0-9]|[2][0-3])(/|-)([0-9]|[0-1][0-9]|[2][0-3]))
- | ([\?])
- | ([\*])
- ) [\s]
- DAY OF MONTH:
- (
- ((([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]),)*([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(C)?)
- | (([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(/|-)([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(C)?)
- | (L)
- | (LW)
- | ([1-9]W)
- | ([1-3][0-9]W)
- | ([\?])
- | ([\*])
- )[\s]
- MONTH:
- (
- ((([1-9]|0[1-9]|1[0-2]),)*([1-9]|0[1-9]|1[0-2]))
- | (([1-9]|0[1-9]|1[0-2])(/|-)([1-9]|0[1-9]|1[0-2]))
- | (((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC),)*(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))
- | ((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-|/)(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))
- | ([\?])
- | ([\*])
- )[\s]
- DAY OF WEEK:
- (
- (([1-7],)*([1-7]))
- | ([1-7](/|-)([1-7]))
- | (((MON|TUE|WED|THU|FRI|SAT|SUN),)*(MON|TUE|WED|THU|FRI|SAT|SUN)(C)?)
- | ((MON|TUE|WED|THU|FRI|SAT|SUN)(-|/)(MON|TUE|WED|THU|FRI|SAT|SUN)(C)?)
- | (([1-7]|(MON|TUE|WED|THU|FRI|SAT|SUN))(L|LW)?)
- | (([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)#([1-7])?)
- | ([\?])
- | ([\*])
- )
- YEAR (OPTIONAL):
- (
- [\s]?
- ([\*])?
- | ((19[7-9][0-9])|(20[0-9][0-9]))?
- | (((19[7-9][0-9])|(20[0-9][0-9]))(-|/)((19[7-9][0-9])|(20[0-9][0-9])))?
- | ((((19[7-9][0-9])|(20[0-9][0-9])),)*((19[7-9][0-9])|(20[0-9][0-9])))?
- )
-
-
-
-
-
-
-
-
-
- Number of times to repeat the Trigger (-1 for indefinite)
-
-
-
-
-
-
-
-
-
- Simple Trigger Misfire Instructions
-
-
-
-
-
-
-
-
-
-
-
-
-
- Simple Trigger Misfire Instructions
-
-
-
-
-
-
-
-
-
-
- Date Interval Trigger Misfire Instructions
-
-
-
-
-
-
-
-
-
-
- Interval Units
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/job_scheduling_data_2_0.xsd b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/job_scheduling_data_2_0.xsd
deleted file mode 100644
index bad0b0e86..000000000
--- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/xml/job_scheduling_data_2_0.xsd
+++ /dev/null
@@ -1,342 +0,0 @@
-
-
-
-
-
- Root level node
-
-
-
-
-
- Commands to be executed before scheduling the jobs and triggers in this file.
-
-
-
-
- Directives to be followed while scheduling the jobs and triggers in this file.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Version of the XML Schema instance
-
-
-
-
-
-
-
-
- Delete all jobs, if any, in the identified group. "*" can be used to identify all groups. Will also result in deleting all triggers related to the jobs.
-
-
- Delete all triggers, if any, in the identified group. "*" can be used to identify all groups. Will also result in deletion of related jobs that are non-durable.
-
-
- Delete the identified job if it exists (will also result in deleting all triggers related to it).
-
-
-
-
-
-
-
-
- Delete the identified trigger if it exists (will also result in deletion of related jobs that are non-durable).
-
-
-
-
-
-
-
-
-
-
-
-
-
- Whether the existing scheduling data (with same identifiers) will be overwritten. If false, and ignore-duplicates is not false, and jobs or triggers with the same names already exist as those in the file, an error will occur.
-
-
- If true (and overwrite-existing-data is false) then any job/triggers encountered in this file that have names that already exist in the scheduler will be ignored, and no error will be produced.
-
-
-
-
-
-
- Define a JobDetail
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a JobDataMap
-
-
-
-
-
-
-
-
- Define a JobDataMap entry
-
-
-
-
-
-
-
-
-
- Define a Trigger
-
-
-
-
-
-
-
-
-
-
- Common Trigger definitions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a SimpleTrigger
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a CronTrigger
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Define a DateIntervalTrigger
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cron expression (see JavaDoc for examples)
-
- Special thanks to Chris Thatcher (thatcher@butterfly.net) for the regular expression!
-
- Regular expressions are not my strong point but I believe this is complete,
- with the caveat that order for expressions like 3-0 is not legal but will pass,
- and month and day names must be capitalized.
- If you want to examine the correctness look for the [\s] to denote the
- seperation of individual regular expressions. This is how I break them up visually
- to examine them:
-
- SECONDS:
- (
- ((([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?,)*([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?)
- | (([\*]|[0-9]|[0-5][0-9])/([0-9]|[0-5][0-9]))
- | ([\?])
- | ([\*])
- ) [\s]
- MINUTES:
- (
- ((([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?,)*([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?)
- | (([\*]|[0-9]|[0-5][0-9])/([0-9]|[0-5][0-9]))
- | ([\?])
- | ([\*])
- ) [\s]
- HOURS:
- (
- ((([0-9]|[0-1][0-9]|[2][0-3])(-([0-9]|[0-1][0-9]|[2][0-3]))?,)*([0-9]|[0-1][0-9]|[2][0-3])(-([0-9]|[0-1][0-9]|[2][0-3]))?)
- | (([\*]|[0-9]|[0-1][0-9]|[2][0-3])/([0-9]|[0-1][0-9]|[2][0-3]))
- | ([\?])
- | ([\*])
- ) [\s]
- DAY OF MONTH:
- (
- ((([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(-([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]))?,)*([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(-([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]))?(C)?)
- | (([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])/([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(C)?)
- | (L(-[0-9])?)
- | (L(-[1-2][0-9])?)
- | (L(-[3][0-1])?)
- | (LW)
- | ([1-9]W)
- | ([1-3][0-9]W)
- | ([\?])
- | ([\*])
- )[\s]
- MONTH:
- (
- ((([1-9]|0[1-9]|1[0-2])(-([1-9]|0[1-9]|1[0-2]))?,)*([1-9]|0[1-9]|1[0-2])(-([1-9]|0[1-9]|1[0-2]))?)
- | (([1-9]|0[1-9]|1[0-2])/([1-9]|0[1-9]|1[0-2]))
- | (((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?,)*(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)
- | ((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)/(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))
- | ([\?])
- | ([\*])
- )[\s]
- DAY OF WEEK:
- (
- (([1-7](-([1-7]))?,)*([1-7])(-([1-7]))?)
- | ([1-7]/([1-7]))
- | (((MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?,)*(MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?(C)?)
- | ((MON|TUE|WED|THU|FRI|SAT|SUN)/(MON|TUE|WED|THU|FRI|SAT|SUN)(C)?)
- | (([1-7]|(MON|TUE|WED|THU|FRI|SAT|SUN))(L|LW)?)
- | (([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)#([1-7])?)
- | ([\?])
- | ([\*])
- )
- YEAR (OPTIONAL):
- (
- [\s]?
- ([\*])?
- | ((19[7-9][0-9])|(20[0-9][0-9]))?
- | (((19[7-9][0-9])|(20[0-9][0-9]))/((19[7-9][0-9])|(20[0-9][0-9])))?
- | ((((19[7-9][0-9])|(20[0-9][0-9]))(-((19[7-9][0-9])|(20[0-9][0-9])))?,)*((19[7-9][0-9])|(20[0-9][0-9]))(-((19[7-9][0-9])|(20[0-9][0-9])))?)?
- )
-
-
-
-
-
-
-
-
-
- Number of times to repeat the Trigger (-1 for indefinite)
-
-
-
-
-
-
-
-
-
- Simple Trigger Misfire Instructions
-
-
-
-
-
-
-
-
-
-
-
-
-
- Cron Trigger Misfire Instructions
-
-
-
-
-
-
-
-
-
-
- Date Interval Trigger Misfire Instructions
-
-
-
-
-
-
-
-
-
-
- Interval Units
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/fine-third-default/fine-sjsxp/pom.xml b/fine-third-default/fine-sjsxp/pom.xml
index b32b177b8..6dc30c69a 100644
--- a/fine-third-default/fine-sjsxp/pom.xml
+++ b/fine-third-default/fine-sjsxp/pom.xml
@@ -13,5 +13,11 @@
fine-sjsxp
${revision}
-
+
+
+ com.fr.third
+ fine-stax
+ ${revision}
+
+
\ No newline at end of file