/*
* Copyright 2004, 2005, 2006 Odysseus Software GmbH
*
* 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.
*/
package de.odysseus.calyxo.control;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import de.odysseus.calyxo.control.base.ControlModuleContext;
import de.odysseus.calyxo.control.base.ControlModuleGroup;
import de.odysseus.calyxo.control.base.ControlModuleMapping;
import de.odysseus.calyxo.control.base.ControlModuleMappings;
import de.odysseus.calyxo.control.impl.DefaultModule;
/**
* Module controller servlet.
*
* Each application module runs in its own servlet. The module servlets
* share an instance of {@link de.odysseus.calyxo.control.base.ControlModuleGroup}.
* A module servlet holds a reference to its underlying module, an
* instance of {@link de.odysseus.calyxo.control.impl.DefaultModule}. Incoming
* requests are delegated to the module, which invokes the appropriate
* action.
*
* @author Christoph Beck
*/
public class ModuleServlet extends HttpServlet {
protected static final Log log = LogFactory.getLog(ModuleServlet.class);
private static final String DEFAULT_MODULE = DefaultModule.class.getName();
protected ControlModuleContext context;
protected ControlModuleGroup modules;
protected Module module;
/**
* Initialize module.
* Also create application-wide support instance if there is none.
*
* @throws ServletException
*/
public void init() throws ServletException {
String name = getServletName();
log.debug("Initializing module servlet '" + name + "'");
// get module mapping
List list = ControlModuleMappings.getInstance(getServletContext()).getMappings(name);
if (list.size() != 1) {
throw new ServletException("There must be exactly one servlet mapping for module '" + name + "'");
}
ControlModuleMapping mapping = (ControlModuleMapping)list.get(0);
log.info("Associating module '" + name + "' with '" + mapping.getPath("*") + "'");
// create module context
context = new ControlModuleContext(getServletConfig(), mapping, null);
// create module
String type = context.getInitParameter("module-class");
if (type == null) {
type = DEFAULT_MODULE;
}
try {
module = (Module)context.getClassLoader().loadClass(type).newInstance();
} catch (Exception e) {
throw new ServletException("Cannot create module of class " + type, e);
}
module.init(context);
// get global container for control modules
modules = ControlModuleGroup.getInstance(getServletContext());
// add our module
modules.add(context);
}
/**
* Destroy module.
* Remove module from support.
* Also uninstall application-wide support instance if there are no
* modules left.
*/
public void destroy() {
log.info("Destroying servlet '" + getServletName() + "'");
module.destroy();
modules.remove(context);
}
/**
* Process GET request.
* Delegate to {@link #process(HttpServletRequest, HttpServletResponse)} method.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}
/**
* Process POST request.
* Delegate to {@link #process(HttpServletRequest, HttpServletResponse)} method.
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}
/**
* Process request.
* Select module, compute action path, execute action.
* @param request the request we are processing
* @param response the response we are creating
* @exception ServletException pass through
* @throws IOException pass through
*/
protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// select our module
modules.setControlModuleContext(request, context);
// get the module-relative action path
String action = context.getAction(request);
if (action == null) {
throw new ServletException("Could not get action for '" + request.getRequestURI() + "'");
}
// delegate to our module
module.process(request, response, action);
}
}