The Quartz framework contains another listener that we haven't mentioned yet. This one is unlike the other listeners, in that it's designed for a specific purpose: to be used with a utility job that comes with the framework.
The Listener, which is the org.quartz.jobs.FileScanListener interface, is explicitly designed to be used with the FileScanJob, which is also located in the org.quartz.jobs package. The FileScanJob checks the lastModifiedDate on a specific file. When someone changes the file, the job invokes the fileUpdated() method on the FileScanListener.
As with the other types of Quartz listeners, you must create a concrete class that implements the FileScanListener interface. Only one method must be implemented:
public void fileUpdated(String fileName);
Listing 7.12 shows our extremely simple FileScanListener implementation.
Listing 7.12. A Simple FileScanListener Implementation
package org.cavaness.quartzbook.chapter7; import java.io.File; import java.sql.Timestamp; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class SimpleFileScanListener implements org.quartz.jobs.FileScanListener { private static Log logger = LogFactory.getLog(SimpleFileScanListener.class); public void fileUpdated(String fileName) { File file = new File(fileName); Timestamp modified = new Timestamp(file.lastModified()); logger.info( fileName + " was changed at " + modified ); } } |
Obviously, you would want to do something more interesting than just writing out a log message, but you get the point with the simple example in Listing 7.12. We also need to schedule the FileScanJob that uses the new type of listener. Listing 7.13 shows how to schedule the FileScanJob.
Listing 7.13. Scheduling the FileScanJob
package org.cavaness.quartzbook.chapter7; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerUtils; import org.quartz.impl.StdSchedulerFactory; import org.quartz.jobs.FileScanJob; public class Listing_7_13 { private static Log logger = LogFactory.getLog(Listing_7_13.class); public static void main(String[] args) { Listing_7_13 example = new Listing_7_13(); try { Scheduler scheduler = example.createScheduler(); example.scheduleJob(scheduler); scheduler.start(); } catch (SchedulerException ex) { logger.error(ex); } } protected Scheduler createScheduler() throws SchedulerException { return StdSchedulerFactory.getDefaultScheduler(); } protected void scheduleJob(Scheduler scheduler) throws SchedulerException { // Store the FileScanListener instance scheduler.getContext().put("SimpleFileScanListener", new SimpleFileScanListener()); // Create a JobDetail for the FileScanJob JobDetail jobDetail = new JobDetail("FileScanJob", null, FileScanJob.class); // The FileScanJob needs some parameters JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put(FileScanJob.FILE_NAME, "C:\quartz-book\input1\test.txt"); jobDataMap.put(FileScanJob.FILE_SCAN_LISTENER_NAME, "SimpleFileScanListener"); jobDetail.setJobDataMap(jobDataMap); // Create a Trigger and register the Job Trigger trigger = TriggerUtils.makeSecondlyTrigger(30); trigger.setName("SimpleTrigger"); trigger.setStartTime(new Date()); scheduler.scheduleJob(jobDetail, trigger); } } |
The program in Listing 7.13 is like almost every other Quartz application that needs to schedule a job. The FileScanJob requires two parameters: the FILE_NAME of the file to watch and the name of the FileScanListener (FILE_SCAN_LISTENER_NAME). The values for these two parameters are stored in the JobDataMap so the FileScanJob can access them.
The only "gotcha" that you should watch out for is to make sure that you add an instance of the FileScanListener to the SchedulerContext. This is done in Listing 7.13 and shown in the following code fragment:
scheduler.getContext().put("SimpleFileScanListener", new SimpleFileScanListener());
This is necessary because the FileScanJob gets a reference to the SchedulerContext and looks for a FileScanListener using the name that was set in the JobDataMap:
jobDataMap.put(FileScanJob.FILE_SCAN_LISTENER_NAME, "SimpleFileScanListener");
If you are confused, don't worry: Look at the source code for the org.quartz.jobs.FileScanJob class. That's one of the best things about open source software.
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