Browse Source
Merge in CORE/base-third from ~ZHOUPING/base-third:feature/10.0 to feature/10.0 * commit '1737949fc3763fe6463629006677fbecdc80f6fa': REPORT-28620 10.0扫描后quartz有漏洞research/11.0
zhouping
5 years ago
7 changed files with 29 additions and 2487 deletions
@ -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. |
|
||||||
* |
|
||||||
* <p>The XML schema definition can be found here: |
|
||||||
* http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd</p>
|
|
||||||
* |
|
||||||
* <p> |
|
||||||
* The periodically scanning of files for changes is not currently supported in a |
|
||||||
* clustered environment. |
|
||||||
* </p> |
|
||||||
* |
|
||||||
* <p> |
|
||||||
* If using this plugin with JobStoreCMT, be sure to set the |
|
||||||
* plugin property <em>wrapInUserTransaction</em> to true. Also, if you have a |
|
||||||
* positive <em>scanInterval</em> be sure to set |
|
||||||
* <em>org.quartz.scheduler.wrapJobExecutionInUserTransaction</em> to true. |
|
||||||
* </p> |
|
||||||
* |
|
||||||
* @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<String, JobFile> jobFiles = new LinkedHashMap<String, JobFile>(); |
|
||||||
|
|
||||||
private long scanInterval = 0; |
|
||||||
|
|
||||||
boolean started = false; |
|
||||||
|
|
||||||
protected ClassLoadHelper classLoadHelper = null; |
|
||||||
|
|
||||||
private Set<String> jobTriggerNameSet = new HashSet<String>(); |
|
||||||
|
|
||||||
/* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
* |
|
||||||
* 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 <code>true</code>. |
|
||||||
*/ |
|
||||||
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 <code>true</code>. |
|
||||||
*/ |
|
||||||
public void setFailOnFileNotFound(boolean failOnFileNotFound) { |
|
||||||
this.failOnFileNotFound = failOnFileNotFound; |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
* |
|
||||||
* SchedulerPlugin Interface. |
|
||||||
* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
*/ |
|
||||||
|
|
||||||
/** |
|
||||||
* <p> |
|
||||||
* Called during creation of the <code>Scheduler</code> in order to give |
|
||||||
* the <code>SchedulerPlugin</code> a chance to initialize. |
|
||||||
* </p> |
|
||||||
* |
|
||||||
* @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<JobFile> 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 <em>wrapInUserTransaction</em> because shutdown() |
|
||||||
* does not interact with the <code>Scheduler</code>. |
|
||||||
*/ |
|
||||||
@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
|
|
@ -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 <a href="mailto:bonhamcm@thirdeyeconsulting.com">Chris Bonham</a> |
|
||||||
*/ |
|
||||||
public class ValidationException extends Exception { |
|
||||||
|
|
||||||
private static final long serialVersionUID = -1697832087051681357L; |
|
||||||
|
|
||||||
/* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
* |
|
||||||
* Data members. |
|
||||||
* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
*/ |
|
||||||
|
|
||||||
private Collection<Exception> validationExceptions = new ArrayList<Exception>(); |
|
||||||
|
|
||||||
/* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
* |
|
||||||
* 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<Exception> 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<Exception> errors) { |
|
||||||
this(message); |
|
||||||
this.validationExceptions = Collections |
|
||||||
.unmodifiableCollection(validationExceptions); |
|
||||||
initCause(errors.iterator().next()); |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
* |
|
||||||
* Interface. |
|
||||||
* |
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
||||||
*/ |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns collection of errors. |
|
||||||
* |
|
||||||
* @return collection of errors. |
|
||||||
*/ |
|
||||||
public Collection<Exception> 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<Exception> iter = getValidationExceptions().iterator(); iter |
|
||||||
.hasNext(); ) { |
|
||||||
Exception e = iter.next(); |
|
||||||
|
|
||||||
if (!first) { |
|
||||||
sb.append('\n'); |
|
||||||
first = false; |
|
||||||
} |
|
||||||
|
|
||||||
sb.append(e.getMessage()); |
|
||||||
} |
|
||||||
|
|
||||||
return sb.toString(); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -1,339 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" |
|
||||||
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData" |
|
||||||
targetNamespace="http://www.quartz-scheduler.org/xml/JobSchedulingData" |
|
||||||
elementFormDefault="qualified" |
|
||||||
version="1.8"> |
|
||||||
|
|
||||||
<xs:element name="job-scheduling-data"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Root level node</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence maxOccurs="unbounded"> |
|
||||||
<xs:element name="pre-processing-commands" type="pre-processing-commandsType" minOccurs="0" maxOccurs="1"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Commands to be executed before scheduling the jobs and triggers in this file.</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="processing-directives" type="processing-directivesType" minOccurs="0" maxOccurs="1"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Directives to be followed while scheduling the jobs and triggers in this file.</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="schedule" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence maxOccurs="unbounded"> |
|
||||||
<xs:element name="job" type="job-detailType" minOccurs="0" maxOccurs="unbounded"/> |
|
||||||
<xs:element name="trigger" type="triggerType" minOccurs="0" maxOccurs="unbounded"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
</xs:sequence> |
|
||||||
<xs:attribute name="version" type="xs:string"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Version of the XML Schema instance</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
</xs:attribute> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
|
|
||||||
<xs:complexType name="pre-processing-commandsType"> |
|
||||||
<xs:sequence maxOccurs="unbounded"> |
|
||||||
<xs:element name="delete-jobs-in-group" type="xs:string" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="delete-triggers-in-group" type="xs:string" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="delete-job" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>Delete the identified job if it exists (will also result in deleting all triggers related to it).</xs:documentation></xs:annotation> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="delete-trigger" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>Delete the identified trigger if it exists (will also result in deletion of related jobs that are non-durable).</xs:documentation></xs:annotation> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="processing-directivesType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="overwrite-existing-data" type="xs:boolean" minOccurs="0" default="true"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="ignore-duplicates" type="xs:boolean" minOccurs="0" default="false"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="job-detailType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a JobDetail</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="description" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="job-class" type="xs:string"/> |
|
||||||
<xs:element name="job-listener-ref" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:sequence minOccurs="0"> |
|
||||||
<xs:element name="volatility" type="xs:boolean"/> |
|
||||||
<xs:element name="durability" type="xs:boolean"/> |
|
||||||
<xs:element name="recover" type="xs:boolean"/> |
|
||||||
</xs:sequence> |
|
||||||
<xs:element name="job-data-map" type="job-data-mapType" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="job-data-mapType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a JobDataMap</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:element name="entry" type="entryType"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="entryType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a JobDataMap entry</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="key" type="xs:string"/> |
|
||||||
<xs:element name="value" type="xs:string"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="triggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a Trigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:choice> |
|
||||||
<xs:element name="simple" type="simpleTriggerType"/> |
|
||||||
<xs:element name="cron" type="cronTriggerType"/> |
|
||||||
<xs:element name="date-interval" type="dateIntervalTriggerType"/> |
|
||||||
</xs:choice> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="abstractTriggerType" abstract="true"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Common Trigger definitions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="description" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="job-name" type="xs:string"/> |
|
||||||
<xs:element name="job-group" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="calendar-name" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="volatility" type="xs:boolean" minOccurs="0"/> |
|
||||||
<xs:element name="job-data-map" type="job-data-mapType" minOccurs="0"/> |
|
||||||
<xs:sequence minOccurs="0"> |
|
||||||
<xs:element name="start-time" type="xs:dateTime"/> |
|
||||||
<xs:element name="end-time" type="xs:dateTime" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="simpleTriggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a SimpleTrigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexContent> |
|
||||||
<xs:extension base="abstractTriggerType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="misfire-instruction" type="simple-trigger-misfire-instructionType" minOccurs="0" /> |
|
||||||
<xs:sequence minOccurs="0"> |
|
||||||
<xs:element name="repeat-count" type="repeat-countType"/> |
|
||||||
<xs:element name="repeat-interval" type="xs:nonNegativeInteger"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:sequence> |
|
||||||
</xs:extension> |
|
||||||
</xs:complexContent> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="cronTriggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a CronTrigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexContent> |
|
||||||
<xs:extension base="abstractTriggerType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="misfire-instruction" type="cron-trigger-misfire-instructionType" minOccurs="0"/> |
|
||||||
<xs:element name="cron-expression" type="cron-expressionType"/> |
|
||||||
<xs:element name="time-zone" type="xs:string" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:extension> |
|
||||||
</xs:complexContent> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="dateIntervalTriggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a DateIntervalTrigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexContent> |
|
||||||
<xs:extension base="abstractTriggerType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="misfire-instruction" type="date-interval-trigger-misfire-instructionType" minOccurs="0"/> |
|
||||||
<xs:element name="repeat-interval" type="xs:nonNegativeInteger"/> |
|
||||||
<xs:element name="repeat-interval-unit" type="interval-unitType"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:extension> |
|
||||||
</xs:complexContent> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:simpleType name="cron-expressionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation> |
|
||||||
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])))? |
|
||||||
) |
|
||||||
</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="(((([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](((([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](((([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](((([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](((([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]((([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])?)|([\?])|([\*]))([\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])))?)"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="repeat-countType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Number of times to repeat the Trigger (-1 for indefinite)</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:integer"> |
|
||||||
<xs:minInclusive value="-1"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
|
|
||||||
<xs:simpleType name="simple-trigger-misfire-instructionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Simple Trigger Misfire Instructions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_SMART_POLICY"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_FIRE_NOW"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="cron-trigger-misfire-instructionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Simple Trigger Misfire Instructions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_SMART_POLICY"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_DO_NOTHING"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="date-interval-trigger-misfire-instructionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Date Interval Trigger Misfire Instructions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_SMART_POLICY"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_DO_NOTHING"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="interval-unitType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Interval Units</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="DAY"/> |
|
||||||
<xs:pattern value="HOUR"/> |
|
||||||
<xs:pattern value="MINUTE"/> |
|
||||||
<xs:pattern value="MONTH"/> |
|
||||||
<xs:pattern value="SECOND"/> |
|
||||||
<xs:pattern value="WEEK"/> |
|
||||||
<xs:pattern value="YEAR"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
</xs:schema> |
|
@ -1,342 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" |
|
||||||
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData" |
|
||||||
targetNamespace="http://www.quartz-scheduler.org/xml/JobSchedulingData" |
|
||||||
elementFormDefault="qualified" |
|
||||||
version="2.0"> |
|
||||||
|
|
||||||
<xs:element name="job-scheduling-data"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Root level node</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence maxOccurs="unbounded"> |
|
||||||
<xs:element name="pre-processing-commands" type="pre-processing-commandsType" minOccurs="0" maxOccurs="1"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Commands to be executed before scheduling the jobs and triggers in this file.</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="processing-directives" type="processing-directivesType" minOccurs="0" maxOccurs="1"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Directives to be followed while scheduling the jobs and triggers in this file.</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="schedule" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence maxOccurs="unbounded"> |
|
||||||
<xs:element name="job" type="job-detailType" minOccurs="0" maxOccurs="unbounded"/> |
|
||||||
<xs:element name="trigger" type="triggerType" minOccurs="0" maxOccurs="unbounded"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
</xs:sequence> |
|
||||||
<xs:attribute name="version" type="xs:string"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Version of the XML Schema instance</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
</xs:attribute> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
|
|
||||||
<xs:complexType name="pre-processing-commandsType"> |
|
||||||
<xs:sequence maxOccurs="unbounded"> |
|
||||||
<xs:element name="delete-jobs-in-group" type="xs:string" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="delete-triggers-in-group" type="xs:string" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="delete-job" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>Delete the identified job if it exists (will also result in deleting all triggers related to it).</xs:documentation></xs:annotation> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="delete-trigger" minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:annotation><xs:documentation>Delete the identified trigger if it exists (will also result in deletion of related jobs that are non-durable).</xs:documentation></xs:annotation> |
|
||||||
<xs:complexType> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
</xs:element> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="processing-directivesType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="overwrite-existing-data" type="xs:boolean" minOccurs="0" default="true"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
<xs:element name="ignore-duplicates" type="xs:boolean" minOccurs="0" default="false"> |
|
||||||
<xs:annotation><xs:documentation>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.</xs:documentation></xs:annotation> |
|
||||||
</xs:element> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="job-detailType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a JobDetail</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="description" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="job-class" type="xs:string"/> |
|
||||||
<xs:sequence minOccurs="0"> |
|
||||||
<xs:element name="durability" type="xs:boolean"/> |
|
||||||
<xs:element name="recover" type="xs:boolean"/> |
|
||||||
</xs:sequence> |
|
||||||
<xs:element name="job-data-map" type="job-data-mapType" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="job-data-mapType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a JobDataMap</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence minOccurs="0" maxOccurs="unbounded"> |
|
||||||
<xs:element name="entry" type="entryType"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="entryType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a JobDataMap entry</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="key" type="xs:string"/> |
|
||||||
<xs:element name="value" type="xs:string"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="triggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a Trigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:choice> |
|
||||||
<xs:element name="simple" type="simpleTriggerType"/> |
|
||||||
<xs:element name="cron" type="cronTriggerType"/> |
|
||||||
<xs:element name="calendar-interval" type="calendarIntervalTriggerType"/> |
|
||||||
</xs:choice> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="abstractTriggerType" abstract="true"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Common Trigger definitions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="name" type="xs:string"/> |
|
||||||
<xs:element name="group" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="description" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="job-name" type="xs:string"/> |
|
||||||
<xs:element name="job-group" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="priority" type="xs:nonNegativeInteger" minOccurs="0"/> |
|
||||||
<xs:element name="calendar-name" type="xs:string" minOccurs="0"/> |
|
||||||
<xs:element name="job-data-map" type="job-data-mapType" minOccurs="0"/> |
|
||||||
<xs:sequence minOccurs="0"> |
|
||||||
<xs:choice> |
|
||||||
<xs:element name="start-time" type="xs:dateTime"/> |
|
||||||
<xs:element name="start-time-seconds-in-future" type="xs:nonNegativeInteger"/> |
|
||||||
</xs:choice> |
|
||||||
<xs:element name="end-time" type="xs:dateTime" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:sequence> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="simpleTriggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a SimpleTrigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexContent> |
|
||||||
<xs:extension base="abstractTriggerType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="misfire-instruction" type="simple-trigger-misfire-instructionType" minOccurs="0" /> |
|
||||||
<xs:sequence minOccurs="0"> |
|
||||||
<xs:element name="repeat-count" type="repeat-countType"/> |
|
||||||
<xs:element name="repeat-interval" type="xs:nonNegativeInteger"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:sequence> |
|
||||||
</xs:extension> |
|
||||||
</xs:complexContent> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="cronTriggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a CronTrigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexContent> |
|
||||||
<xs:extension base="abstractTriggerType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="misfire-instruction" type="cron-trigger-misfire-instructionType" minOccurs="0"/> |
|
||||||
<xs:element name="cron-expression" type="cron-expressionType"/> |
|
||||||
<xs:element name="time-zone" type="xs:string" minOccurs="0"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:extension> |
|
||||||
</xs:complexContent> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:complexType name="calendarIntervalTriggerType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Define a DateIntervalTrigger</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:complexContent> |
|
||||||
<xs:extension base="abstractTriggerType"> |
|
||||||
<xs:sequence> |
|
||||||
<xs:element name="misfire-instruction" type="date-interval-trigger-misfire-instructionType" minOccurs="0"/> |
|
||||||
<xs:element name="repeat-interval" type="xs:nonNegativeInteger"/> |
|
||||||
<xs:element name="repeat-interval-unit" type="interval-unitType"/> |
|
||||||
</xs:sequence> |
|
||||||
</xs:extension> |
|
||||||
</xs:complexContent> |
|
||||||
</xs:complexType> |
|
||||||
|
|
||||||
<xs:simpleType name="cron-expressionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation> |
|
||||||
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])))?)? |
|
||||||
) |
|
||||||
</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="(((([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](((([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](((([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](((([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](((([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]((([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])?)|([\?])|([\*]))([\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])))?)?)"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="repeat-countType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Number of times to repeat the Trigger (-1 for indefinite)</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:integer"> |
|
||||||
<xs:minInclusive value="-1"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
|
|
||||||
<xs:simpleType name="simple-trigger-misfire-instructionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Simple Trigger Misfire Instructions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_SMART_POLICY"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_FIRE_NOW"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="cron-trigger-misfire-instructionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Cron Trigger Misfire Instructions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_SMART_POLICY"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_DO_NOTHING"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="date-interval-trigger-misfire-instructionType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Date Interval Trigger Misfire Instructions</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_SMART_POLICY"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_DO_NOTHING"/> |
|
||||||
<xs:pattern value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
<xs:simpleType name="interval-unitType"> |
|
||||||
<xs:annotation> |
|
||||||
<xs:documentation>Interval Units</xs:documentation> |
|
||||||
</xs:annotation> |
|
||||||
<xs:restriction base="xs:string"> |
|
||||||
<xs:pattern value="DAY"/> |
|
||||||
<xs:pattern value="HOUR"/> |
|
||||||
<xs:pattern value="MINUTE"/> |
|
||||||
<xs:pattern value="MONTH"/> |
|
||||||
<xs:pattern value="SECOND"/> |
|
||||||
<xs:pattern value="WEEK"/> |
|
||||||
<xs:pattern value="YEAR"/> |
|
||||||
</xs:restriction> |
|
||||||
</xs:simpleType> |
|
||||||
|
|
||||||
</xs:schema> |
|
Loading…
Reference in new issue