1 17 18 19 20 package org.apache.lenya.cms.scheduler; 21 22 import java.io.File ; 23 import java.text.DateFormat ; 24 import java.text.SimpleDateFormat ; 25 import java.util.ArrayList ; 26 import java.util.Date ; 27 import java.util.GregorianCalendar ; 28 import java.util.List ; 29 30 import org.apache.lenya.cms.publication.Publication; 31 import org.apache.lenya.cms.scheduler.xml.TriggerHelper; 32 import org.apache.lenya.xml.DocumentHelper; 33 import org.apache.lenya.xml.NamespaceHelper; 34 import org.apache.log4j.Category; 35 import org.quartz.JobDetail; 36 import org.quartz.SchedulerException; 37 import org.quartz.Trigger; 38 import org.w3c.dom.Document ; 39 import org.w3c.dom.Element ; 40 41 44 public class SchedulerStore { 45 46 public static final String ELEMENT_JOB_GROUP = "job-group"; 47 public static final String ELEMENT_JOB = "job"; 48 public static final String TITLE_ELEMENT = "title"; 49 50 private static final Category log = Category.getInstance(SchedulerStore.class); 51 52 public static final String SNAPSHOT_FILE = 53 "config/scheduler/jobs.xml".replace('/', File.separatorChar); 54 55 59 public SchedulerStore() { 60 } 61 62 68 protected File getJobsFile(Publication publication) throws SchedulerException { 69 File jobsFile; 70 jobsFile = new File (publication.getDirectory(), SNAPSHOT_FILE); 71 log.debug("Resolved job snapshot file: [" + jobsFile.getAbsolutePath() + "]"); 72 return jobsFile; 73 } 74 75 80 protected void writeSnapshot(Publication publication, JobWrapper[] jobs) 81 throws SchedulerException { 82 83 log.debug("Writing job snapshot for publication [" + publication.getId() + "]"); 84 File jobsFile = getJobsFile(publication); 85 86 try { 87 File directory = jobsFile.getParentFile(); 88 89 if (!directory.exists()) { 90 directory.mkdirs(); 91 log.debug("Creating job snapshot directory: " + directory.getPath()); 92 } 93 94 jobsFile.createNewFile(); 95 DocumentHelper.writeDocument(getSnapshot(publication, jobs), jobsFile); 96 } catch (Exception e) { 97 log.error("Writing job snapshot failed: ", e); 98 } 99 } 100 101 108 public Document getSnapshot(Publication publication, JobWrapper[] jobs) 109 throws SchedulerException { 110 NamespaceHelper helper = SchedulerStore.getNamespaceHelper(); 111 Document document = helper.getDocument(); 112 Element root = document.getDocumentElement(); 113 114 log.debug("Creating job snapshot for publication [" + publication.getId() + "]"); 115 root.appendChild(createSnapshot(helper, publication, jobs)); 116 117 return document; 118 } 119 120 121 public static final String NAMESPACE = "http://apache.org/cocoon/lenya/scheduler/1.0"; 122 123 128 public static NamespaceHelper getNamespaceHelper(Document document) { 129 return new NamespaceHelper(NAMESPACE, "sch", document); 130 } 131 132 137 public static NamespaceHelper getNamespaceHelper() { 138 try { 139 return new NamespaceHelper(NAMESPACE, "sch", "scheduler"); 140 } catch (Exception e) { 141 log.error("Could not create namespace helper: ", e); 142 143 return null; 144 } 145 } 146 147 154 protected Element createSnapshot( 155 NamespaceHelper helper, 156 Publication publication, 157 JobWrapper[] jobs) 158 throws SchedulerException { 159 Element jobGroupElement = helper.createElement(ELEMENT_JOB_GROUP); 160 jobGroupElement.setAttribute("name", publication.getId()); 161 162 for (int i = 0; i < jobs.length; i++) { 163 164 ServletJob job = jobs[i].getJob(); 165 Element jobElement = job.save(helper, jobs[i].getJobDetail()); 166 jobGroupElement.appendChild(jobElement); 167 168 Trigger trigger = jobs[i].getTrigger(); 169 170 if (trigger != null) { 171 Element triggerElement = TriggerHelper.createElement(helper, trigger); 172 jobElement.appendChild(triggerElement); 173 } 174 } 175 176 return jobGroupElement; 177 } 178 179 184 public JobWrapper[] restoreJobs(Publication publication) throws SchedulerException { 185 186 log.debug("Restoring jobs for publication [" + publication.getId() + "]"); 187 188 List wrappers = new ArrayList (); 189 File jobsFile = getJobsFile(publication); 190 191 if (jobsFile.exists()) { 192 Element [] jobElements = getJobElements(publication); 193 Document document; 194 try { 195 document = DocumentHelper.readDocument(jobsFile); 196 } catch (Exception e) { 197 throw new SchedulerException(e); 198 } 199 NamespaceHelper helper = SchedulerStore.getNamespaceHelper(document); 200 201 for (int i = 0; i < jobElements.length; i++) { 202 wrappers.add(restoreJob(helper, jobElements[i], publication)); 203 } 204 } 205 else { 206 log.debug("Could not restore jobs for publication [" + publication.getId() + "] - jobs file does not exist."); 207 } 208 209 return (JobWrapper[]) wrappers.toArray(new JobWrapper[wrappers.size()]); 210 } 211 212 217 protected JobWrapper restoreJob( 218 NamespaceHelper helper, 219 Element jobElement, 220 Publication publication) 221 throws SchedulerException { 222 log.debug("Restoring job "); 223 JobWrapper wrapper; 224 225 try { 226 String jobClassName = jobElement.getAttribute(ServletJob.ATTRIBUTE_CLASS); 227 ServletJob job = ServletJobFactory.createJob(jobClassName); 228 JobDetail jobDetail = 229 job.load( 230 jobElement, 231 publication.getId(), 232 publication.getServletContext().getAbsolutePath()); 233 234 Trigger trigger = null; 235 236 Element triggerElement = helper.getFirstChild(jobElement, "trigger"); 237 if (triggerElement != null) { 238 trigger = 239 TriggerHelper.createTrigger( 240 triggerElement, 241 jobDetail.getName(), 242 jobDetail.getGroup()); 243 244 Date now = new GregorianCalendar ().getTime(); 245 if (log.isDebugEnabled()) { 246 DateFormat format = new SimpleDateFormat (); 247 log.debug( 248 " Trigger time: [" + format.format(trigger.getFinalFireTime()) + "]"); 249 log.debug(" Current time: [" + format.format(now) + "]"); 250 } 251 if (!trigger.getFinalFireTime().after(now)) { 252 trigger = null; 253 } 254 } 255 wrapper = new JobWrapper(jobDetail, trigger); 256 257 } catch (Exception e) { 258 throw new SchedulerException(e); 259 } 260 return wrapper; 261 } 262 263 269 protected Element [] getJobElements(Publication publication) throws SchedulerException { 270 Element [] jobElements; 271 try { 272 File jobsFile = getJobsFile(publication); 273 if (jobsFile.exists()) { 274 Document document = DocumentHelper.readDocument(jobsFile); 275 Element schedulerElement = document.getDocumentElement(); 276 NamespaceHelper helper = SchedulerStore.getNamespaceHelper(document); 277 278 Element jobGroupElement = 279 helper.getFirstChild(schedulerElement, SchedulerStore.ELEMENT_JOB_GROUP); 280 if (jobGroupElement == null) { 281 throw new SchedulerException("No <job-group> element found!"); 282 } 283 284 String jobGroupAttribute = jobGroupElement.getAttribute("name"); 285 286 if (!jobGroupAttribute.equals(publication.getId())) { 287 throw new SchedulerException( 288 "The jobs.xml file contains a wrong job group: [" 289 + jobGroupAttribute 290 + "]"); 291 } else { 292 jobElements = helper.getChildren(jobGroupElement, SchedulerStore.ELEMENT_JOB); 293 294 } 295 } else { 296 throw new SchedulerException( 297 "The jobs file [" + jobsFile.getAbsolutePath() + "] does not exist!"); 298 } 299 } catch (SchedulerException e) { 300 throw e; 301 } catch (Exception e) { 302 throw new SchedulerException(e); 303 } 304 return jobElements; 305 } 306 } 307 | Popular Tags |