001: /*
002: * Copyright 2004-2005 OpenSymphony
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy
006: * of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations
014: * under the License.
015: *
016: */
017:
018: /*
019: * Previously Copyright (c) 2001-2004 James House
020: */
021: package org.quartz.jobs;
022:
023: import java.io.File;
024:
025: import org.quartz.JobDataMap;
026: import org.quartz.JobExecutionContext;
027: import org.quartz.JobExecutionException;
028: import org.quartz.SchedulerContext;
029: import org.quartz.SchedulerException;
030: import org.quartz.StatefulJob;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034:
035: /**
036: * Inspects a file and compares whether it's "last modified date" has changed
037: * since the last time it was inspected. If the file has been updated, the
038: * job invokes a "call-back" method on an identified
039: * <code>FileScanListener</code> that can be found in the
040: * <code>SchedulerContext</code>.
041: *
042: * @author jhouse
043: * @see org.quartz.jobs.FileScanListener
044: */
045: public class FileScanJob implements StatefulJob {
046:
047: public static String FILE_NAME = "FILE_NAME";
048: public static String FILE_SCAN_LISTENER_NAME = "FILE_SCAN_LISTENER_NAME";
049: private static String LAST_MODIFIED_TIME = "LAST_MODIFIED_TIME";
050:
051: private final Log log = LogFactory.getLog(getClass());
052:
053: public FileScanJob() {
054: }
055:
056: /**
057: * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
058: */
059: public void execute(JobExecutionContext context)
060: throws JobExecutionException {
061: JobDataMap mergedJobDataMap = context.getMergedJobDataMap();
062: SchedulerContext schedCtxt = null;
063: try {
064: schedCtxt = context.getScheduler().getContext();
065: } catch (SchedulerException e) {
066: throw new JobExecutionException(
067: "Error obtaining scheduler context.", e, false);
068: }
069:
070: String fileName = mergedJobDataMap.getString(FILE_NAME);
071: String listenerName = mergedJobDataMap
072: .getString(FILE_SCAN_LISTENER_NAME);
073:
074: if (fileName == null) {
075: throw new JobExecutionException("Required parameter '"
076: + FILE_NAME + "' not found in merged JobDataMap");
077: }
078: if (listenerName == null) {
079: throw new JobExecutionException("Required parameter '"
080: + FILE_SCAN_LISTENER_NAME
081: + "' not found in merged JobDataMap");
082: }
083:
084: FileScanListener listener = (FileScanListener) schedCtxt
085: .get(listenerName);
086:
087: if (listener == null) {
088: throw new JobExecutionException("FileScanListener named '"
089: + listenerName + "' not found in SchedulerContext");
090: }
091:
092: long lastDate = -1;
093: if (mergedJobDataMap.containsKey(LAST_MODIFIED_TIME)) {
094: lastDate = mergedJobDataMap.getLong(LAST_MODIFIED_TIME);
095: }
096:
097: long newDate = getLastModifiedDate(fileName);
098:
099: if (newDate < 0) {
100: log.warn("File '" + fileName + "' does not exist.");
101: return;
102: }
103:
104: if (lastDate > 0 && (newDate != lastDate)) {
105: // notify call back...
106: log.info("File '" + fileName
107: + "' updated, notifying listener.");
108: listener.fileUpdated(fileName);
109: } else if (log.isDebugEnabled()) {
110: log.debug("File '" + fileName + "' unchanged.");
111: }
112:
113: // It is the JobDataMap on the JobDetail which is actually stateful
114: context.getJobDetail().getJobDataMap().put(LAST_MODIFIED_TIME,
115: newDate);
116: }
117:
118: protected long getLastModifiedDate(String fileName) {
119:
120: File file = new File(fileName);
121:
122: if (!file.exists()) {
123: return -1;
124: } else {
125: return file.lastModified();
126: }
127: }
128: }
|