FileDocCategorySizeDatePackage
InvokerServlet.javaAPI DocGlassfish v2 API20376Fri May 04 22:32:18 BST 2007org.apache.catalina.servlets

InvokerServlet

public final class InvokerServlet extends HttpServlet implements org.apache.catalina.ContainerServlet
The default servlet-invoking servlet for most web applications, used to serve requests to servlets that have not been registered in the web application deployment descriptor.
author
Craig R. McClanahan
version
$Revision: 1.4 $ $Date: 2007/05/05 05:32:18 $

Fields Summary
private org.apache.catalina.Context
context
The Context container associated with our web application.
private int
debug
The debugging detail level for this servlet.
private static org.apache.catalina.util.StringManager
sm
The string manager for this package.
private org.apache.catalina.Wrapper
wrapper
The Wrapper container associated with this servlet.
Constructors Summary
Methods Summary
public voiddestroy()
Finalize this servlet.


        ;       // No actions necessary

    
public voiddoGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Process a GET request for the specified resource.

param
request The servlet request we are processing
param
response The servlet response we are creating
exception
IOException if an input/output error occurs
exception
ServletException if a servlet-specified error occurs


        serveRequest(request, response);

    
public voiddoHead(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Process a HEAD request for the specified resource.

param
request The servlet request we are processing
param
response The servlet response we are creating
exception
IOException if an input/output error occurs
exception
ServletException if a servlet-specified error occurs


        serveRequest(request, response);

    
public voiddoPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Process a POST request for the specified resource.

param
request The servlet request we are processing
param
response The servlet response we are creating
exception
IOException if an input/output error occurs
exception
ServletException if a servlet-specified error occurs


        serveRequest(request, response);

    
public org.apache.catalina.WrappergetWrapper()
Return the Wrapper with which we are associated.



    // ----------------------------------------------- ContainerServlet Methods


                 
       

        return (this.wrapper);

    
public voidinit()
Initialize this servlet.


        // Ensure that our ContainerServlet properties have been set
        if ((wrapper == null) || (context == null))
            throw new UnavailableException
                (sm.getString("invokerServlet.noWrapper"));

        // Set our properties from the initialization parameters
        String value = null;
        try {
            value = getServletConfig().getInitParameter("debug");
            debug = Integer.parseInt(value);
        } catch (Throwable t) {
            ;
        }
        if (debug >= 1)
            log("init: Associated with Context '" + context.getPath() + "'");

    
public voidserveRequest(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
Serve the specified request, creating the corresponding response. After the first time a particular servlet class is requested, it will be served directly (like any registered servlet) because it will have been registered and mapped in our associated Context.

param
request The servlet request we are processing
param
response The servlet response we are creating
exception
IOException if an input/output error occurs
exception
ServletException if a servlet-specified error occurs


        // Disallow calling this servlet via a named dispatcher
        if (request.getAttribute(Globals.NAMED_DISPATCHER_ATTR) != null)
            throw new ServletException
                (sm.getString("invokerServlet.notNamed"));

        // Identify the input parameters and our "included" state
        String inRequestURI = null;
        String inServletPath = null;
        String inPathInfo = null;
        boolean included =
            (request.getAttribute(Globals.INCLUDE_REQUEST_URI_ATTR) != null);

        if (included) {
            inRequestURI =
                (String) request.getAttribute(Globals.INCLUDE_REQUEST_URI_ATTR);
            inServletPath =
                (String) request.getAttribute(Globals.INCLUDE_SERVLET_PATH_ATTR);
            inPathInfo =
                (String) request.getAttribute(Globals.INCLUDE_PATH_INFO_ATTR);
        } else {
            inRequestURI = request.getRequestURI();
            inServletPath = request.getServletPath();
            inPathInfo = request.getPathInfo();
        }
        if (debug >= 1) {
            log("included='" + included + "', requestURI='" +
                inRequestURI + "'");
            log("  servletPath='" + inServletPath + "', pathInfo='" +
                inPathInfo + "'");
        }

        // Make sure a servlet name or class name was specified
        if (inPathInfo == null) {
            if (debug >= 1)
                log("Invalid pathInfo '" + inPathInfo + "'");
            if (included)
                throw new ServletException
                    (sm.getString("invokerServlet.invalidPath", inRequestURI));
            else {
                /* IASRI 4878272
                response.sendError(HttpServletResponse.SC_NOT_FOUND,
                                   inRequestURI);
                */
                // BEGIN IASRI 4878272
                log(sm.getString("invokerServlet.invalidPath", inRequestURI));
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                // END IASRI 4878272
                return;
            }
        }

        // Identify the outgoing servlet name or class, and outgoing path info
        String pathInfo = inPathInfo;
        String servletClass = pathInfo.substring(1);
        int slash = servletClass.indexOf('/");
        //        if (debug >= 2)
        //            log("  Calculating with servletClass='" + servletClass +
        //                "', pathInfo='" + pathInfo + "', slash=" + slash);
        if (slash >= 0) {
            pathInfo = servletClass.substring(slash);
            servletClass = servletClass.substring(0, slash);
        } else {
            pathInfo = "";
        }

        if (servletClass.startsWith("org.apache.catalina")) {
            /* IASRI 4878272
            response.sendError(HttpServletResponse.SC_NOT_FOUND,
                               inRequestURI);
            */
            // BEGIN IASRI 4878272
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            // END IASRI 4878272
            return;
        }

        if (debug >= 1)
            log("Processing servlet '" + servletClass +
                "' with path info '" + pathInfo + "'");
        String name = "org.apache.catalina.INVOKER." + servletClass;
        String pattern = inServletPath + "/" + servletClass + "/*";
        Wrapper wrapper = null;

        // Synchronize to avoid race conditions when multiple requests
        // try to initialize the same servlet at the same time
        synchronized (this) {

            // Are we referencing an existing servlet class or name?
            wrapper = (Wrapper) context.findChild(servletClass);
            if (wrapper == null)
                wrapper = (Wrapper) context.findChild(name);
            if (wrapper != null) {
                String actualServletClass = wrapper.getServletClass();
                if ((actualServletClass != null)
                    && (actualServletClass.startsWith
                        ("org.apache.catalina"))) {
                    /* IASRI 4878272
                    response.sendError(HttpServletResponse.SC_NOT_FOUND,
                                       inRequestURI);
                    */
                    // BEGIN IASRI 4878272
                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
                    // END IASRI 4878272
                    return;
                }
                if (debug >= 1)
                    log("Using wrapper for servlet '" +
                        wrapper.getName() + "' with mapping '" +
                        pattern + "'");
                context.addServletMapping(pattern, wrapper.getName());
            }

            // No, create a new wrapper for the specified servlet class
            else {

                if (debug >= 1)
                    log("Creating wrapper for '" + servletClass +
                        "' with mapping '" + pattern + "'");

                try {
                    wrapper = context.createWrapper();
                    wrapper.setName(name);
                    wrapper.setLoadOnStartup(1);
                    wrapper.setServletClass(servletClass);
                    context.addChild(wrapper);
                    context.addServletMapping(pattern, name);
                } catch (Throwable t) {
                    log(sm.getString("invokerServlet.cannotCreate",
                                     inRequestURI), t);
                    context.removeServletMapping(pattern);
                    context.removeChild(wrapper);
                    if (included)
                        throw new ServletException
                            (sm.getString("invokerServlet.cannotCreate",
                                          inRequestURI), t);
                    else {
                        /* IASRI 4878272
                        response.sendError(HttpServletResponse.SC_NOT_FOUND,
                                           inRequestURI);
                        */
                        // BEGIN IASRI 4878272
                        log(sm.getString("invokerServlet.invalidPath", 
                                         inRequestURI));
                        response.sendError(HttpServletResponse.SC_NOT_FOUND);
                        // END IASRI 4878272
                        return;
                    }
                }
            }

        }

        // Create a request wrapper to pass on to the invoked servlet
        InvokerHttpRequest wrequest =
            new InvokerHttpRequest(request);
        wrequest.setRequestURI(inRequestURI);
        StringBuffer sb = new StringBuffer(inServletPath);
        sb.append("/");
        sb.append(servletClass);
        wrequest.setServletPath(sb.toString());
        if ((pathInfo == null) || (pathInfo.length() < 1)) {
            wrequest.setPathInfo(null);
            wrequest.setPathTranslated(null);
        } else {
            wrequest.setPathInfo(pathInfo);
            wrequest.setPathTranslated
                (getServletContext().getRealPath(pathInfo));
        }

        // Allocate a servlet instance to perform this request
        Servlet instance = null;
        try {
            //            if (debug >= 2)
            //                log("  Allocating servlet instance");
            instance = wrapper.allocate();
        } catch (ServletException e) {
            log(sm.getString("invokerServlet.allocate", inRequestURI), e);
            context.removeServletMapping(pattern);
            context.removeChild(wrapper);
            Throwable rootCause = e.getRootCause();
            if (rootCause == null)
                rootCause = e;
            if (rootCause instanceof ClassNotFoundException) {
                /* IASRI 4878272
                response.sendError(HttpServletResponse.SC_NOT_FOUND,
                                   inRequestURI);
                */
                // BEGIN IASRI 4878272
                log(sm.getString("invokerServlet.invalidPath", inRequestURI));
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
                // END IASRI 4878272
                return;
            } else if (rootCause instanceof IOException) {
                throw (IOException) rootCause;
            } else if (rootCause instanceof RuntimeException) {
                throw (RuntimeException) rootCause;
            } else if (rootCause instanceof ServletException) {
                throw (ServletException) rootCause;
            } else {
                throw new ServletException
                    (sm.getString("invokerServlet.allocate", inRequestURI),
                     rootCause);
            }
        } catch (Throwable e) {
            log(sm.getString("invokerServlet.allocate", inRequestURI), e);
            context.removeServletMapping(pattern);
            context.removeChild(wrapper);
            throw new ServletException
                (sm.getString("invokerServlet.allocate", inRequestURI), e);
        }

        // After loading the wrapper, restore some of the fields when including
        if (included) {
            wrequest.setRequestURI(request.getRequestURI());
            wrequest.setPathInfo(request.getPathInfo());
            wrequest.setServletPath(request.getServletPath());
        }

        // Invoke the service() method of the allocated servlet
        try {
            String jspFile = wrapper.getJspFile();
            if (jspFile != null)
                request.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
            else
                request.removeAttribute(Globals.JSP_FILE_ATTR);
            request.setAttribute(Globals.INVOKED_ATTR,
                                 request.getServletPath());
            //            if (debug >= 2)
            //                log("  Calling service() method, jspFile=" +
            //                    jspFile);
            instance.service(wrequest, response);
            request.removeAttribute(Globals.INVOKED_ATTR);
            request.removeAttribute(Globals.JSP_FILE_ATTR);
        } catch (IOException e) {
            //            if (debug >= 2)
            //                log("  service() method IOException", e);
            request.removeAttribute(Globals.INVOKED_ATTR);
            request.removeAttribute(Globals.JSP_FILE_ATTR);
            try {
                wrapper.deallocate(instance);
            } catch (Throwable f) {
                ;
            }
            throw e;
        } catch (UnavailableException e) {
            //            if (debug >= 2)
            //                log("  service() method UnavailableException", e);
            context.removeServletMapping(pattern);
            request.removeAttribute(Globals.INVOKED_ATTR);
            request.removeAttribute(Globals.JSP_FILE_ATTR);
            try {
                wrapper.deallocate(instance);
            } catch (Throwable f) {
                ;
            }
            throw e;
        } catch (ServletException e) {
            //            if (debug >= 2)
            //                log("  service() method ServletException", e);
            request.removeAttribute(Globals.INVOKED_ATTR);
            request.removeAttribute(Globals.JSP_FILE_ATTR);
            try {
                wrapper.deallocate(instance);
            } catch (Throwable f) {
                ;
            }
            throw e;
        } catch (RuntimeException e) {
            //            if (debug >= 2)
            //                log("  service() method RuntimeException", e);
            request.removeAttribute(Globals.INVOKED_ATTR);
            request.removeAttribute(Globals.JSP_FILE_ATTR);
            try {
                wrapper.deallocate(instance);
            } catch (Throwable f) {
                ;
            }
            throw e;
        } catch (Throwable e) {
            //            if (debug >= 2)
            //                log("  service() method Throwable", e);
            request.removeAttribute(Globals.INVOKED_ATTR);
            request.removeAttribute(Globals.JSP_FILE_ATTR);
            try {
                wrapper.deallocate(instance);
            } catch (Throwable f) {
                ;
            }
            throw new ServletException("Invoker service() exception", e);
        }

        // Deallocate the allocated servlet instance
        try {
            //            if (debug >= 2)
            //                log("  deallocate servlet instance");
            wrapper.deallocate(instance);
        } catch (ServletException e) {
            log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
            throw e;
        } catch (Throwable e) {
            log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
            throw new ServletException
                (sm.getString("invokerServlet.deallocate", inRequestURI), e);
        }

    
public voidsetWrapper(org.apache.catalina.Wrapper wrapper)
Set the Wrapper with which we are associated.

param
wrapper The new wrapper


        this.wrapper = wrapper;
        if (wrapper == null)
            context = null;
        else
            context = (Context) wrapper.getParent();