1 /**
2 * Copyright 2005-2006 the original author or authors.
3 *
4 * Licensed under the Gnu General Pubic License, Version 2.0 (the
5 * "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/gpl-license.php
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the Gnu General Public License for more details.
14 */
15 package org.figure8.join.services.scripting;
16
17 import org.figure8.join.core.EntityObject;
18 import org.figure8.join.core.InvalidParameterException;
19 import org.figure8.join.services.scheduling.QuartzCronManager;
20 import org.figure8.join.services.scheduling.QuartzCronParameterInfo;
21 import org.figure8.join.util.LogUtil;
22
23 import org.apache.commons.logging.Log;
24 import org.quartz.Job;
25 import org.quartz.JobExecutionContext;
26 import org.quartz.JobExecutionException;
27
28 import java.io.File;
29 import java.io.FileOutputStream;
30 import java.io.FileNotFoundException;
31 import java.util.Date;
32 import java.util.Iterator;
33 import java.util.Properties;
34 /**
35 * This is a base class for Quartz jobs that wants to launch script when
36 * the time scheduled with cron arrive. It acts as an adapter between the
37 * scheduled batch world and the {@link ScriptLauncher} facilities.
38 * <br/>
39 * This class is a Quartz {@link Job} that is {@link org.figure8.join.core.Configurable}.
40 * <br/>
41 *
42 * @see org.figure8.join.core.Configurable
43 *
44 * @author <a href="mailto:jerome.evrard@gmail.com">Jerome Evrard</a>
45 * @version $Revision: 1.2 $
46 */
47 public abstract class ScriptLauncherQuartzAdapter extends ScriptLauncherAdapterSupport implements Job{
48
49
50
51 /** Get a commons logger. */
52 private static final Log log = LogUtil.getLog(ScriptLauncherQuartzAdapter.class);
53
54
55
56
57 /**
58 * This method is executed when scheduled time is reached.
59 * @param context The execution context of the job (contains job's user parameters)
60 */
61 public void execute(JobExecutionContext context) throws JobExecutionException{
62
63 setName(context.getJobDetail().getName());
64 ScriptLogInfo logInfo = null;
65 File logFile = createNewLogFile();
66
67
68 Object entity = getParameterFromContext(QuartzCronManager.JOB_ENTITY, context);
69 if (entity != null && entity instanceof EntityObject){
70 log.debug("An Entity is present into execution context: " + entity);
71 logInfo = new ScriptLogInfo((EntityObject)entity, logFile.getPath().replace('\\', '/'),
72 context.getJobDetail().getName(), "QuartzAdapter", "Unknown file path");
73 }
74 else{
75 logInfo = new ScriptLogInfo(logFile.getPath().replace('\\', '/'),
76 context.getJobDetail().getName(), "QuartzAdapter", "Unknown file path");
77 }
78
79 try {configureJobFromContext(context);}
80 catch (InvalidParameterException ipe){
81 log.fatal("Exception while configuring the Job using parameters present into JobExecutionContext");
82 log.fatal("Here's the detailed message: " + ipe.getMessage());
83
84 if (logInfo != null){
85 logInfo.setExceptionMsg(ipe.getMessage());
86 saveLogInfoIfAvailable(logInfo);
87 }
88 return;
89 }
90
91 if (logInfo != null){
92 logInfo.setScriptFile(getScriptLauncher().getScriptPath());
93 }
94
95
96 Properties jobProperties = new Properties();
97 Iterator dataKeys = context.getJobDetail().getJobDataMap().keySet().iterator();
98 while (dataKeys.hasNext()){
99
100 Object key = dataKeys.next();
101 Object value = getParameterFromContext(key.toString(), context);
102 if (value != null && value instanceof QuartzCronParameterInfo){
103 QuartzCronParameterInfo param = (QuartzCronParameterInfo)value;
104 if (!param.isJobParameter())
105 jobProperties.put(key.toString(), param.getValue());
106 }
107 else jobProperties.put(key.toString(), value);
108 }
109
110 try{
111
112 if (log.isInfoEnabled())
113 log.info("Launching the script of '" + name + "' Quartz adapter. Start time is: " + new Date());
114
115 getScriptLauncher().setLogOutputStream(new FileOutputStream(logFile));
116 getScriptLauncher().runScript(jobProperties);
117
118 context.setResult(new Integer(0));
119 logInfo.setExceptionMsg("Execution is properly terminated.");
120 }
121 catch (ScriptException se){
122
123 context.setResult(new Integer(1));
124 log.error("ScriptException when running " + getScriptLauncher().getScriptPath() + ": " + se.getMessage());
125
126 if (logInfo != null)
127 logInfo.setExceptionMsg(se.getMessage());
128 }
129 catch (FileNotFoundException fnfe){
130
131 log.error("FileNotFoundException while getting OS on " + logFile.getPath() + ": " + fnfe.getMessage());
132 context.setResult(new Integer(1));
133
134 if (logInfo != null)
135 logInfo.setExceptionMsg(fnfe.getMessage());
136 }
137 finally{
138
139 if (log.isInfoEnabled())
140 log.info("Script of '" + name + "' Quartz adapter has end. Stop time is: " + new Date());
141 }
142
143
144 if (logInfo != null){
145 boolean done = saveLogInfoIfAvailable(logInfo);
146 }
147 return;
148 }
149
150
151
152
153 /**
154 * This is a convenient method for retrieving a cron parameter value from context.
155 * @param key The key of cron parameter to retrieve.
156 * @param context The job context to retrieve parameter from
157 * @return An object representing Quartz Cron parameter value
158 */
159 protected Object getParameterFromContext(String key, JobExecutionContext context){
160 return context.getJobDetail().getJobDataMap().get(key);
161 }
162
163 /**
164 * Configure this job instance using the {@link QuartzCronParameterInfo} that
165 * may be present into the execution context. This may be necessary because when
166 * launched by a scheduler, job instance is not directly available so configuration
167 * parameters may be passed using the job details data map.
168 * @param context
169 * @throws InvalidParameterException
170 */
171 protected void configureJobFromContext(JobExecutionContext context) throws InvalidParameterException{
172 Iterator values = context.getJobDetail().getJobDataMap().values().iterator();
173 while (values != null && values.hasNext()){
174 Object value = values.next();
175 if (value instanceof QuartzCronParameterInfo){
176 QuartzCronParameterInfo paramInfo = (QuartzCronParameterInfo)value;
177 if (paramInfo.isJobParameter()){
178
179 if (log.isDebugEnabled())
180 log.debug("Configuring the ScriptLauncher with: " + paramInfo.getName() + "[" + paramInfo.getValue() + "]");
181 setParameter(paramInfo.getName(), paramInfo.getValue());
182 }
183 }
184 }
185 }
186 }