001: /*
002: * Copyright 2007 Paolo Spizzirri (paolo.spizzirri@assetdata.it)
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy 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,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.romaframework.module.schedulerquartz;
018:
019: import java.text.DateFormat;
020: import java.util.ArrayList;
021: import java.util.Date;
022: import java.util.List;
023: import java.util.Map;
024:
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027: import org.quartz.CronTrigger;
028: import org.quartz.JobDetail;
029: import org.quartz.JobExecutionContext;
030: import org.quartz.SchedulerException;
031: import org.quartz.SchedulerFactory;
032: import org.quartz.SimpleTrigger;
033: import org.quartz.Trigger;
034: import org.quartz.impl.StdSchedulerFactory;
035: import org.romaframework.aspect.i18n.I18NAspect;
036: import org.romaframework.aspect.persistence.PersistenceAspect;
037: import org.romaframework.aspect.persistence.QueryByFilter;
038: import org.romaframework.aspect.scheduler.SchedulerAspectAbstract;
039: import org.romaframework.aspect.scheduler.SchedulerEvent;
040: import org.romaframework.aspect.view.ViewAspect;
041: import org.romaframework.core.Utility;
042: import org.romaframework.core.command.CommandContext;
043: import org.romaframework.core.config.RomaApplicationContext;
044: import org.romaframework.core.flow.ObjectContext;
045: import org.romaframework.core.schema.SchemaClassResolver;
046: import org.romaframework.module.schedulerquartz.command.CommandJobDelegate;
047: import org.romaframework.module.schedulerquartz.domain.QuartzSchedulerEvent;
048:
049: public class QuartzSchedulerAspect extends SchedulerAspectAbstract {
050:
051: protected static final Log log = LogFactory
052: .getLog(QuartzSchedulerAspect.class);
053:
054: protected org.quartz.Scheduler scheduler;
055:
056: private Map<String, Object> jobsImplementation = null;
057:
058: public org.quartz.Scheduler getScheduler() {
059: return scheduler;
060: }
061:
062: public QuartzSchedulerAspect() {
063: }
064:
065: public void shutdown() {
066: try {
067: scheduler.shutdown();
068: } catch (SchedulerException e) {
069: log.error(e);
070: }
071: }
072:
073: public void run() {
074: // REGISTER THE APPLICATION DOMAIN
075: RomaApplicationContext.getInstance().getBean(
076: SchemaClassResolver.class).addDomainPackage(
077: QuartzSchedulerAspect.class.getPackage().getName());
078:
079: // REGISTER THE APPLICATION DOMAIN + VIEW
080: RomaApplicationContext.getInstance().getBean(
081: SchemaClassResolver.class).addDomainPackage(
082: QuartzSchedulerAspect.class.getPackage().getName()
083: + Utility.PACKAGE_SEPARATOR
084: + ViewAspect.ASPECT_NAME);
085:
086: SchedulerFactory factory = new StdSchedulerFactory();
087: try {
088: scheduler = factory.getScheduler();
089: scheduler.start();
090: log.info("Scheduler succesfully Started");
091:
092: } catch (SchedulerException sce) {
093: throw new org.romaframework.aspect.scheduler.SchedulerException(
094: "Scheduler engene not started", sce);
095: }
096:
097: List<QuartzSchedulerEvent> events = loadStoredEvents();
098: for (QuartzSchedulerEvent event : events) {
099: try {
100: schedule(event);
101: log.info("Scheduled Job: " + event.getName());
102: } catch (org.romaframework.aspect.scheduler.SchedulerException rsce) {
103: log
104: .error("Error on scheduling job: "
105: + event.getName());
106: }
107: }
108: }
109:
110: public void pauseJob(SchedulerEvent event)
111: throws org.romaframework.aspect.scheduler.SchedulerException {
112: String jobName = null;
113: try {
114: log.info("Pausing Job: " + event.getName());
115: scheduler.pauseJob(event.getName(), null);
116: } catch (SchedulerException sce) {
117: log.error("Error on pausing Job: " + jobName);
118: throw new org.romaframework.aspect.scheduler.SchedulerException(
119: sce);
120: }
121: }
122:
123: public void unpauseJob(SchedulerEvent iEvent)
124: throws org.romaframework.aspect.scheduler.SchedulerException {
125: try {
126:
127: log.info("Pausing Job: " + iEvent.getName());
128: scheduler.resumeJob(iEvent.getName(), null);
129: } catch (SchedulerException sce) {
130: log.error("Error on pausing Job: " + iEvent.getName());
131: throw new org.romaframework.aspect.scheduler.SchedulerException(
132: sce);
133: }
134:
135: }
136:
137: public void executeNow(SchedulerEvent iEvent)
138: throws org.romaframework.aspect.scheduler.SchedulerException {
139: try {
140: scheduler.triggerJob(iEvent.getName(), null);
141: } catch (SchedulerException sce) {
142: throw new org.romaframework.aspect.scheduler.SchedulerException(
143: "Errore nell'esecuzione del Job selezionato", sce);
144: }
145: }
146:
147: public void schedule(SchedulerEvent iEvent)
148: throws org.romaframework.aspect.scheduler.SchedulerException {
149: try {
150: JobDetail quartzJob = new JobDetail(iEvent.getName(), null,
151: Class.forName(CommandJobDelegate.class.getName()));
152: quartzJob.getJobDataMap().put(
153: CommandJobDelegate.PAR_COMMAND,
154: getJobImplementation(iEvent.getImplementation()));
155: quartzJob.getJobDataMap().put(
156: CommandJobDelegate.PAR_CONTEXT,
157: new CommandContext(iEvent.getContext()));
158: Trigger quartzTrigger;
159: if (iEvent.getRule() == null || iEvent.getRule().equals(""))
160: quartzTrigger = new SimpleTrigger(iEvent.getName(),
161: null, iEvent.getStartTime());
162: else
163: quartzTrigger = new CronTrigger(iEvent.getName(), null,
164: iEvent.getName(), null, iEvent.getStartTime(),
165: null, iEvent.getRule());
166: scheduler.scheduleJob(quartzJob, quartzTrigger);
167: } catch (Exception ex) {
168: throw new org.romaframework.aspect.scheduler.SchedulerException(
169: "Error on Job Scheduling: " + iEvent.getName(), ex);
170: }
171: }
172:
173: public void unSchedule(SchedulerEvent iEvent)
174: throws org.romaframework.aspect.scheduler.SchedulerException {
175: try {
176: this .scheduler.deleteJob(iEvent.getName(), null);
177: } catch (Exception ex) {
178: throw new org.romaframework.aspect.scheduler.SchedulerException(
179: "Errore durante l'eliminazione del Job: "
180: + iEvent.getName(), ex);
181: }
182: }
183:
184: private static List<QuartzSchedulerEvent> loadStoredEvents() {
185: PersistenceAspect db = ObjectContext.getInstance()
186: .getComponent("NoTxPersistenceAspect");
187: QueryByFilter filter = new QueryByFilter(
188: QuartzSchedulerEvent.class);
189: return db.query(filter);
190: }
191:
192: public String getNextEventExcecution(String name) {
193: String nextFire = null;
194: DateFormat dateFormatter = ObjectContext.getInstance()
195: .getComponent(I18NAspect.class).getDateTimeFormat();
196: try {
197: Trigger trigger = scheduler.getTrigger(name, null);
198: nextFire = dateFormatter.format(trigger.getNextFireTime());
199: } catch (Exception ex) {
200: log.error("Error on retrieveng trigger status");
201: nextFire = "Error";
202: }
203:
204: return nextFire;
205: }
206:
207: public String getLastEventExcecution(String name) {
208: String NOT_YET_EXECUTED = "Not yet exexcuted";
209: String ERROR = "Error";
210:
211: String lastFire = NOT_YET_EXECUTED;
212: DateFormat dateFormatter = ObjectContext.getInstance()
213: .getComponent(I18NAspect.class).getDateTimeFormat();
214: try {
215: Trigger trigger = scheduler.getTrigger(name, null);
216: Date date = trigger.getPreviousFireTime();
217: if (date != null)
218: lastFire = dateFormatter.format(date);
219: } catch (Exception ex) {
220: log.error("Errror on retrieving trigger State");
221: log.error(ex);
222: lastFire = ERROR;
223: }
224:
225: return lastFire;
226: }
227:
228: public void setJobsImplementation(
229: Map<String, Object> jobsImplementation) {
230: this .jobsImplementation = jobsImplementation;
231: }
232:
233: public Map<String, Object> getJobsImplementation() {
234: return jobsImplementation;
235: }
236:
237: public List<String> getImplementationsList() {
238: if (jobsImplementation == null)
239: return null;
240: List<String> implementationsList = new ArrayList<String>();
241: for (String jobImplemetation : jobsImplementation.keySet())
242: implementationsList.add(jobImplemetation);
243: return implementationsList;
244: }
245:
246: public Object getJobImplementation(String implementation) {
247: return jobsImplementation.get(implementation);
248: }
249:
250: public String getEventState(String name) {
251: String EXECUTING = "Executing";
252: String status = null;
253: try {
254: status = getEventStateTrigger(name);
255: List<String> executingJobs = getCurrentlyExecutingJobs();
256: if (executingJobs != null && executingJobs.size() > 0
257: && executingJobs.contains(name))
258: status = EXECUTING;
259:
260: } catch (Exception ex) {
261:
262: }
263:
264: return status;
265:
266: }
267:
268: private String getEventStateTrigger(String name)
269: throws org.romaframework.aspect.scheduler.SchedulerException {
270: String status = null;
271: int state = 0;
272: try {
273: state = scheduler.getTriggerState(name, null);
274: } catch (SchedulerException sce) {
275: log.error("Error on retrieving trigger status");
276: }
277: switch (state) {
278: case -1:
279: status = "Not Scheduled";
280: break;
281:
282: case 0:
283: status = "Normal";
284: break;
285:
286: case 1:
287: status = "Paused";
288: break;
289:
290: case 2:
291: status = "Completed";
292: break;
293:
294: case 3:
295: status = "Error";
296: break;
297:
298: case 4:
299: status = "Blocked";
300: break;
301:
302: default:
303: break;
304: }
305:
306: return status;
307:
308: }
309:
310: private List<String> getCurrentlyExecutingJobs() {
311: List<String> executingJobs = null;
312:
313: try {
314: List<JobExecutionContext> executionContexts = scheduler
315: .getCurrentlyExecutingJobs();
316: if (executionContexts != null
317: || executionContexts.size() > 0) {
318: executingJobs = new ArrayList<String>();
319: for (JobExecutionContext executionContext : executionContexts)
320: executingJobs.add(executionContext.getJobDetail()
321: .getName());
322: }
323: } catch (SchedulerException sce) {
324: log
325: .error("Error on retrieving executing jobs from scheduler");
326: }
327:
328: return executingJobs;
329:
330: }
331:
332: }
|