KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > servlets > InvokerServlet


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.servlets;
20
21
22 import java.io.IOException JavaDoc;
23
24 import javax.servlet.Servlet JavaDoc;
25 import javax.servlet.ServletException JavaDoc;
26 import javax.servlet.UnavailableException JavaDoc;
27 import javax.servlet.http.HttpServlet JavaDoc;
28 import javax.servlet.http.HttpServletRequest JavaDoc;
29 import javax.servlet.http.HttpServletResponse JavaDoc;
30
31 import org.apache.catalina.ContainerServlet;
32 import org.apache.catalina.Context;
33 import org.apache.catalina.Globals;
34 import org.apache.catalina.Wrapper;
35 import org.apache.catalina.util.StringManager;
36
37
38 /**
39  * The default servlet-invoking servlet for most web applications,
40  * used to serve requests to servlets that have not been registered
41  * in the web application deployment descriptor.
42  *
43  * @author Craig R. McClanahan
44  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
45  */

46
47 public final class InvokerServlet
48     extends HttpServlet JavaDoc implements ContainerServlet {
49
50
51     // ----------------------------------------------------- Instance Variables
52

53
54     /**
55      * The Context container associated with our web application.
56      */

57     private Context context = null;
58
59
60     /**
61      * The debugging detail level for this servlet.
62      */

63     private int debug = 0;
64
65
66     /**
67      * The string manager for this package.
68      */

69     private static StringManager sm =
70         StringManager.getManager(Constants.Package);
71
72
73     /**
74      * The Wrapper container associated with this servlet.
75      */

76     private Wrapper wrapper = null;
77
78
79     // ----------------------------------------------- ContainerServlet Methods
80

81
82     /**
83      * Return the Wrapper with which we are associated.
84      */

85     public Wrapper getWrapper() {
86
87         return (this.wrapper);
88
89     }
90
91
92     /**
93      * Set the Wrapper with which we are associated.
94      *
95      * @param wrapper The new wrapper
96      */

97     public void setWrapper(Wrapper wrapper) {
98
99         this.wrapper = wrapper;
100         if (wrapper == null)
101             context = null;
102         else
103             context = (Context) wrapper.getParent();
104
105     }
106
107
108     // --------------------------------------------------------- Public Methods
109

110
111     /**
112      * Finalize this servlet.
113      */

114     public void destroy() {
115
116         ; // No actions necessary
117

118     }
119
120
121     /**
122      * Process a GET request for the specified resource.
123      *
124      * @param request The servlet request we are processing
125      * @param response The servlet response we are creating
126      *
127      * @exception IOException if an input/output error occurs
128      * @exception ServletException if a servlet-specified error occurs
129      */

130     public void doGet(HttpServletRequest JavaDoc request,
131                       HttpServletResponse JavaDoc response)
132         throws IOException JavaDoc, ServletException JavaDoc {
133
134         serveRequest(request, response);
135
136     }
137
138
139     /**
140      * Process a HEAD request for the specified resource.
141      *
142      * @param request The servlet request we are processing
143      * @param response The servlet response we are creating
144      *
145      * @exception IOException if an input/output error occurs
146      * @exception ServletException if a servlet-specified error occurs
147      */

148     public void doHead(HttpServletRequest JavaDoc request,
149                        HttpServletResponse JavaDoc response)
150         throws IOException JavaDoc, ServletException JavaDoc {
151
152         serveRequest(request, response);
153
154     }
155
156
157     /**
158      * Process a POST request for the specified resource.
159      *
160      * @param request The servlet request we are processing
161      * @param response The servlet response we are creating
162      *
163      * @exception IOException if an input/output error occurs
164      * @exception ServletException if a servlet-specified error occurs
165      */

166     public void doPost(HttpServletRequest JavaDoc request,
167                        HttpServletResponse JavaDoc response)
168         throws IOException JavaDoc, ServletException JavaDoc {
169
170         serveRequest(request, response);
171
172     }
173
174
175     /**
176      * Initialize this servlet.
177      */

178     public void init() throws ServletException JavaDoc {
179
180         // Ensure that our ContainerServlet properties have been set
181
if ((wrapper == null) || (context == null))
182             throw new UnavailableException JavaDoc
183                 (sm.getString("invokerServlet.noWrapper"));
184
185         // Set our properties from the initialization parameters
186
if (getServletConfig().getInitParameter("debug") != null)
187             debug = Integer.parseInt(getServletConfig().getInitParameter("debug"));
188
189         if (debug >= 1)
190             log("init: Associated with Context '" + context.getPath() + "'");
191
192     }
193
194
195
196     // -------------------------------------------------------- Private Methods
197

198
199     /**
200      * Serve the specified request, creating the corresponding response.
201      * After the first time a particular servlet class is requested, it will
202      * be served directly (like any registered servlet) because it will have
203      * been registered and mapped in our associated Context.
204      *
205      * @param request The servlet request we are processing
206      * @param response The servlet response we are creating
207      *
208      * @exception IOException if an input/output error occurs
209      * @exception ServletException if a servlet-specified error occurs
210      */

211     public void serveRequest(HttpServletRequest JavaDoc request,
212                              HttpServletResponse JavaDoc response)
213         throws IOException JavaDoc, ServletException JavaDoc {
214
215         // Disallow calling this servlet via a named dispatcher
216
if (request.getAttribute(Globals.NAMED_DISPATCHER_ATTR) != null)
217             throw new ServletException JavaDoc
218                 (sm.getString("invokerServlet.notNamed"));
219
220         // Identify the input parameters and our "included" state
221
String JavaDoc inRequestURI = null;
222         String JavaDoc inServletPath = null;
223         String JavaDoc inPathInfo = null;
224         boolean included =
225             (request.getAttribute(Globals.INCLUDE_REQUEST_URI_ATTR) != null);
226
227         if (included) {
228             inRequestURI =
229                 (String JavaDoc) request.getAttribute(Globals.INCLUDE_REQUEST_URI_ATTR);
230             inServletPath =
231                 (String JavaDoc) request.getAttribute(Globals.INCLUDE_SERVLET_PATH_ATTR);
232             inPathInfo =
233                 (String JavaDoc) request.getAttribute(Globals.INCLUDE_PATH_INFO_ATTR);
234         } else {
235             inRequestURI = request.getRequestURI();
236             inServletPath = request.getServletPath();
237             inPathInfo = request.getPathInfo();
238         }
239         if (debug >= 1) {
240             log("included='" + included + "', requestURI='" +
241                 inRequestURI + "'");
242             log(" servletPath='" + inServletPath + "', pathInfo='" +
243                 inPathInfo + "'");
244         }
245
246         // Make sure a servlet name or class name was specified
247
if (inPathInfo == null) {
248             if (debug >= 1)
249                 log("Invalid pathInfo '" + inPathInfo + "'");
250             if (included)
251                 throw new ServletException JavaDoc
252                     (sm.getString("invokerServlet.invalidPath", inRequestURI));
253             else {
254                 response.sendError(HttpServletResponse.SC_NOT_FOUND,
255                                    inRequestURI);
256                 return;
257             }
258         }
259
260         // Identify the outgoing servlet name or class, and outgoing path info
261
String JavaDoc pathInfo = inPathInfo;
262         String JavaDoc servletClass = pathInfo.substring(1);
263         int slash = servletClass.indexOf('/');
264         if (slash >= 0) {
265             pathInfo = servletClass.substring(slash);
266             servletClass = servletClass.substring(0, slash);
267         } else {
268             pathInfo = "";
269         }
270
271         if (servletClass.startsWith("org.apache.catalina")) {
272             response.sendError(HttpServletResponse.SC_NOT_FOUND,
273                                inRequestURI);
274             return;
275         }
276
277         if (debug >= 1)
278             log("Processing servlet '" + servletClass +
279                 "' with path info '" + pathInfo + "'");
280         String JavaDoc name = "org.apache.catalina.INVOKER." + servletClass;
281         String JavaDoc pattern = inServletPath + "/" + servletClass + "/*";
282         Wrapper wrapper = null;
283
284         // Synchronize to avoid race conditions when multiple requests
285
// try to initialize the same servlet at the same time
286
synchronized (this) {
287
288             // Are we referencing an existing servlet class or name?
289
wrapper = (Wrapper) context.findChild(servletClass);
290             if (wrapper == null)
291                 wrapper = (Wrapper) context.findChild(name);
292             if (wrapper != null) {
293                 String JavaDoc actualServletClass = wrapper.getServletClass();
294                 if ((actualServletClass != null)
295                     && (actualServletClass.startsWith
296                         ("org.apache.catalina"))) {
297                     response.sendError(HttpServletResponse.SC_NOT_FOUND,
298                                        inRequestURI);
299                     return;
300                 }
301                 if (debug >= 1)
302                     log("Using wrapper for servlet '" +
303                         wrapper.getName() + "' with mapping '" +
304                         pattern + "'");
305                 context.addServletMapping(pattern, wrapper.getName());
306             }
307
308             // No, create a new wrapper for the specified servlet class
309
else {
310
311                 if (debug >= 1)
312                     log("Creating wrapper for '" + servletClass +
313                         "' with mapping '" + pattern + "'");
314
315                 try {
316                     wrapper = context.createWrapper();
317                     wrapper.setName(name);
318                     wrapper.setLoadOnStartup(1);
319                     wrapper.setServletClass(servletClass);
320                     context.addChild(wrapper);
321                     context.addServletMapping(pattern, name);
322                 } catch (Exception JavaDoc e) {
323                     log(sm.getString("invokerServlet.cannotCreate",
324                                      inRequestURI), e);
325                     context.removeServletMapping(pattern);
326                     context.removeChild(wrapper);
327                     if (included)
328                         throw new ServletException JavaDoc
329                             (sm.getString("invokerServlet.cannotCreate",
330                                           inRequestURI), e);
331                     else {
332                         response.sendError(HttpServletResponse.SC_NOT_FOUND,
333                                            inRequestURI);
334                         return;
335                     }
336                 }
337             }
338
339         }
340
341         // Create a request wrapper to pass on to the invoked servlet
342
InvokerHttpRequest wrequest =
343             new InvokerHttpRequest(request);
344         wrequest.setRequestURI(inRequestURI);
345         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(inServletPath);
346         sb.append("/");
347         sb.append(servletClass);
348         wrequest.setServletPath(sb.toString());
349         if ((pathInfo == null) || (pathInfo.length() < 1)) {
350             wrequest.setPathInfo(null);
351             wrequest.setPathTranslated(null);
352         } else {
353             wrequest.setPathInfo(pathInfo);
354             wrequest.setPathTranslated
355                 (getServletContext().getRealPath(pathInfo));
356         }
357
358         // Allocate a servlet instance to perform this request
359
Servlet JavaDoc instance = null;
360         try {
361             instance = wrapper.allocate();
362         } catch (ServletException JavaDoc e) {
363             log(sm.getString("invokerServlet.allocate", inRequestURI), e);
364             context.removeServletMapping(pattern);
365             context.removeChild(wrapper);
366             Throwable JavaDoc rootCause = e.getRootCause();
367             if (rootCause == null)
368                 rootCause = e;
369             if (rootCause instanceof ClassNotFoundException JavaDoc) {
370                 response.sendError(HttpServletResponse.SC_NOT_FOUND,
371                                    inRequestURI);
372                 return;
373             } else if (rootCause instanceof IOException JavaDoc) {
374                 throw (IOException JavaDoc) rootCause;
375             } else if (rootCause instanceof RuntimeException JavaDoc) {
376                 throw (RuntimeException JavaDoc) rootCause;
377             } else if (rootCause instanceof ServletException JavaDoc) {
378                 throw (ServletException JavaDoc) rootCause;
379             } else {
380                 throw new ServletException JavaDoc
381                     (sm.getString("invokerServlet.allocate", inRequestURI),
382                      rootCause);
383             }
384         }
385
386         // After loading the wrapper, restore some of the fields when including
387
if (included) {
388             wrequest.setRequestURI(request.getRequestURI());
389             wrequest.setPathInfo(request.getPathInfo());
390             wrequest.setServletPath(request.getServletPath());
391         }
392
393         // Invoke the service() method of the allocated servlet
394
try {
395             String JavaDoc jspFile = wrapper.getJspFile();
396             if (jspFile != null)
397                 request.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
398             else
399                 request.removeAttribute(Globals.JSP_FILE_ATTR);
400             request.setAttribute(Globals.INVOKED_ATTR,
401                                  request.getServletPath());
402             instance.service(wrequest, response);
403         } catch (UnavailableException JavaDoc e) {
404             context.removeServletMapping(pattern);
405             throw e;
406         } finally {
407             request.removeAttribute(Globals.INVOKED_ATTR);
408             request.removeAttribute(Globals.JSP_FILE_ATTR);
409             // Deallocate the allocated servlet instance
410
try {
411                 wrapper.deallocate(instance);
412             } catch (ServletException JavaDoc e) {
413                 log(sm.getString("invokerServlet.deallocate", inRequestURI), e);
414                 throw e;
415             }
416         }
417
418     }
419
420
421 }
422
Popular Tags