1 17 18 19 20 package org.apache.lenya.cms.scheduler; 21 22 import java.io.File ; 23 import java.io.FileFilter ; 24 import java.io.IOException ; 25 import java.io.PrintWriter ; 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.Date ; 29 import java.util.Enumeration ; 30 import java.util.HashMap ; 31 import java.util.Iterator ; 32 import java.util.List ; 33 import java.util.Map ; 34 35 import javax.servlet.ServletConfig ; 36 import javax.servlet.ServletContext ; 37 import javax.servlet.ServletException ; 38 import javax.servlet.http.HttpServlet ; 39 import javax.servlet.http.HttpServletRequest ; 40 import javax.servlet.http.HttpServletResponse ; 41 42 import org.apache.lenya.cms.publication.DocumentBuildException; 43 import org.apache.lenya.cms.publication.Publication; 44 import org.apache.lenya.cms.publication.PublicationException; 45 import org.apache.lenya.cms.publication.PublicationFactory; 46 import org.apache.lenya.cms.publishing.PublishingEnvironment; 47 import org.apache.lenya.cms.scheduler.xml.TriggerHelper; 48 import org.apache.lenya.util.NamespaceMap; 49 import org.apache.lenya.xml.DocumentHelper; 50 import org.apache.log4j.Category; 51 import org.quartz.SchedulerException; 52 import org.w3c.dom.Document ; 53 54 57 public class LoadQuartzServlet extends HttpServlet { 58 private static Category log = Category.getInstance(LoadQuartzServlet.class); 59 private static SchedulerWrapper scheduler = null; 60 private ServletContext servletContext; 61 private String schedulerConfigurations; 62 63 public static final String PREFIX = "scheduler"; 64 public static final String PARAMETER_ACTION = "action"; 65 public static final String PARAMETER_PUBLICATION_ID = "publication-id"; 66 public static final String PARAMETER_DOCUMENT_URL = "document-url"; 67 public static final String CONFIGURATION_ELEMENT = "scheduler-configurations"; 68 69 73 public static SchedulerWrapper getScheduler() { 74 return scheduler; 75 } 76 77 80 private static Map servlets = new HashMap (); 81 82 87 public void init(ServletConfig config) throws ServletException { 88 super.init(config); 89 90 this.schedulerConfigurations = config.getInitParameter(CONFIGURATION_ELEMENT); 91 this.servletContext = config.getServletContext(); 92 93 log.debug( 94 ".init(): Servlet Context Path: " + getServletContextDirectory().getAbsolutePath()); 95 96 try { 97 log.debug("Storing servlet"); 98 String contextPath = getServletContextDirectory().getCanonicalPath(); 99 log.debug(" Context path: [" + contextPath + "]"); 100 servlets.put(contextPath, this); 101 } catch (IOException e) { 102 throw new ServletException (e); 103 } 104 105 log.debug(".init(): Scheduler Configurations: " + this.schedulerConfigurations); 106 107 try { 108 log.info("Working?..."); 109 process(); 110 log.info("OK"); 111 } catch (Exception e) { 112 log.error("Init of LoadQuartzServlet failed", e); 113 throw new ServletException (e); 114 } 115 } 116 117 123 public void process() throws ServletException , SchedulerException { 124 scheduler = 125 new SchedulerWrapper( 126 getServletContextDirectory().getAbsolutePath(), 127 schedulerConfigurations); 128 129 try { 130 ShutdownHook(); 131 } catch (Exception e) { 132 log.error(e.toString(), e); 133 } 134 135 restoreJobs(); 136 } 137 138 141 public void destroy() { 142 destroyScheduler(); 143 } 144 145 148 public static void destroyScheduler() { 149 log.debug("destroy: "); 150 getScheduler().shutdown(); 151 } 152 153 159 public static void ShutdownHook() throws Exception { 160 log.debug("-------------------- ShutdownHook --------------------"); 161 Runtime.getRuntime().addShutdownHook(new Thread () { 162 public void run() { 163 LoadQuartzServlet.destroyScheduler(); 164 } 165 }); 166 log.debug("-------------------- End ShutdownHook --------------------"); 167 } 168 169 176 public void doGet(HttpServletRequest request, HttpServletResponse response) 177 throws IOException , ServletException { 178 handleRequest(request, response); 179 } 180 181 190 public void doPost(HttpServletRequest req, HttpServletResponse resp) 191 throws ServletException , IOException { 192 doGet(req, resp); 193 } 194 195 protected static final String ADD = "add"; 196 protected static final String MODIFY = "modify"; 197 protected static final String DELETE = "delete"; 198 protected static final String DOCUMENT_DELETED = "document-deleted"; 199 200 206 protected void handleRequest(HttpServletRequest request, HttpServletResponse response) 207 throws IOException { 208 log.debug("----------------------------------------------------------------"); 209 log.debug("- Incoming request at URI: "); 210 log.debug( 211 request.getServerName() + ":" + request.getServerPort() + request.getRequestURI()); 212 log.debug("----------------------------------------------------------------"); 213 log.debug("Request parameters:"); 214 215 NamespaceMap schedulerParameters = getSchedulerParameters(request); 216 217 try { 218 String publicationId = (String ) schedulerParameters.get(PARAMETER_PUBLICATION_ID); 219 log.debug("Scheduler invoked."); 220 221 log.debug("Scheduler Parameters:"); 222 log.debug(" scheduler.publication-id: [" + publicationId + "]"); 223 224 logSessionAttributes(request); 225 226 String action = (String ) schedulerParameters.get(PARAMETER_ACTION); 228 log.debug(" scheduler.action: [" + action + "]"); 229 if (action == null) { 230 } else if (action.equals(ADD)) { 231 Date startTime = TriggerHelper.getDate(schedulerParameters); 232 getScheduler().addJob(publicationId, startTime, request); 233 } else if (action.equals(MODIFY)) { 234 Date startTime = TriggerHelper.getDate(schedulerParameters); 235 String jobId = getJobId(schedulerParameters); 236 getScheduler().modifyJob(jobId, publicationId, startTime); 237 } else if (action.equals(DELETE)) { 238 String jobId = getJobId(schedulerParameters); 239 getScheduler().deleteJob(jobId, publicationId); 240 } else if (action.equals(DOCUMENT_DELETED)) { 241 242 Publication publication = 243 PublicationFactory.getPublication( 244 publicationId, 245 getServletContextDirectory().getAbsolutePath()); 246 247 String documentUrl = (String ) schedulerParameters.get(PARAMETER_DOCUMENT_URL); 248 org.apache.lenya.cms.publication.Document document = 249 publication.getDocumentBuilder().buildDocument(publication, documentUrl); 250 deleteDocumentJobs(document); 251 } 252 253 PrintWriter writer = response.getWriter(); 256 response.setContentType("text/xml"); 257 258 Document snapshot = getScheduler().getSnapshot(); 259 260 DocumentHelper.writeDocument(snapshot, writer); 261 } catch (Exception e) { 262 log.error("Can't create job snapshot: ", e); 263 throw new IOException (e.getMessage() + " (view log for details)"); 264 } 265 } 266 267 272 public static NamespaceMap getSchedulerParameters(HttpServletRequest request) { 273 Map parameterMap = new HashMap (); 274 List keys = new ArrayList (); 275 for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) { 276 String key = (String ) e.nextElement(); 277 keys.add(key); 278 } 279 Collections.sort(keys); 280 for (Iterator i = keys.iterator(); i.hasNext();) { 281 String key = (String ) i.next(); 282 String [] values = request.getParameterValues(key); 283 log.debug(" [" + key + "] = [" + values[0] + "]"); 284 if (values.length == 1) { 285 parameterMap.put(key, values[0]); 286 } else { 287 parameterMap.put(key, values); 288 } 289 } 290 291 NamespaceMap schedulerParameters = new NamespaceMap(parameterMap, PREFIX); 292 return schedulerParameters; 293 } 294 295 302 public void deleteDocumentJobs(org.apache.lenya.cms.publication.Document document) 303 throws DocumentBuildException, SchedulerException, PublicationException { 304 log.debug("Requested to delete jobs for document URL [" + document.getCompleteURL() + "]"); 305 getScheduler().deleteJobs(document); 306 } 307 308 313 protected String getJobId(NamespaceMap schedulerParameters) { 314 String parameterName = 315 NamespaceMap.getFullName(SchedulerWrapper.JOB_PREFIX, SchedulerWrapper.JOB_ID); 316 String jobId = (String ) schedulerParameters.get(parameterName); 317 log.debug(" scheduler.job.id: [" + jobId + "]"); 318 return jobId; 319 } 320 321 325 protected void logSessionAttributes(HttpServletRequest request) { 326 log.debug("-------------------- Session Attributes --------------------"); 327 for (Enumeration e = request.getSession().getAttributeNames(); e.hasMoreElements();) { 328 String name = (String ) e.nextElement(); 329 log.debug(name + " = " + request.getSession().getAttribute(name)); 330 } 331 log.debug("-------------------- End Session Attributes --------------------"); 332 } 333 334 339 public File getServletContextDirectory() { 340 return new File (this.servletContext.getRealPath("/")); 341 } 342 343 347 public void restoreJobs() throws SchedulerException { 348 349 File publicationsDirectory = 350 new File (getServletContextDirectory(), PublishingEnvironment.PUBLICATION_PREFIX); 351 352 File [] publicationDirectories = publicationsDirectory.listFiles(new FileFilter () { 353 public boolean accept(File file) { 354 return file.isDirectory(); 355 } 356 }); 357 358 log.debug("========================================="); 359 log.debug(" Restoring jobs."); 360 log.debug(" servlet context: [" + getServletContextDirectory() + "]"); 361 log.debug(" publications directory: [" + publicationsDirectory + "]"); 362 log.debug("========================================="); 363 364 for (int i = 0; i < publicationDirectories.length; i++) { 365 File directory = publicationDirectories[i]; 366 String publicationId = directory.getName(); 367 if (PublicationFactory 368 .existsPublication(publicationId, getServletContextDirectory().getAbsolutePath())) { 369 getScheduler().restoreJobs(publicationId); 370 } 371 } 372 } 373 374 public static final String SERVLET_URL = "/servlet/QuartzSchedulerServlet"; 375 376 381 public static LoadQuartzServlet getServlet(String contextPath) { 382 return (LoadQuartzServlet) servlets.get(contextPath); 383 } 384 385 390 public static String getDeleteDocumentRequestURI( 391 String port, 392 String servletContextPath, 393 org.apache.lenya.cms.publication.Document document) { 394 395 NamespaceMap requestParameters = new NamespaceMap(PREFIX); 396 requestParameters.put(PARAMETER_ACTION, DOCUMENT_DELETED); 397 requestParameters.put(PARAMETER_PUBLICATION_ID, document.getPublication().getId()); 398 requestParameters.put(PARAMETER_DOCUMENT_URL, document.getCompleteURL()); 399 400 String requestUri = "http://127.0.0.1:" + port + servletContextPath + "?"; 401 Map map = requestParameters.getMap(); 402 403 String [] keys = (String []) map.keySet().toArray(new String [map.keySet().size()]); 404 for (int i = 0; i < keys.length; i++) { 405 if (i > 0) { 406 requestUri += "&"; 407 } 408 String value = (String ) map.get(keys[i]); 409 requestUri += keys[i] + "=" + value; 410 } 411 412 return requestUri; 413 } 414 } 415 | Popular Tags |