KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > server > webapp > RequestDispatcherImpl


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.server.webapp;
31
32 import com.caucho.server.connection.AbstractHttpResponse;
33 import com.caucho.server.connection.AbstractResponseStream;
34 import com.caucho.server.connection.CauchoRequest;
35 import com.caucho.server.connection.CauchoResponse;
36 import com.caucho.server.dispatch.Invocation;
37 import com.caucho.util.L10N;
38
39 import javax.servlet.RequestDispatcher JavaDoc;
40 import javax.servlet.ServletException JavaDoc;
41 import javax.servlet.ServletRequest JavaDoc;
42 import javax.servlet.ServletResponse JavaDoc;
43 import javax.servlet.http.HttpServletRequest JavaDoc;
44 import javax.servlet.http.HttpServletRequestWrapper JavaDoc;
45 import javax.servlet.http.HttpServletResponse JavaDoc;
46 import javax.servlet.http.HttpServletResponseWrapper JavaDoc;
47 import javax.servlet.http.HttpSession JavaDoc;
48 import java.io.IOException JavaDoc;
49 import java.io.OutputStream JavaDoc;
50 import java.io.PrintWriter JavaDoc;
51
52 public class RequestDispatcherImpl implements RequestDispatcher JavaDoc {
53   private static final L10N L = new L10N(RequestDispatcherImpl.class);
54   
55   private static final String JavaDoc REQUEST_URI =
56     "javax.servlet.include.request_uri";
57   private static final String JavaDoc CONTEXT_PATH =
58     "javax.servlet.include.context_path";
59   private static final String JavaDoc SERVLET_PATH =
60     "javax.servlet.include.servlet_path";
61   private static final String JavaDoc PATH_INFO =
62     "javax.servlet.include.path_info";
63   private static final String JavaDoc QUERY_STRING =
64     "javax.servlet.include.query_string";
65
66   private static final String JavaDoc FWD_REQUEST_URI =
67     "javax.servlet.forward.request_uri";
68   private static final String JavaDoc FWD_CONTEXT_PATH =
69     "javax.servlet.forward.context_path";
70   private static final String JavaDoc FWD_SERVLET_PATH =
71     "javax.servlet.forward.servlet_path";
72   private static final String JavaDoc FWD_PATH_INFO =
73     "javax.servlet.forward.path_info";
74   private static final String JavaDoc FWD_QUERY_STRING =
75     "javax.servlet.forward.query_string";
76
77   // WebApp the request dispatcher was called from
78
private WebApp _webApp;
79   private Invocation _includeInvocation;
80   private Invocation _forwardInvocation;
81   private Invocation _errorInvocation;
82   private boolean _isLogin;
83
84   RequestDispatcherImpl(Invocation includeInvocation,
85                         Invocation forwardInvocation,
86                         Invocation errorInvocation,
87                         WebApp webApp)
88   {
89     _includeInvocation = includeInvocation;
90     _forwardInvocation = forwardInvocation;
91     _errorInvocation = errorInvocation;
92     _webApp = webApp;
93   }
94
95   public void setLogin(boolean isLogin)
96   {
97     _isLogin = isLogin;
98   }
99
100   public boolean isModified()
101   {
102     return _includeInvocation.isModified();
103   }
104
105   public void forward(ServletRequest JavaDoc request, ServletResponse JavaDoc response)
106     throws ServletException JavaDoc, IOException JavaDoc
107   {
108     forward((HttpServletRequest JavaDoc) request, (HttpServletResponse JavaDoc) response,
109         null, _forwardInvocation);
110   }
111
112   public void error(ServletRequest JavaDoc request, ServletResponse JavaDoc response)
113     throws ServletException JavaDoc, IOException JavaDoc
114   {
115     forward((HttpServletRequest JavaDoc) request, (HttpServletResponse JavaDoc) response,
116         null, _errorInvocation);
117   }
118
119   /**
120    * Forwards the request to the servlet named by the request dispatcher.
121    *
122    * @param req the servlet request.
123    * @param res the servlet response.
124    * @param method special to tell if from error.
125    */

126   public void forward(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res,
127               String JavaDoc method, Invocation invocation)
128     throws ServletException JavaDoc, IOException JavaDoc
129   {
130     AbstractHttpResponse response = null;
131     DispatchRequest subRequest;
132     HttpSession JavaDoc session = null;
133
134     CauchoResponse cauchoRes = null;
135
136     if (res instanceof CauchoResponse)
137       cauchoRes = (CauchoResponse) res;
138
139     if (res.isCommitted() && method == null) {
140       IllegalStateException JavaDoc exn;
141       exn = new IllegalStateException JavaDoc("forward() not allowed after buffer has committed.");
142
143       if (cauchoRes == null || ! cauchoRes.hasError()) {
144     if (cauchoRes != null)
145       cauchoRes.setHasError(true);
146         throw exn;
147       }
148       
149       _webApp.log(exn.getMessage(), exn);
150     }
151
152     if (res instanceof AbstractHttpResponse)
153       response = (AbstractHttpResponse) res;
154
155     ServletResponse JavaDoc resPtr = res;
156       
157     if (method == null)
158       method = req.getMethod();
159
160     subRequest = DispatchRequest.createDispatch();
161
162     HttpServletRequest JavaDoc parentRequest = req;
163     HttpServletRequestWrapper JavaDoc reqWrapper = null;
164     HttpServletRequest JavaDoc topRequest = subRequest;
165
166     if (! (req instanceof CauchoRequest))
167       topRequest = req;
168
169     while (parentRequest instanceof HttpServletRequestWrapper JavaDoc &&
170        ! (parentRequest instanceof CauchoRequest)) {
171       reqWrapper = (HttpServletRequestWrapper JavaDoc) parentRequest;
172       parentRequest = (HttpServletRequest JavaDoc) reqWrapper.getRequest();
173     }
174
175     String JavaDoc newQueryString = invocation.getQueryString();
176     String JavaDoc reqQueryString = req.getQueryString();
177
178     String JavaDoc queryString;
179
180     /* Changed to match tomcat */
181     // server/10y3
182
if (_isLogin)
183       queryString = newQueryString;
184     else if (reqQueryString == null)
185       queryString = newQueryString;
186     else if (newQueryString == null)
187       queryString = reqQueryString;
188     else if (reqQueryString.equals(newQueryString))
189       queryString = newQueryString;
190     /*
191     else
192       queryString = newQueryString + '&' + reqQueryString;
193     */

194     else
195       queryString = newQueryString;
196
197     WebApp oldWebApp;
198
199     if (req instanceof CauchoRequest)
200       oldWebApp = ((CauchoRequest) req).getWebApp();
201     else
202       oldWebApp = (WebApp) _webApp.getContext(req.getContextPath());
203
204     subRequest.init(invocation.getWebApp(), oldWebApp,
205                     parentRequest, res, method,
206             invocation.getURI(),
207             invocation.getServletPath(),
208             invocation.getPathInfo(),
209             queryString, newQueryString);
210
211     
212     if (reqWrapper != null) {
213       reqWrapper.setRequest(subRequest);
214
215       if (topRequest == parentRequest) // server/172o
216
topRequest = reqWrapper;
217     }
218
219     Object JavaDoc oldUri = null;
220     Object JavaDoc oldContextPath = null;
221     Object JavaDoc oldServletPath = null;
222     Object JavaDoc oldPathInfo = null;
223     Object JavaDoc oldQueryString = null;
224     Object JavaDoc oldJSPFile = null;
225     Object JavaDoc oldForward = null;
226     
227     oldUri = req.getAttribute(REQUEST_URI);
228
229     if (oldUri != null) {
230       oldContextPath = req.getAttribute(CONTEXT_PATH);
231       oldServletPath = req.getAttribute(SERVLET_PATH);
232       oldPathInfo = req.getAttribute(PATH_INFO);
233       oldQueryString = req.getAttribute(QUERY_STRING);
234
235       req.removeAttribute(REQUEST_URI);
236       req.removeAttribute(CONTEXT_PATH);
237       req.removeAttribute(SERVLET_PATH);
238       req.removeAttribute(PATH_INFO);
239       req.removeAttribute(QUERY_STRING);
240       req.removeAttribute("caucho.jsp.jsp-file");
241     }
242
243     if (req.getAttribute(FWD_REQUEST_URI) == null) {
244       subRequest.setAttribute(FWD_REQUEST_URI, req.getRequestURI());
245       subRequest.setAttribute(FWD_CONTEXT_PATH, req.getContextPath());
246       subRequest.setAttribute(FWD_SERVLET_PATH, req.getServletPath());
247       subRequest.setAttribute(FWD_PATH_INFO, req.getPathInfo());
248       subRequest.setAttribute(FWD_QUERY_STRING, req.getQueryString());
249     }
250     
251     oldForward = req.getAttribute("caucho.forward");
252     req.setAttribute("caucho.forward", "true");
253
254     subRequest.setPageURI(subRequest.getRequestURI());
255     subRequest.setPageContextPath(subRequest.getContextPath());
256     subRequest.setPageServletPath(subRequest.getServletPath());
257     subRequest.setPagePathInfo(subRequest.getPathInfo());
258     subRequest.setPageQueryString(subRequest.getQueryString());
259
260     CauchoRequest oldRequest = null;
261     AbstractResponseStream oldStream = null;
262     if (response != null) {
263       oldRequest = response.getRequest();
264       oldStream = response.getResponseStream();
265     }
266
267     Thread JavaDoc thread = Thread.currentThread();
268     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
269
270     try {
271       if (response != null) {
272     response.setRequest(subRequest);
273     response.setResponseStream(response.getOriginalStream());
274       }
275       
276       res.resetBuffer();
277       res.setContentLength(-1);
278
279       invocation.service(topRequest, res);
280
281       if (cauchoRes != null)
282         cauchoRes.close();
283       else {
284         try {
285           OutputStream JavaDoc os = res.getOutputStream();
286       if (os != null)
287         os.close();
288         } catch (IllegalStateException JavaDoc e) {
289         }
290     
291     try {
292       PrintWriter JavaDoc out = res.getWriter();
293       if (out != null)
294         out.close();
295     } catch (IllegalStateException JavaDoc e1) {
296     }
297
298     // server/1732 wants this commented out
299
/*
300     // TCK wants the code (test?)
301     ServletResponse ptr = res;
302     while (ptr instanceof HttpServletResponseWrapper) {
303       ptr = ((HttpServletResponseWrapper) ptr).getResponse();
304
305       if (ptr instanceof AbstractHttpResponse) {
306         ((AbstractHttpResponse) ptr).finish();
307         break;
308       }
309     }
310     */

311       }
312     } finally {
313       subRequest.finish();
314       
315       thread.setContextClassLoader(oldLoader);
316
317       if (response != null) {
318         response.setRequest(oldRequest);
319         response.setResponseStream(oldStream);
320         //response.setWriter(oldWriter);
321
}
322
323       DispatchRequest.free(subRequest);
324       
325       if (reqWrapper != null)
326     reqWrapper.setRequest(parentRequest);
327
328       // XXX: are these necessary?
329
if (oldUri != null)
330     req.setAttribute(REQUEST_URI, oldUri);
331
332       if (oldContextPath != null)
333     req.setAttribute(CONTEXT_PATH, oldContextPath);
334
335       if (oldServletPath != null)
336     req.setAttribute(SERVLET_PATH, oldServletPath);
337
338       if (oldPathInfo != null)
339     req.setAttribute(PATH_INFO, oldPathInfo);
340
341       if (oldQueryString != null)
342     req.setAttribute(QUERY_STRING, oldQueryString);
343       
344       if (oldForward == null)
345     req.removeAttribute("caucho.forward");
346     }
347   }
348
349
350   public void include(ServletRequest JavaDoc request, ServletResponse JavaDoc response)
351     throws ServletException JavaDoc, IOException JavaDoc
352   {
353     include(request, response, null);
354   }
355
356   /**
357    * Include a request into the current page.
358    */

359   public void include(ServletRequest JavaDoc request, ServletResponse JavaDoc response,
360               String JavaDoc method)
361     throws ServletException JavaDoc, IOException JavaDoc
362   {
363     HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) request;
364     HttpServletResponse JavaDoc res = (HttpServletResponse JavaDoc) response;
365
366     IncludeDispatchRequest subRequest;
367     DispatchResponse subResponse;
368
369     Invocation invocation = _includeInvocation;
370     WebApp webApp = invocation.getWebApp();
371     String JavaDoc queryString = invocation.getQueryString();
372
373     if (method == null)
374       method = req.getMethod();
375
376     if (! "POST".equals(method))
377       method = "GET";
378
379     HttpServletRequest JavaDoc parentRequest = req;
380     HttpServletRequestWrapper JavaDoc reqWrapper = null;
381
382     HttpServletResponse JavaDoc parentResponse = res;
383     HttpServletResponseWrapper JavaDoc resWrapper = null;
384
385     if (! _webApp.getDispatchWrapsFilters()) {
386       if (req instanceof HttpServletRequestWrapper JavaDoc &&
387       ! (req instanceof CauchoRequest)) {
388     reqWrapper = (HttpServletRequestWrapper JavaDoc) req;
389     parentRequest = (HttpServletRequest JavaDoc) reqWrapper.getRequest();
390       }
391
392       if (res instanceof HttpServletResponseWrapper JavaDoc &&
393       ! (res instanceof CauchoResponse)) {
394     resWrapper = (HttpServletResponseWrapper JavaDoc) res;
395     parentResponse = (HttpServletResponse JavaDoc) resWrapper.getResponse();
396       }
397     }
398
399     subRequest = IncludeDispatchRequest.createDispatch();
400
401     WebApp oldWebApp;
402
403     if (req instanceof CauchoRequest)
404       oldWebApp = ((CauchoRequest) req).getWebApp();
405     else
406       oldWebApp = (WebApp) webApp.getContext(req.getContextPath());
407
408     subRequest.init(webApp, oldWebApp,
409             parentRequest, parentResponse,
410             method,
411                     req.getRequestURI(), req.getServletPath(),
412                     req.getPathInfo(), req.getQueryString(),
413                     queryString);
414
415     HttpServletRequest JavaDoc topRequest = subRequest;
416
417     if (reqWrapper != null) {
418       reqWrapper.setRequest(subRequest);
419       topRequest = reqWrapper;
420     }
421
422     subResponse = DispatchResponse.createDispatch();
423     subResponse.setNextResponse(res);
424
425     AbstractResponseStream s = null;
426     boolean oldDisableClose = false;
427
428     subResponse.init(subRequest);
429     subResponse.setNextResponse(parentResponse);
430     subResponse.start();
431     subResponse.setCharacterEncoding(res.getCharacterEncoding());
432
433     if (_webApp.getDispatchWrapsFilters())
434       subResponse.setCauchoResponseStream(true);
435
436     CauchoResponse cauchoRes = null;
437     if (res instanceof CauchoResponse) {
438       cauchoRes = (CauchoResponse) res;
439     }
440     else if (! _webApp.getDispatchWrapsFilters()) {
441       subResponse.killCache();
442     }
443
444     HttpServletResponse JavaDoc topResponse = subResponse;
445
446     if (resWrapper != null) {
447       resWrapper.setResponse(subResponse);
448       topResponse = res;
449     }
450
451     Object JavaDoc oldUri = null;
452     Object JavaDoc oldContextPath = null;
453     Object JavaDoc oldServletPath = null;
454     Object JavaDoc oldPathInfo = null;
455     Object JavaDoc oldQueryString = null;
456
457     oldUri = req.getAttribute(REQUEST_URI);
458     if (oldUri != null) {
459       oldContextPath = request.getAttribute(CONTEXT_PATH);
460       oldServletPath = req.getAttribute(SERVLET_PATH);
461       oldPathInfo = req.getAttribute(PATH_INFO);
462       oldQueryString = req.getAttribute(QUERY_STRING);
463     }
464
465     subRequest.setPageURI(invocation.getURI());
466     subRequest.setAttribute(REQUEST_URI, invocation.getURI());
467     String JavaDoc contextPath;
468     if (webApp != null)
469       contextPath = webApp.getContextPath();
470     else
471       contextPath = null;
472     
473     subRequest.setPageContextPath(contextPath);
474     subRequest.setAttribute(CONTEXT_PATH, contextPath);
475     subRequest.setPageServletPath(invocation.getServletPath());
476     subRequest.setAttribute(SERVLET_PATH, invocation.getServletPath());
477     subRequest.setPagePathInfo(invocation.getPathInfo());
478     subRequest.setAttribute(PATH_INFO, invocation.getPathInfo());
479     subRequest.setPageQueryString(queryString);
480     subRequest.setAttribute(QUERY_STRING, queryString);
481
482     subRequest.removeAttribute("caucho.jsp.jsp-file");
483
484     Thread JavaDoc thread = Thread.currentThread();
485     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
486     boolean isOkay = false;
487     try {
488       invocation.service(topRequest, topResponse);
489       isOkay = true;
490     } finally {
491       thread.setContextClassLoader(oldLoader);
492       // XXX: In many cases, able to use clear()?
493

494       subRequest.finish();
495
496       /* XXX:
497       if (s != null)
498     s.setDisableClose(oldDisableClose);
499       */

500       if (oldUri != null)
501         req.setAttribute(REQUEST_URI, oldUri);
502       else
503         req.removeAttribute(REQUEST_URI);
504
505       if (oldContextPath != null)
506         req.setAttribute(CONTEXT_PATH, oldContextPath);
507       else
508         req.removeAttribute(CONTEXT_PATH);
509
510       if (oldServletPath != null)
511         req.setAttribute(SERVLET_PATH, oldServletPath);
512       else
513         req.removeAttribute(SERVLET_PATH);
514
515       if (oldPathInfo != null)
516         req.setAttribute(PATH_INFO, oldPathInfo);
517       else
518         req.removeAttribute(PATH_INFO);
519
520       if (oldQueryString != null)
521         req.setAttribute(QUERY_STRING, oldQueryString);
522       else
523         req.removeAttribute(QUERY_STRING);
524
525       if (! isOkay)
526     subResponse.killCache();
527
528       subResponse.close();
529
530       /*
531       if (! (res instanceof CauchoResponse)) {
532     if (s != null)
533       s.close();
534       }
535       */

536
537       IncludeDispatchRequest.free(subRequest);
538       DispatchResponse.free(subResponse);
539
540       if (reqWrapper != null)
541     reqWrapper.setRequest(parentRequest);
542
543       if (resWrapper != null)
544     resWrapper.setResponse(parentResponse);
545     }
546   }
547 }
548
Popular Tags