001: /*
002: * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: */
007: package winstone.invoker;
008:
009: import java.io.IOException;
010: import java.util.Hashtable;
011: import java.util.Iterator;
012: import java.util.Map;
013:
014: import javax.servlet.ServletConfig;
015: import javax.servlet.ServletException;
016: import javax.servlet.http.HttpServlet;
017: import javax.servlet.http.HttpServletRequest;
018: import javax.servlet.http.HttpServletResponse;
019:
020: import winstone.Logger;
021: import winstone.Mapping;
022: import winstone.RequestDispatcher;
023: import winstone.ServletConfiguration;
024: import winstone.WebAppConfiguration;
025: import winstone.WinstoneResourceBundle;
026:
027: /**
028: * If a URI matches a servlet class name, mount an instance of that servlet, and
029: * try to process the request using that servlet.
030: *
031: * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
032: * @version $Id: InvokerServlet.java,v 1.6 2006/03/24 17:24:24 rickknowles Exp $
033: */
034: public class InvokerServlet extends HttpServlet {
035: // private static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
036: private static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
037:
038: private static final WinstoneResourceBundle INVOKER_RESOURCES = new WinstoneResourceBundle(
039: "winstone.invoker.LocalStrings");
040: private Map mountedInstances;
041:
042: // private String prefix;
043: // private String invokerPrefix;
044:
045: /**
046: * Set up a blank map of servlet configuration instances
047: */
048: public void init(ServletConfig config) throws ServletException {
049: super .init(config);
050: this .mountedInstances = new Hashtable();
051: // this.prefix = config.getInitParameter("prefix");
052: // this.invokerPrefix = config.getInitParameter("invokerPrefix");
053: }
054:
055: /**
056: * Destroy any mounted instances we might be holding, then destroy myself
057: */
058: public void destroy() {
059: if (this .mountedInstances != null) {
060: synchronized (this .mountedInstances) {
061: for (Iterator i = this .mountedInstances.values()
062: .iterator(); i.hasNext();)
063: ((ServletConfiguration) i.next()).destroy();
064: this .mountedInstances.clear();
065: }
066: }
067: this .mountedInstances = null;
068: // this.prefix = null;
069: // this.invokerPrefix = null;
070: }
071:
072: /**
073: * Get an instance of the servlet configuration object
074: */
075: protected ServletConfiguration getInvokableInstance(
076: String servletName) throws ServletException, IOException {
077: ServletConfiguration sc = null;
078: synchronized (this .mountedInstances) {
079: if (this .mountedInstances.containsKey(servletName)) {
080: sc = (ServletConfiguration) this .mountedInstances
081: .get(servletName);
082: }
083: }
084:
085: if (sc == null) {
086: // If found, mount an instance
087: try {
088: // Class servletClass = Class.forName(servletName, true,
089: // Thread.currentThread().getContextClassLoader());
090: sc = new ServletConfiguration(
091: (WebAppConfiguration) this .getServletContext(),
092: getServletConfig().getServletName() + ":"
093: + servletName, servletName,
094: new Hashtable(), -1);
095: this .mountedInstances.put(servletName, sc);
096: Logger.log(Logger.DEBUG, INVOKER_RESOURCES,
097: "InvokerServlet.MountingServlet", new String[] {
098: servletName,
099: getServletConfig().getServletName() });
100: // just to trigger the servlet.init()
101: sc.ensureInitialization();
102: } catch (Throwable err) {
103: sc = null;
104: }
105: }
106: return sc;
107: }
108:
109: protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
110: throws ServletException, IOException {
111: boolean isInclude = (req.getAttribute(INCLUDE_PATH_INFO) != null);
112: // boolean isForward = (req.getAttribute(FORWARD_PATH_INFO) != null);
113: String servletName = null;
114:
115: if (isInclude)
116: servletName = (String) req.getAttribute(INCLUDE_PATH_INFO);
117: // else if (isForward)
118: // servletName = (String) req.getAttribute(FORWARD_PATH_INFO);
119: else if (req.getPathInfo() != null)
120: servletName = req.getPathInfo();
121: else
122: servletName = "";
123: if (servletName.startsWith("/"))
124: servletName = servletName.substring(1);
125: ServletConfiguration invokedServlet = getInvokableInstance(servletName);
126:
127: if (invokedServlet == null) {
128: Logger.log(Logger.WARNING, INVOKER_RESOURCES,
129: "InvokerServlet.NoMatchingServletFound",
130: servletName);
131: rsp.sendError(HttpServletResponse.SC_NOT_FOUND,
132: INVOKER_RESOURCES.getString(
133: "InvokerServlet.NoMatchingServletFound",
134: servletName));
135: } else {
136: RequestDispatcher rd = new RequestDispatcher(
137: (WebAppConfiguration) getServletContext(),
138: invokedServlet);
139: rd.setForNamedDispatcher(new Mapping[0], new Mapping[0]);
140: rd.forward(req, rsp);
141: }
142: }
143:
144: protected void doPost(HttpServletRequest req,
145: HttpServletResponse rsp) throws ServletException,
146: IOException {
147: doGet(req, rsp);
148: }
149: }
|