/*
* Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
* Distributed under the terms of either:
* - the common development and distribution license (CDDL), v1.0; or
* - the GNU Lesser General Public License, v2.1 or later
*/
package winstone.invoker;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import winstone.Logger;
import winstone.Mapping;
import winstone.RequestDispatcher;
import winstone.ServletConfiguration;
import winstone.WebAppConfiguration;
import winstone.WinstoneResourceBundle;
/**
* If a URI matches a servlet class name, mount an instance of that servlet, and
* try to process the request using that servlet.
*
* @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
* @version $Id: InvokerServlet.java,v 1.6 2006/03/24 17:24:24 rickknowles Exp $
*/
public class InvokerServlet extends HttpServlet {
// private static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
private static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
private static final WinstoneResourceBundle INVOKER_RESOURCES =
new WinstoneResourceBundle("winstone.invoker.LocalStrings");
private Map mountedInstances;
// private String prefix;
// private String invokerPrefix;
/**
* Set up a blank map of servlet configuration instances
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.mountedInstances = new Hashtable();
// this.prefix = config.getInitParameter("prefix");
// this.invokerPrefix = config.getInitParameter("invokerPrefix");
}
/**
* Destroy any mounted instances we might be holding, then destroy myself
*/
public void destroy() {
if (this.mountedInstances != null) {
synchronized (this.mountedInstances) {
for (Iterator i = this.mountedInstances.values().iterator(); i
.hasNext();)
((ServletConfiguration) i.next()).destroy();
this.mountedInstances.clear();
}
}
this.mountedInstances = null;
// this.prefix = null;
// this.invokerPrefix = null;
}
/**
* Get an instance of the servlet configuration object
*/
protected ServletConfiguration getInvokableInstance(String servletName)
throws ServletException, IOException {
ServletConfiguration sc = null;
synchronized (this.mountedInstances) {
if (this.mountedInstances.containsKey(servletName)) {
sc = (ServletConfiguration) this.mountedInstances.get(servletName);
}
}
if (sc == null) {
// If found, mount an instance
try {
// Class servletClass = Class.forName(servletName, true,
// Thread.currentThread().getContextClassLoader());
sc = new ServletConfiguration((WebAppConfiguration) this.getServletContext(),
getServletConfig().getServletName() + ":" + servletName, servletName,
new Hashtable(), -1);
this.mountedInstances.put(servletName, sc);
Logger.log(Logger.DEBUG, INVOKER_RESOURCES,
"InvokerServlet.MountingServlet", new String[] {
servletName,
getServletConfig().getServletName() });
// just to trigger the servlet.init()
sc.ensureInitialization();
} catch (Throwable err) {
sc = null;
}
}
return sc;
}
protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
throws ServletException, IOException {
boolean isInclude = (req.getAttribute(INCLUDE_PATH_INFO) != null);
// boolean isForward = (req.getAttribute(FORWARD_PATH_INFO) != null);
String servletName = null;
if (isInclude)
servletName = (String) req.getAttribute(INCLUDE_PATH_INFO);
// else if (isForward)
// servletName = (String) req.getAttribute(FORWARD_PATH_INFO);
else if (req.getPathInfo() != null)
servletName = req.getPathInfo();
else
servletName = "";
if (servletName.startsWith("/"))
servletName = servletName.substring(1);
ServletConfiguration invokedServlet = getInvokableInstance(servletName);
if (invokedServlet == null) {
Logger.log(Logger.WARNING, INVOKER_RESOURCES,
"InvokerServlet.NoMatchingServletFound", servletName);
rsp.sendError(HttpServletResponse.SC_NOT_FOUND, INVOKER_RESOURCES
.getString("InvokerServlet.NoMatchingServletFound",
servletName));
} else {
RequestDispatcher rd = new RequestDispatcher(
(WebAppConfiguration) getServletContext(),
invokedServlet);
rd.setForNamedDispatcher(new Mapping[0], new Mapping[0]);
rd.forward(req, rsp);
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse rsp)
throws ServletException, IOException {
doGet(req, rsp);
}
}