KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > jsp > QServlet


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.jsp;
31
32 import com.caucho.log.Log;
33 import com.caucho.server.connection.CauchoRequest;
34 import com.caucho.server.connection.CauchoResponse;
35 import com.caucho.server.connection.RequestAdapter;
36 import com.caucho.server.connection.ResponseAdapter;
37 import com.caucho.server.webapp.WebApp;
38 import com.caucho.util.L10N;
39 import com.caucho.vfs.ClientDisconnectException;
40 import com.caucho.vfs.JarPath;
41 import com.caucho.vfs.Path;
42 import com.caucho.vfs.Vfs;
43
44 import javax.servlet.*;
45 import javax.servlet.http.HttpServletRequest JavaDoc;
46 import javax.servlet.http.HttpServletResponse JavaDoc;
47 import java.io.FileNotFoundException JavaDoc;
48 import java.io.IOException JavaDoc;
49 import java.util.logging.Level JavaDoc;
50 import java.util.logging.Logger JavaDoc;
51
52 /**
53  * Base servlet for both JSP and XTP. It's primarily responsible for
54  * returning the proper error messages when things go wrong.
55  *
56  * <p>The manager create the compiled JSP and XTP pages. The manager
57  * returns a Page object which is actually executed.
58  *
59  * @see JspManager
60  * @see XtpManager
61  * @see Page
62  */

63 abstract public class QServlet implements Servlet {
64   static final String JavaDoc COPYRIGHT =
65     "Copyright(c) 1998-2006 Caucho Technology. All rights reserved.";
66
67   private static final Logger JavaDoc log = Log.open(QServlet.class);
68   private static final L10N L = new L10N(QServlet.class);
69
70   protected WebApp _webApp;
71   private PageManager _manager;
72
73   private ServletConfig _config;
74
75   /**
76    * Initialize the servlet. If necessary, convert the ServletContext
77    * to a CauchoWebApp. Also, read the configuration Registry
78    * it it hasn't been read yet.
79    */

80   public void init(ServletConfig config) throws ServletException
81   {
82     ServletContext cxt = config.getServletContext();
83     _webApp = (WebApp) cxt;
84
85     _config = config;
86
87     log.finer(config.getServletName() + " init");
88   }
89
90   /**
91    * JspServlet and XtpServlet will set the PageManager with this method.
92    */

93   protected void setManager(PageManager manager)
94   {
95     _manager = manager;
96   }
97
98   protected PageManager getManager()
99   {
100     return _manager;
101   }
102
103   /**
104    * Override the Servlet method to return the generated application.
105    */

106   public ServletContext getServletContext()
107   {
108     return _webApp;
109   }
110
111   /**
112    * Returns the config.
113    */

114   public ServletConfig getServletConfig()
115   {
116     return _config;
117   }
118
119   /**
120    * Returns the init parameter
121    */

122   public String JavaDoc getInitParameter(String JavaDoc name)
123   {
124     return _config.getInitParameter(name);
125   }
126
127   /**
128    * The service method gets the JSP/XTP page and executes it. The
129    * request and response objects are converted to Caucho objects so
130    * other servlet runners will produce the same results as the Caucho
131    * servlet runner.
132    */

133   public void service(ServletRequest JavaDoc req, ServletResponse JavaDoc res)
134     throws ServletException, IOException JavaDoc
135   {
136     CauchoRequest request;
137     CauchoResponse response;
138     ResponseAdapter resAdapt = null;
139
140     if (req instanceof CauchoRequest)
141       request = (CauchoRequest) req;
142     else
143       request = RequestAdapter.create((HttpServletRequest JavaDoc) req, _webApp);
144
145     if (res instanceof CauchoResponse)
146       response = (CauchoResponse) res;
147     else {
148       resAdapt = ResponseAdapter.create((HttpServletResponse JavaDoc) res);
149       response = resAdapt;
150     }
151
152     Page page = null;
153
154     try {
155       page = getPage(request, response);
156
157       if (page == null) {
158         response.sendError(HttpServletResponse.SC_NOT_FOUND);
159         return;
160       }
161
162       page.service(request, response);
163     }
164     catch (JspParseException e) {
165       if (e.getErrorPage() != null)
166         forwardErrorPage(request, response, e, e.getErrorPage());
167       else
168         throw new ServletException(e);
169     }
170     catch (ClientDisconnectException e) {
171       throw e;
172     }
173     catch (Throwable JavaDoc e) {
174       if (page != null && page.getErrorPage() != null &&
175           forwardErrorPage(request, response, e, page.getErrorPage())) {
176       }
177       else if (e instanceof IOException JavaDoc) {
178         log.log(Level.FINE, e.toString(), e);
179         throw (IOException JavaDoc) e;
180       }
181       else if (e instanceof ServletException) {
182         log.log(Level.FINE, e.toString(), e);
183         throw (ServletException) e;
184       }
185       else {
186         log.log(Level.FINE, e.toString(), e);
187         throw new ServletException(e);
188       }
189     }
190
191     if (resAdapt != null) {
192       resAdapt.close();
193       ResponseAdapter.free(resAdapt);
194     }
195   }
196
197   /**
198    * Creates and returns a new page.
199    *
200    * @param request the servlet request
201    * @param response the servlet response
202    *
203    * @return the compiled page
204    */

205   public Page getPage(HttpServletRequest JavaDoc request,
206                       HttpServletResponse JavaDoc response)
207     throws Exception JavaDoc
208   {
209     try {
210       Page page = getSubPage(request, response);
211
212       return page;
213     }
214     catch (JspParseException e) {
215       if (e.getErrorPage() != null) {
216         if (e.getCause() != null && ! (e instanceof JspLineParseException))
217           forwardErrorPage(request, response, e.getCause(), e.getErrorPage());
218         else
219           forwardErrorPage(request, response, e, e.getErrorPage());
220
221         return null;
222       }
223       else
224         throw e;
225     }
226   }
227
228   /**
229    * Given a request and response, returns the compiled Page. For example,
230    * JspManager will return the JspPage and XtpManager will
231    * return the XtpPage.
232    *
233    * @param req servlet request for generating the page.
234    * @param res servlet response to any needed error messages.
235    */

236   private Page getSubPage(HttpServletRequest JavaDoc req, HttpServletResponse JavaDoc res)
237     throws Exception JavaDoc
238   {
239     CauchoRequest cauchoRequest = null;
240
241     initGetPage();
242       
243     /*
244     if (! _webApp.isActive())
245       throw new UnavailableException("JSP compilation unavailable during restart", 10);
246     */

247
248     if (req instanceof CauchoRequest)
249       cauchoRequest = (CauchoRequest) req;
250
251     String JavaDoc servletPath;
252
253     if (cauchoRequest != null)
254       servletPath = cauchoRequest.getPageServletPath();
255     else
256       servletPath = RequestAdapter.getPageServletPath(req);
257
258     if (servletPath == null)
259       servletPath = "/";
260
261     String JavaDoc uri;
262     String JavaDoc pageURI;
263
264     if (cauchoRequest != null)
265       uri = cauchoRequest.getPageURI();
266     else
267       uri = RequestAdapter.getPageURI(req);
268
269     Path appDir = _webApp.getAppDir();
270
271     String JavaDoc realPath;
272     Path subcontext;
273
274     Page page;
275
276     String JavaDoc jspPath = (String JavaDoc) req.getAttribute("caucho.jsp.jsp-file");
277     if (jspPath != null) {
278       req.removeAttribute("caucho.jsp.jsp-file");
279
280       subcontext = getPagePath(jspPath);
281
282       return _manager.getPage(uri, jspPath, subcontext);
283     }
284
285     String JavaDoc pathInfo;
286
287     if (cauchoRequest != null)
288       pathInfo = cauchoRequest.getPagePathInfo();
289     else
290       pathInfo = RequestAdapter.getPagePathInfo(req);
291
292     subcontext = getPagePath(servletPath);
293     if (subcontext != null)
294       return _manager.getPage(servletPath, subcontext);
295
296     if (pathInfo == null) {
297       realPath = _webApp.getRealPath(servletPath);
298       subcontext = appDir.lookupNative(realPath);
299
300       return _manager.getPage(servletPath, subcontext);
301     }
302
303     subcontext = getPagePath(servletPath + pathInfo);
304     if (subcontext != null)
305       return _manager.getPage(servletPath + pathInfo, subcontext);
306
307     // If servlet path exists, can't use pathInfo to lookup servlet,
308
// because /jsp/WEB-INF would be a security hole
309
if (servletPath != null && ! servletPath.equals("")) {
310       // server/0035
311
throw new FileNotFoundException JavaDoc(L.l("{0} was not found on this server.",
312                       uri));
313       // return null;
314
}
315
316     subcontext = getPagePath(pathInfo);
317     if (subcontext != null)
318       return _manager.getPage(pathInfo, subcontext);
319
320     subcontext = getPagePath(uri);
321     if (subcontext == null)
322       throw new FileNotFoundException JavaDoc(L.l("{0} was not found on this server.",
323                       uri));
324     
325     return _manager.getPage(uri, subcontext);
326   }
327
328   private void initGetPage()
329   {
330     // marks the listener array as used
331
_webApp.getJspApplicationContext().getELListenerArray();
332   }
333
334   public Page getPage(String JavaDoc uri, String JavaDoc pageURI)
335     throws Exception JavaDoc
336   {
337     Path path = getPagePath(pageURI);
338
339     if (path == null)
340       return null;
341
342     return _manager.getPage(uri, pageURI, path);
343   }
344
345   /**
346    * Returns the path to be used as the servlet name.
347    */

348   private Path getPagePath(String JavaDoc pathName)
349   {
350     Path appDir = _webApp.getAppDir();
351     String JavaDoc realPath = _webApp.getRealPath(pathName);
352     Path path = appDir.lookupNative(realPath);
353
354     if (path.isFile() && path.canRead())
355       return path;
356
357     java.net.URL JavaDoc url;
358     ClassLoader JavaDoc loader = _webApp.getClassLoader();
359     if (loader != null) {
360       url = _webApp.getClassLoader().getResource(pathName);
361
362       String JavaDoc name = url != null ? url.toString() : null;
363
364       path = null;
365       if (url != null && (name.endsWith(".jar") || name.endsWith(".zip")))
366         path = JarPath.create(Vfs.lookup(url.toString())).lookup(pathName);
367       else if (url != null)
368         path = Vfs.lookup(url.toString());
369
370       if (path != null && path.isFile() && path.canRead())
371         return path;
372     }
373
374     url = ClassLoader.getSystemResource(pathName);
375     String JavaDoc name = url != null ? url.toString() : null;
376
377       path = null;
378     if (url != null && (name.endsWith(".jar") || name.endsWith(".zip")))
379       path = JarPath.create(Vfs.lookup(url.toString())).lookup(pathName);
380     else if (url != null)
381       path = Vfs.lookup(url.toString());
382
383     if (path != null && path.isFile() && path.canRead())
384       return path;
385     else
386       return null;
387   }
388
389   /**
390    * Remove the page from any cache.
391    */

392   public void killPage(HttpServletRequest JavaDoc request,
393                        HttpServletResponse JavaDoc response,
394                        Page page)
395   {
396     _manager.killPage(request, response, page);
397   }
398
399   /**
400    * Forwards an error to the proper error page.
401    *
402    * @param req the servlet request
403    * @param res the servlet response
404    * @param e the exception
405    * @param errorPage the error page
406    */

407   private boolean forwardErrorPage(HttpServletRequest JavaDoc req,
408                                    HttpServletResponse JavaDoc res,
409                                    Throwable JavaDoc e, String JavaDoc errorPage)
410     throws ServletException, IOException JavaDoc
411   {
412     req.setAttribute("javax.servlet.jsp.jspException", e);
413     req.setAttribute("javax.servlet.error.exception_type", e);
414     req.setAttribute("javax.servlet.error.request_uri",
415                      req.getRequestURI());
416
417     if (res instanceof CauchoResponse) {
418       CauchoResponse cauchoResponse = (CauchoResponse) res;
419       cauchoResponse.killCache();
420       cauchoResponse.setNoCache(true);
421     }
422
423     RequestDispatcher rd = req.getRequestDispatcher(errorPage);
424
425     if (rd == null)
426       return false;
427
428     rd.forward(req, res);
429
430     return true;
431   }
432
433   public void destroy()
434   {
435     _manager.destroy();
436
437     log.finer(_config.getServletName() + " destroy");
438   }
439 }
440
Popular Tags