Creating a Quartz Plug-In

Creating a new plug-in is very simple. All you have to do is create a Java class (or reuse an existing one) that implements the org.quartz.spi.SchedulerPlugin interface. The Scheduler will create an instance of the plug-in during startup. The plug-in must have a no-argument constructor and obviously not be abstract.

The JobInitializationPlugin

The Quartz framework includes a plug-in for loading job and trigger information from an XML file. The plug-in is org.quartz.plugins.xml.JobInitializationPlugin and was discussed briefly back in Chapter 3, "Hello, Quartz." When you use this plug-in, the Quartz framework searches for a file called quartz_jobs.xml and attempts to load job and trigger information from this file.

Changing the XML File That the JobInitializationPlugin Loads From

The plug-in enables you to change the name of the jobs file that it looks for to load job and trigger information. You change it by setting a different filename in the quartz.properties file. We talk more about setting parameters for plug-ins later in this chapter.

As Chapter 3 explained, this plug-in is very convenient when your application requirements don't involve loading job information from a database. It's also very useful during development and testing because you can quickly configure which jobs and triggers are to be fired. That is, arguably, it's easier to modify an XML file than a set of database tables.

A nice extension to this idea of loading job and trigger information from an XML file would be to have a directory where you can store job XML files, and, by using a plug-in, the Scheduler would load whatever job files were present. This would enable you to conveniently add or remove jobs at Scheduler startup by simply adding or removing them from the specified directory. In the rest of this chapter, we show you how to build this plug-in.

Creating the JobLoaderPlugin

We call this new plug-in the JobLoaderPlugin. Listing 8.2 shows the JobLoaderPlugin class.

Listing 8.2. A Quartz SchedulerPlugin that Loads Multiple Job Files from a Directory

package org.cavaness.quartzbook.chapter8;

import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Scheduler;
import org.quartz.SchedulerConfigException;
import org.quartz.SchedulerException;
import org.quartz.spi.SchedulerPlugin;
import org.quartz.xml.JobSchedulingDataProcessor;

public class JobLoaderPlugin implements SchedulerPlugin {

 private static Log logger =
 LogFactory.getLog(JobLoaderPlugin.class);
 
 // The directory to load jobs from
 private String jobsDirectory;
 
 // An array of File objects
 private File[] jobFiles = null;
 
 private String pluginName;
 
 private Scheduler scheduler;

 private boolean validateXML = true;

 private boolean validateSchema = true;

 public JobLoaderPlugin() {
 }

 public File[] getJobFiles() {
 return jobFiles;
 }

 public void setJobFiles(File[] jobFiles) {
 this.jobFiles = jobFiles;
 }

 public boolean isValidateSchema() {
 return validateSchema;
 }
 
 public void setValidateSchema(boolean validatingSchema) {
 this.validateSchema = validatingSchema;
 }
 
 public void initialize(String name, final Scheduler scheduler)
 throws SchedulerException {

 this.pluginName = name;
 this.scheduler = scheduler;
 
 logger.debug("Registering Plugin " + pluginName);
 // Load the job definitions from the specified directory
 loadJobs();
}
private void loadJobs() throws SchedulerException {

 File dir = null;

 // Check directory
 if (getJobsDirectory() == null
 || !(dir =
 new File(getJobsDirectory())).exists()) {
 throw new SchedulerConfigException(
 "The jobs directory was missing "
 + jobsDirectory);

 }
 logger.info("Loading jobs from " + dir.getName());

 // Only XML files, filtering out any directories
 this.jobFiles = dir.listFiles(new XMLFileOnlyFilter());
}

public void start() {
 processJobs();
}

public void shutdown() {
 // nothing to clean up
}

public void processJobs() {
 // There should be at least one job
 if (getJobFiles() == null || getJobFiles().length == 0) {
 return;
 }

 JobSchedulingDataProcessor processor =
 new JobSchedulingDataProcessor(
 true, isValidateXML(), isValidateSchema());

 int size = getJobFiles().length;
 for (int i = 0; i < size; i++) {
 File jobFile = getJobFiles()[i];

 String fileName = jobFile.getAbsolutePath();
 logger.debug("Loading job file: " + fileName);

 try {

 processor.processFileAndScheduleJobs(
 fileName, scheduler, true);

 } catch (Exception ex) {
 logger.error("Error loading jobs: " + fileName);
 logger.error(ex);
 }
 }
 }

 public String getJobsDirectory() {
 return jobsDirectory;
 }

 public void setJobsDirectory(String jobsDirectory) {
 this.jobsDirectory = jobsDirectory;
 }

 public String getPluginName() {
 return pluginName;
 }

 public void setPluginName(String pluginName) {
 this.pluginName = pluginName;
 }

 public boolean isValidateXML() {
 return validateXML;
 }

 public void setValidateXML(boolean validateXML) {
 this.validateXML = validateXML;
 }
}

The real work of the JobLoaderPlugin in Listing 8.2 is done in just two methods: initialize() and start(). Both are required by the SchedulerPlugin interface. The rest of the methods are just setXXX and getXXX methods to fulfill the JavaBean contract because private properties have been declared.

The JobLoaderPlugin initialize() Method

As you can see, the initialize() method, which is called by the Scheduler, calls the private loadJobs() method. The loadJobs() method uses the jobsDirectory that was passed in from the quartz.properties file to retrieve all XML files stored in that directory. The plug-in doesn't try to schedule the jobs yet because the Scheduler isn't fully instantiated when the plug-in's initialize() method is called. The JobLoaderPlugin simply holds on to an array of File objects, waiting for the start() method to be called. We also hold on to the instance of the Scheduler so that we have access to it when the start() method is called.

The JobLoaderPlugin start() Method

When the Scheduler calls the start() method in the JobLoaderPlugin, the start() method calls processJobs(). The processJobs() method loops through the array of job files and loads each one into the Scheduler instance.

The processing of the job file is done by an instance of an org.quartz.xml JobSchedulingDataProcessor. The processFileAndScheduleJobs() method is called and passed the filename, the Scheduler instance, and a Boolean that tells whether existing jobs should be overwritten.

When the processJobs() method is complete, all job files from the specified jobsDirectory should have been loaded and scheduled.


Registering Your Plug Ins

Scheduling in the Enterprise

Getting Started with Quartz

Hello, Quartz

Scheduling Jobs

Cron Triggers and More

JobStores and Persistence

Implementing Quartz Listeners

Using Quartz Plug-Ins

Using Quartz Remotely

Using Quartz with J2EE

Clustering Quartz

Quartz Cookbook

Quartz and Web Applications

Using Quartz with Workflow

Appendix A. Quartz Configuration Reference



Quartz Job Scheduling Framework(c) Building Open Source Enterprise Applications
Quartz Job Scheduling Framework: Building Open Source Enterprise Applications
ISBN: 0131886703
EAN: 2147483647
Year: N/A
Pages: 148

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net