Package org.apache.lenya.cms.scheduler

Source Code of org.apache.lenya.cms.scheduler.LoadQuartzServlet

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

/* $Id: LoadQuartzServlet.java,v 1.38 2004/03/01 16:18:26 gregor Exp $  */

package org.apache.lenya.cms.scheduler;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.lenya.cms.publication.DocumentBuildException;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.PublicationException;
import org.apache.lenya.cms.publication.PublicationFactory;
import org.apache.lenya.cms.publishing.PublishingEnvironment;
import org.apache.lenya.cms.scheduler.xml.TriggerHelper;
import org.apache.lenya.util.NamespaceMap;
import org.apache.lenya.xml.DocumentHelper;
import org.apache.log4j.Category;
import org.quartz.SchedulerException;
import org.w3c.dom.Document;

/**
* A simple servlet that starts an instance of a Quartz scheduler.
*/
public class LoadQuartzServlet extends HttpServlet {
    private static Category log = Category.getInstance(LoadQuartzServlet.class);
    private static SchedulerWrapper scheduler = null;
    private ServletContext servletContext;
    private String schedulerConfigurations;

    public static final String PREFIX = "scheduler";
    public static final String PARAMETER_ACTION = "action";
    public static final String PARAMETER_PUBLICATION_ID = "publication-id";
    public static final String PARAMETER_DOCUMENT_URL = "document-url";
    public static final String CONFIGURATION_ELEMENT = "scheduler-configurations";

    /**
     * Returns the scheduler wrapper.
     * @return A scheduler wrapper.
     */
    public static SchedulerWrapper getScheduler() {
        return scheduler;
    }

    /**
     * Maps servlet context names to servlets.
     */
    private static Map servlets = new HashMap();

    /**
     * Initializes the servlet.
     * @param config The servlet configuration.
     * @throws ServletException when something went wrong.
     */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);

        this.schedulerConfigurations = config.getInitParameter(CONFIGURATION_ELEMENT);
        this.servletContext = config.getServletContext();
       
        log.debug(
            ".init(): Servlet Context Path: " + getServletContextDirectory().getAbsolutePath());
           
        try {
            log.debug("Storing servlet");
            String contextPath = getServletContextDirectory().getCanonicalPath();
            log.debug("  Context path: [" + contextPath + "]");
            servlets.put(contextPath, this);
        } catch (IOException e) {
            throw new ServletException(e);
        }
           
        log.debug(".init(): Scheduler Configurations: " + this.schedulerConfigurations);

        try {
            log.info("Working?...");
            process();
            log.info("OK");
        } catch (Exception e) {
            log.error("Init of LoadQuartzServlet failed", e);
            throw new ServletException(e);
        }
    }

    /**
     * Process.
     *
     * @throws ServletException when an error occurs.
     * @throws SchedulerException when an error occurs.
     */
    public void process() throws ServletException, SchedulerException {
        scheduler =
            new SchedulerWrapper(
                getServletContextDirectory().getAbsolutePath(),
                schedulerConfigurations);

        try {
            ShutdownHook();
        } catch (Exception e) {
            log.error(e.toString(), e);
        }

        restoreJobs();
    }

    /**
     * Shuts down the scheduler.
     */
    public void destroy() {
        destroyScheduler();
    }

    /**
     * Shuts down the scheduler.
     */
    public static void destroyScheduler() {
        log.debug("destroy: ");
        getScheduler().shutdown();
    }

    /**
     * This method sets a ShutdownHook to the system This traps the CTRL+C or kill signal and
     * shutdows  Correctly the system.
     *
     * @throws Exception when something went wrong.
     */
    public static void ShutdownHook() throws Exception {
        log.debug("-------------------- ShutdownHook --------------------");
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                LoadQuartzServlet.destroyScheduler();
            }
        });
        log.debug("-------------------- End ShutdownHook --------------------");
    }

    /**
     * Handles a GET request.
     * @param request The request.
     * @param response The response.
     * @throws IOException when an error occured.
     * @throws ServletException when an error occured.
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
        handleRequest(request, response);
    }

    /**
     * Handles a POST request.
     *
     * @param req The requust.
     * @param resp The response.
     *
     * @throws ServletException when an error occured.
     * @throws IOException when an error occured.
     */
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        doGet(req, resp);
    }

    protected static final String ADD = "add";
    protected static final String MODIFY = "modify";
    protected static final String DELETE = "delete";
    protected static final String DOCUMENT_DELETED = "document-deleted";

    /**
     * Handles a servlet request.
     * @param request The request.
     * @param response The response.
     * @throws IOException when something went wrong.
     */
    protected void handleRequest(HttpServletRequest request, HttpServletResponse response)
        throws IOException {
        log.debug("----------------------------------------------------------------");
        log.debug("- Incoming request at URI: ");
        log.debug(
            request.getServerName() + ":" + request.getServerPort() + request.getRequestURI());
        log.debug("----------------------------------------------------------------");
        log.debug("Request parameters:");

        NamespaceMap schedulerParameters = getSchedulerParameters(request);

        try {
            String publicationId = (String) schedulerParameters.get(PARAMETER_PUBLICATION_ID);
            log.debug("Scheduler invoked.");

            log.debug("Scheduler Parameters:");
            log.debug("    scheduler.publication-id: [" + publicationId + "]");

            logSessionAttributes(request);

            // check if the request wants to submit, modify or delete a job.
            String action = (String) schedulerParameters.get(PARAMETER_ACTION);
            log.debug("    scheduler.action:         [" + action + "]");
            if (action == null) {
            } else if (action.equals(ADD)) {
                Date startTime = TriggerHelper.getDate(schedulerParameters);
                getScheduler().addJob(publicationId, startTime, request);
            } else if (action.equals(MODIFY)) {
                Date startTime = TriggerHelper.getDate(schedulerParameters);
                String jobId = getJobId(schedulerParameters);
                getScheduler().modifyJob(jobId, publicationId, startTime);
            } else if (action.equals(DELETE)) {
                String jobId = getJobId(schedulerParameters);
                getScheduler().deleteJob(jobId, publicationId);
            } else if (action.equals(DOCUMENT_DELETED)) {

                Publication publication =
                    PublicationFactory.getPublication(
                        publicationId,
                        getServletContextDirectory().getAbsolutePath());

                String documentUrl = (String) schedulerParameters.get(PARAMETER_DOCUMENT_URL);
                org.apache.lenya.cms.publication.Document document =
                    publication.getDocumentBuilder().buildDocument(publication, documentUrl);
                deleteDocumentJobs(document);
            }

            // handle the remainder of the request by simply returning all
            // scheduled jobs (for the given publication ID).
            PrintWriter writer = response.getWriter();
            response.setContentType("text/xml");

            Document snapshot = getScheduler().getSnapshot();

            DocumentHelper.writeDocument(snapshot, writer);
        } catch (Exception e) {
            log.error("Can't create job snapshot: ", e);
            throw new IOException(e.getMessage() + " (view log for details)");
        }
    }

    /**
     * Extracts the scheduler parameters from a request.
     * @param request The request.
     * @return A namespace map.
     */
    public static NamespaceMap getSchedulerParameters(HttpServletRequest request) {
        Map parameterMap = new HashMap();
        List keys = new ArrayList();
        for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
            String key = (String) e.nextElement();
            keys.add(key);
        }
        Collections.sort(keys);
        for (Iterator i = keys.iterator(); i.hasNext();) {
            String key = (String) i.next();
            String[] values = request.getParameterValues(key);
            log.debug("    [" + key + "] = [" + values[0] + "]");
            if (values.length == 1) {
                parameterMap.put(key, values[0]);
            } else {
                parameterMap.put(key, values);
            }
        }
       
        NamespaceMap schedulerParameters = new NamespaceMap(parameterMap, PREFIX);
        return schedulerParameters;
    }

    /**
     * Deletes
     * @param document
     * @throws DocumentBuildException
     * @throws SchedulerException
     * @throws PublicationException
     */
    public void deleteDocumentJobs(org.apache.lenya.cms.publication.Document document)
        throws DocumentBuildException, SchedulerException, PublicationException {
        log.debug("Requested to delete jobs for document URL [" + document.getCompleteURL() + "]");
        getScheduler().deleteJobs(document);
    }

    /**
     * Extracts the job ID from the scheduler parameters.
     * @param schedulerParameters A namespace map.
     * @return A string.
     */
    protected String getJobId(NamespaceMap schedulerParameters) {
        String parameterName =
            NamespaceMap.getFullName(SchedulerWrapper.JOB_PREFIX, SchedulerWrapper.JOB_ID);
        String jobId = (String) schedulerParameters.get(parameterName);
        log.debug("    scheduler.job.id:         [" + jobId + "]");
        return jobId;
    }

    /**
     * Logs the session attributes of a request.
     * @param request The request.
     */
    protected void logSessionAttributes(HttpServletRequest request) {
        log.debug("-------------------- Session Attributes --------------------");
        for (Enumeration e = request.getSession().getAttributeNames(); e.hasMoreElements();) {
            String name = (String) e.nextElement();
            log.debug(name + " = " + request.getSession().getAttribute(name));
        }
        log.debug("-------------------- End Session Attributes --------------------");
    }

    /**
     * Returns the servlet context path.
     *
     * @return A string.
     */
    public File getServletContextDirectory() {
        return new File(this.servletContext.getRealPath("/"));
    }

    /**
     * Restores the jobs.
     * @throws SchedulerException when something went wrong.
     */
    public void restoreJobs() throws SchedulerException {

        File publicationsDirectory =
            new File(getServletContextDirectory(), PublishingEnvironment.PUBLICATION_PREFIX);

        File[] publicationDirectories = publicationsDirectory.listFiles(new FileFilter() {
            public boolean accept(File file) {
                return file.isDirectory();
            }
        });

        log.debug("=========================================");
        log.debug("  Restoring jobs.");
        log.debug("    servlet context: [" + getServletContextDirectory() + "]");
        log.debug("    publications directory: [" + publicationsDirectory + "]");
        log.debug("=========================================");

        for (int i = 0; i < publicationDirectories.length; i++) {
            File directory = publicationDirectories[i];
            String publicationId = directory.getName();
            if (PublicationFactory
                .existsPublication(publicationId, getServletContextDirectory().getAbsolutePath())) {
                getScheduler().restoreJobs(publicationId);
            }
        }
    }

    public static final String SERVLET_URL = "/servlet/QuartzSchedulerServlet";

    /**
     * Returns the servlet for a certain canonical servlet context path.
     * @param contextPath The canonical servlet context path.
     * @return A LoadQuartzServlet.
     */
    public static LoadQuartzServlet getServlet(String contextPath) {
        return (LoadQuartzServlet) servlets.get(contextPath);
    }

    /**
     * Generates the request URI needed to delete the jobs for a certain document.
     * @param document The document.
     * @return A string.
     */
    public static String getDeleteDocumentRequestURI(
        String port,
        String servletContextPath,
        org.apache.lenya.cms.publication.Document document) {

        NamespaceMap requestParameters = new NamespaceMap(PREFIX);
        requestParameters.put(PARAMETER_ACTION, DOCUMENT_DELETED);
        requestParameters.put(PARAMETER_PUBLICATION_ID, document.getPublication().getId());
        requestParameters.put(PARAMETER_DOCUMENT_URL, document.getCompleteURL());

        String requestUri = "http://127.0.0.1:" + port + servletContextPath + "?";
        Map map = requestParameters.getMap();

        String[] keys = (String[]) map.keySet().toArray(new String[map.keySet().size()]);
        for (int i = 0; i < keys.length; i++) {
            if (i > 0) {
                requestUri += "&";
            }
            String value = (String) map.get(keys[i]);
            requestUri += keys[i] + "=" + value;
        }

        return requestUri;
    }
}
TOP

Related Classes of org.apache.lenya.cms.scheduler.LoadQuartzServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.