KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lenya > cms > scheduler > LoadQuartzServlet


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17
18 /* $Id: LoadQuartzServlet.java 42598 2004-03-01 16:18:28Z gregor $ */
19
20 package org.apache.lenya.cms.scheduler;
21
22 import java.io.File JavaDoc;
23 import java.io.FileFilter JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.PrintWriter JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.Map JavaDoc;
34
35 import javax.servlet.ServletConfig JavaDoc;
36 import javax.servlet.ServletContext JavaDoc;
37 import javax.servlet.ServletException JavaDoc;
38 import javax.servlet.http.HttpServlet JavaDoc;
39 import javax.servlet.http.HttpServletRequest JavaDoc;
40 import javax.servlet.http.HttpServletResponse JavaDoc;
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 JavaDoc;
53
54 /**
55  * A simple servlet that starts an instance of a Quartz scheduler.
56  */

57 public class LoadQuartzServlet extends HttpServlet JavaDoc {
58     private static Category log = Category.getInstance(LoadQuartzServlet.class);
59     private static SchedulerWrapper scheduler = null;
60     private ServletContext JavaDoc servletContext;
61     private String JavaDoc schedulerConfigurations;
62
63     public static final String JavaDoc PREFIX = "scheduler";
64     public static final String JavaDoc PARAMETER_ACTION = "action";
65     public static final String JavaDoc PARAMETER_PUBLICATION_ID = "publication-id";
66     public static final String JavaDoc PARAMETER_DOCUMENT_URL = "document-url";
67     public static final String JavaDoc CONFIGURATION_ELEMENT = "scheduler-configurations";
68
69     /**
70      * Returns the scheduler wrapper.
71      * @return A scheduler wrapper.
72      */

73     public static SchedulerWrapper getScheduler() {
74         return scheduler;
75     }
76
77     /**
78      * Maps servlet context names to servlets.
79      */

80     private static Map JavaDoc servlets = new HashMap JavaDoc();
81
82     /**
83      * Initializes the servlet.
84      * @param config The servlet configuration.
85      * @throws ServletException when something went wrong.
86      */

87     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
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 JavaDoc contextPath = getServletContextDirectory().getCanonicalPath();
99             log.debug(" Context path: [" + contextPath + "]");
100             servlets.put(contextPath, this);
101         } catch (IOException JavaDoc e) {
102             throw new ServletException JavaDoc(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 JavaDoc e) {
112             log.error("Init of LoadQuartzServlet failed", e);
113             throw new ServletException JavaDoc(e);
114         }
115     }
116
117     /**
118      * Process.
119      *
120      * @throws ServletException when an error occurs.
121      * @throws SchedulerException when an error occurs.
122      */

123     public void process() throws ServletException JavaDoc, SchedulerException {
124         scheduler =
125             new SchedulerWrapper(
126                 getServletContextDirectory().getAbsolutePath(),
127                 schedulerConfigurations);
128
129         try {
130             ShutdownHook();
131         } catch (Exception JavaDoc e) {
132             log.error(e.toString(), e);
133         }
134
135         restoreJobs();
136     }
137
138     /**
139      * Shuts down the scheduler.
140      */

141     public void destroy() {
142         destroyScheduler();
143     }
144
145     /**
146      * Shuts down the scheduler.
147      */

148     public static void destroyScheduler() {
149         log.debug("destroy: ");
150         getScheduler().shutdown();
151     }
152
153     /**
154      * This method sets a ShutdownHook to the system This traps the CTRL+C or kill signal and
155      * shutdows Correctly the system.
156      *
157      * @throws Exception when something went wrong.
158      */

159     public static void ShutdownHook() throws Exception JavaDoc {
160         log.debug("-------------------- ShutdownHook --------------------");
161         Runtime.getRuntime().addShutdownHook(new Thread JavaDoc() {
162             public void run() {
163                 LoadQuartzServlet.destroyScheduler();
164             }
165         });
166         log.debug("-------------------- End ShutdownHook --------------------");
167     }
168
169     /**
170      * Handles a GET request.
171      * @param request The request.
172      * @param response The response.
173      * @throws IOException when an error occured.
174      * @throws ServletException when an error occured.
175      */

176     public void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
177         throws IOException JavaDoc, ServletException JavaDoc {
178         handleRequest(request, response);
179     }
180
181     /**
182      * Handles a POST request.
183      *
184      * @param req The requust.
185      * @param resp The response.
186      *
187      * @throws ServletException when an error occured.
188      * @throws IOException when an error occured.
189      */

190     public void doPost(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc resp)
191         throws ServletException JavaDoc, IOException JavaDoc {
192         doGet(req, resp);
193     }
194
195     protected static final String JavaDoc ADD = "add";
196     protected static final String JavaDoc MODIFY = "modify";
197     protected static final String JavaDoc DELETE = "delete";
198     protected static final String JavaDoc DOCUMENT_DELETED = "document-deleted";
199
200     /**
201      * Handles a servlet request.
202      * @param request The request.
203      * @param response The response.
204      * @throws IOException when something went wrong.
205      */

206     protected void handleRequest(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
207         throws IOException JavaDoc {
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 JavaDoc publicationId = (String JavaDoc) 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             // check if the request wants to submit, modify or delete a job.
227
String JavaDoc action = (String JavaDoc) schedulerParameters.get(PARAMETER_ACTION);
228             log.debug(" scheduler.action: [" + action + "]");
229             if (action == null) {
230             } else if (action.equals(ADD)) {
231                 Date JavaDoc startTime = TriggerHelper.getDate(schedulerParameters);
232                 getScheduler().addJob(publicationId, startTime, request);
233             } else if (action.equals(MODIFY)) {
234                 Date JavaDoc startTime = TriggerHelper.getDate(schedulerParameters);
235                 String JavaDoc jobId = getJobId(schedulerParameters);
236                 getScheduler().modifyJob(jobId, publicationId, startTime);
237             } else if (action.equals(DELETE)) {
238                 String JavaDoc 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 JavaDoc documentUrl = (String JavaDoc) 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             // handle the remainder of the request by simply returning all
254
// scheduled jobs (for the given publication ID).
255
PrintWriter JavaDoc writer = response.getWriter();
256             response.setContentType("text/xml");
257
258             Document JavaDoc snapshot = getScheduler().getSnapshot();
259
260             DocumentHelper.writeDocument(snapshot, writer);
261         } catch (Exception JavaDoc e) {
262             log.error("Can't create job snapshot: ", e);
263             throw new IOException JavaDoc(e.getMessage() + " (view log for details)");
264         }
265     }
266
267     /**
268      * Extracts the scheduler parameters from a request.
269      * @param request The request.
270      * @return A namespace map.
271      */

272     public static NamespaceMap getSchedulerParameters(HttpServletRequest JavaDoc request) {
273         Map JavaDoc parameterMap = new HashMap JavaDoc();
274         List JavaDoc keys = new ArrayList JavaDoc();
275         for (Enumeration JavaDoc e = request.getParameterNames(); e.hasMoreElements();) {
276             String JavaDoc key = (String JavaDoc) e.nextElement();
277             keys.add(key);
278         }
279         Collections.sort(keys);
280         for (Iterator JavaDoc i = keys.iterator(); i.hasNext();) {
281             String JavaDoc key = (String JavaDoc) i.next();
282             String JavaDoc[] 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     /**
296      * Deletes
297      * @param document
298      * @throws DocumentBuildException
299      * @throws SchedulerException
300      * @throws PublicationException
301      */

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     /**
309      * Extracts the job ID from the scheduler parameters.
310      * @param schedulerParameters A namespace map.
311      * @return A string.
312      */

313     protected String JavaDoc getJobId(NamespaceMap schedulerParameters) {
314         String JavaDoc parameterName =
315             NamespaceMap.getFullName(SchedulerWrapper.JOB_PREFIX, SchedulerWrapper.JOB_ID);
316         String JavaDoc jobId = (String JavaDoc) schedulerParameters.get(parameterName);
317         log.debug(" scheduler.job.id: [" + jobId + "]");
318         return jobId;
319     }
320
321     /**
322      * Logs the session attributes of a request.
323      * @param request The request.
324      */

325     protected void logSessionAttributes(HttpServletRequest JavaDoc request) {
326         log.debug("-------------------- Session Attributes --------------------");
327         for (Enumeration JavaDoc e = request.getSession().getAttributeNames(); e.hasMoreElements();) {
328             String JavaDoc name = (String JavaDoc) e.nextElement();
329             log.debug(name + " = " + request.getSession().getAttribute(name));
330         }
331         log.debug("-------------------- End Session Attributes --------------------");
332     }
333
334     /**
335      * Returns the servlet context path.
336      *
337      * @return A string.
338      */

339     public File JavaDoc getServletContextDirectory() {
340         return new File JavaDoc(this.servletContext.getRealPath("/"));
341     }
342
343     /**
344      * Restores the jobs.
345      * @throws SchedulerException when something went wrong.
346      */

347     public void restoreJobs() throws SchedulerException {
348
349         File JavaDoc publicationsDirectory =
350             new File JavaDoc(getServletContextDirectory(), PublishingEnvironment.PUBLICATION_PREFIX);
351
352         File JavaDoc[] publicationDirectories = publicationsDirectory.listFiles(new FileFilter JavaDoc() {
353             public boolean accept(File JavaDoc 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 JavaDoc directory = publicationDirectories[i];
366             String JavaDoc publicationId = directory.getName();
367             if (PublicationFactory
368                 .existsPublication(publicationId, getServletContextDirectory().getAbsolutePath())) {
369                 getScheduler().restoreJobs(publicationId);
370             }
371         }
372     }
373
374     public static final String JavaDoc SERVLET_URL = "/servlet/QuartzSchedulerServlet";
375
376     /**
377      * Returns the servlet for a certain canonical servlet context path.
378      * @param contextPath The canonical servlet context path.
379      * @return A LoadQuartzServlet.
380      */

381     public static LoadQuartzServlet getServlet(String JavaDoc contextPath) {
382         return (LoadQuartzServlet) servlets.get(contextPath);
383     }
384
385     /**
386      * Generates the request URI needed to delete the jobs for a certain document.
387      * @param document The document.
388      * @return A string.
389      */

390     public static String JavaDoc getDeleteDocumentRequestURI(
391         String JavaDoc port,
392         String JavaDoc 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 JavaDoc requestUri = "http://127.0.0.1:" + port + servletContextPath + "?";
401         Map JavaDoc map = requestParameters.getMap();
402
403         String JavaDoc[] keys = (String JavaDoc[]) map.keySet().toArray(new String JavaDoc[map.keySet().size()]);
404         for (int i = 0; i < keys.length; i++) {
405             if (i > 0) {
406                 requestUri += "&";
407             }
408             String JavaDoc value = (String JavaDoc) map.get(keys[i]);
409             requestUri += keys[i] + "=" + value;
410         }
411
412         return requestUri;
413     }
414 }
415
Popular Tags