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"))) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
inRequestURI);
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 (Exception e) {
log(sm.getString("invokerServlet.cannotCreate",
inRequestURI), e);
context.removeServletMapping(pattern);
context.removeChild(wrapper);
if (included)
throw new ServletException
(sm.getString("invokerServlet.cannotCreate",
inRequestURI), e);
else {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
inRequestURI);
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 {
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) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
inRequestURI);
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);
}
}
// 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());
instance.service(wrequest, response);
} catch (UnavailableException e) {
context.removeServletMapping(pattern);
throw e;
} finally {
request.removeAttribute(Globals.INVOKED_ATTR);
request.removeAttribute(Globals.JSP_FILE_ATTR);
// Deallocate the allocated servlet instance
try {
wrapper.deallocate(instance);
} catch (ServletException e) {
log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
throw e;
}
}