KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jasper > servlet > JspServlet


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 package org.apache.jasper.servlet;
19
20 import java.io.IOException JavaDoc;
21 import java.lang.reflect.Constructor JavaDoc;
22 import java.util.Enumeration JavaDoc;
23
24 import javax.servlet.ServletConfig JavaDoc;
25 import javax.servlet.ServletContext JavaDoc;
26 import javax.servlet.ServletException 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.PeriodicEventListener;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.apache.jasper.Constants;
36 import org.apache.jasper.EmbeddedServletOptions;
37 import org.apache.jasper.Options;
38 import org.apache.jasper.compiler.JspRuntimeContext;
39 import org.apache.jasper.compiler.Localizer;
40
41 /**
42  * The JSP engine (a.k.a Jasper).
43  *
44  * The servlet container is responsible for providing a
45  * URLClassLoader for the web application context Jasper
46  * is being used in. Jasper will try get the Tomcat
47  * ServletContext attribute for its ServletContext class
48  * loader, if that fails, it uses the parent class loader.
49  * In either case, it must be a URLClassLoader.
50  *
51  * @author Anil K. Vijendran
52  * @author Harish Prabandham
53  * @author Remy Maucherat
54  * @author Kin-man Chung
55  * @author Glenn Nielsen
56  */

57 public class JspServlet extends HttpServlet JavaDoc implements PeriodicEventListener {
58
59     // Logger
60
private Log log = LogFactory.getLog(JspServlet.class);
61
62     private ServletContext JavaDoc context;
63     private ServletConfig JavaDoc config;
64     private Options options;
65     private JspRuntimeContext rctxt;
66
67
68     /*
69      * Initializes this JspServlet.
70      */

71     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
72         
73         super.init(config);
74         this.config = config;
75         this.context = config.getServletContext();
76         
77         // Initialize the JSP Runtime Context
78
// Check for a custom Options implementation
79
String JavaDoc engineOptionsName =
80             config.getInitParameter("engineOptionsClass");
81         if (engineOptionsName != null) {
82             // Instantiate the indicated Options implementation
83
try {
84                 ClassLoader JavaDoc loader = Thread.currentThread()
85                         .getContextClassLoader();
86                 Class JavaDoc engineOptionsClass = loader.loadClass(engineOptionsName);
87                 Class JavaDoc[] ctorSig = { ServletConfig JavaDoc.class, ServletContext JavaDoc.class };
88                 Constructor JavaDoc ctor = engineOptionsClass.getConstructor(ctorSig);
89                 Object JavaDoc[] args = { config, context };
90                 options = (Options) ctor.newInstance(args);
91             } catch (Throwable JavaDoc e) {
92                 // Need to localize this.
93
log.warn("Failed to load engineOptionsClass", e);
94                 // Use the default Options implementation
95
options = new EmbeddedServletOptions(config, context);
96             }
97         } else {
98             // Use the default Options implementation
99
options = new EmbeddedServletOptions(config, context);
100         }
101         rctxt = new JspRuntimeContext(context, options);
102         
103         if (log.isDebugEnabled()) {
104             log.debug(Localizer.getMessage("jsp.message.scratch.dir.is",
105                     options.getScratchDir().toString()));
106             log.debug(Localizer.getMessage("jsp.message.dont.modify.servlets"));
107         }
108     }
109
110
111     /**
112      * Returns the number of JSPs for which JspServletWrappers exist, i.e.,
113      * the number of JSPs that have been loaded into the webapp with which
114      * this JspServlet is associated.
115      *
116      * <p>This info may be used for monitoring purposes.
117      *
118      * @return The number of JSPs that have been loaded into the webapp with
119      * which this JspServlet is associated
120      */

121     public int getJspCount() {
122         return this.rctxt.getJspCount();
123     }
124
125
126     /**
127      * Resets the JSP reload counter.
128      *
129      * @param count Value to which to reset the JSP reload counter
130      */

131     public void setJspReloadCount(int count) {
132         this.rctxt.setJspReloadCount(count);
133     }
134
135
136     /**
137      * Gets the number of JSPs that have been reloaded.
138      *
139      * <p>This info may be used for monitoring purposes.
140      *
141      * @return The number of JSPs (in the webapp with which this JspServlet is
142      * associated) that have been reloaded
143      */

144     public int getJspReloadCount() {
145         return this.rctxt.getJspReloadCount();
146     }
147
148
149     /**
150      * <p>Look for a <em>precompilation request</em> as described in
151      * Section 8.4.2 of the JSP 1.2 Specification. <strong>WARNING</strong> -
152      * we cannot use <code>request.getParameter()</code> for this, because
153      * that will trigger parsing all of the request parameters, and not give
154      * a servlet the opportunity to call
155      * <code>request.setCharacterEncoding()</code> first.</p>
156      *
157      * @param request The servlet requset we are processing
158      *
159      * @exception ServletException if an invalid parameter value for the
160      * <code>jsp_precompile</code> parameter name is specified
161      */

162     boolean preCompile(HttpServletRequest JavaDoc request) throws ServletException JavaDoc {
163
164         String JavaDoc queryString = request.getQueryString();
165         if (queryString == null) {
166             return (false);
167         }
168         int start = queryString.indexOf(Constants.PRECOMPILE);
169         if (start < 0) {
170             return (false);
171         }
172         queryString =
173             queryString.substring(start + Constants.PRECOMPILE.length());
174         if (queryString.length() == 0) {
175             return (true); // ?jsp_precompile
176
}
177         if (queryString.startsWith("&")) {
178             return (true); // ?jsp_precompile&foo=bar...
179
}
180         if (!queryString.startsWith("=")) {
181             return (false); // part of some other name or value
182
}
183         int limit = queryString.length();
184         int ampersand = queryString.indexOf("&");
185         if (ampersand > 0) {
186             limit = ampersand;
187         }
188         String JavaDoc value = queryString.substring(1, limit);
189         if (value.equals("true")) {
190             return (true); // ?jsp_precompile=true
191
} else if (value.equals("false")) {
192         // Spec says if jsp_precompile=false, the request should not
193
// be delivered to the JSP page; the easiest way to implement
194
// this is to set the flag to true, and precompile the page anyway.
195
// This still conforms to the spec, since it says the
196
// precompilation request can be ignored.
197
return (true); // ?jsp_precompile=false
198
} else {
199             throw new ServletException JavaDoc("Cannot have request parameter " +
200                                        Constants.PRECOMPILE + " set to " +
201                                        value);
202         }
203
204     }
205     
206
207     public void service (HttpServletRequest JavaDoc request,
208                  HttpServletResponse JavaDoc response)
209                 throws ServletException JavaDoc, IOException JavaDoc {
210
211         String JavaDoc jspUri = null;
212
213         String JavaDoc jspFile = (String JavaDoc) request.getAttribute(Constants.JSP_FILE);
214         if (jspFile != null) {
215             // JSP is specified via <jsp-file> in <servlet> declaration
216
jspUri = jspFile;
217         } else {
218             /*
219              * Check to see if the requested JSP has been the target of a
220              * RequestDispatcher.include()
221              */

222             jspUri = (String JavaDoc) request.getAttribute(Constants.INC_SERVLET_PATH);
223             if (jspUri != null) {
224                 /*
225          * Requested JSP has been target of
226                  * RequestDispatcher.include(). Its path is assembled from the
227                  * relevant javax.servlet.include.* request attributes
228                  */

229                 String JavaDoc pathInfo = (String JavaDoc) request.getAttribute(
230                                     "javax.servlet.include.path_info");
231                 if (pathInfo != null) {
232                     jspUri += pathInfo;
233                 }
234             } else {
235                 /*
236                  * Requested JSP has not been the target of a
237                  * RequestDispatcher.include(). Reconstruct its path from the
238                  * request's getServletPath() and getPathInfo()
239                  */

240                 jspUri = request.getServletPath();
241                 String JavaDoc pathInfo = request.getPathInfo();
242                 if (pathInfo != null) {
243                     jspUri += pathInfo;
244                 }
245             }
246         }
247
248         if (log.isDebugEnabled()) {
249             log.debug("JspEngine --> " + jspUri);
250             log.debug("\t ServletPath: " + request.getServletPath());
251             log.debug("\t PathInfo: " + request.getPathInfo());
252             log.debug("\t RealPath: " + context.getRealPath(jspUri));
253             log.debug("\t RequestURI: " + request.getRequestURI());
254             log.debug("\t QueryString: " + request.getQueryString());
255             log.debug("\t Request Params: ");
256             Enumeration JavaDoc e = request.getParameterNames();
257             while (e.hasMoreElements()) {
258                 String JavaDoc name = (String JavaDoc) e.nextElement();
259                 log.debug("\t\t " + name + " = "
260                           + request.getParameter(name));
261             }
262         }
263
264         try {
265             boolean precompile = preCompile(request);
266             serviceJspFile(request, response, jspUri, null, precompile);
267         } catch (RuntimeException JavaDoc e) {
268             throw e;
269         } catch (ServletException JavaDoc e) {
270             throw e;
271         } catch (IOException JavaDoc e) {
272             throw e;
273         } catch (Throwable JavaDoc e) {
274             throw new ServletException JavaDoc(e);
275         }
276
277     }
278
279     public void destroy() {
280         if (log.isDebugEnabled()) {
281             log.debug("JspServlet.destroy()");
282         }
283
284         rctxt.destroy();
285     }
286
287
288     public void periodicEvent() {
289         rctxt.checkCompile();
290     }
291
292     // -------------------------------------------------------- Private Methods
293

294     private void serviceJspFile(HttpServletRequest JavaDoc request,
295                                 HttpServletResponse JavaDoc response, String JavaDoc jspUri,
296                                 Throwable JavaDoc exception, boolean precompile)
297         throws ServletException JavaDoc, IOException JavaDoc {
298
299         JspServletWrapper wrapper =
300             (JspServletWrapper) rctxt.getWrapper(jspUri);
301         if (wrapper == null) {
302             synchronized(this) {
303                 wrapper = (JspServletWrapper) rctxt.getWrapper(jspUri);
304                 if (wrapper == null) {
305                     // Check if the requested JSP page exists, to avoid
306
// creating unnecessary directories and files.
307
if (null == context.getResource(jspUri)) {
308                         response.sendError(HttpServletResponse.SC_NOT_FOUND,
309                                            jspUri);
310                         return;
311                     }
312                     boolean isErrorPage = exception != null;
313                     wrapper = new JspServletWrapper(config, options, jspUri,
314                                                     isErrorPage, rctxt);
315                     rctxt.addWrapper(jspUri,wrapper);
316                 }
317             }
318         }
319
320         wrapper.service(request, response, precompile);
321
322     }
323
324
325 }
326
Popular Tags