~ubuntu-branches/ubuntu/intrepid/tomcat5.5/intrepid

« back to all changes in this revision

Viewing changes to jasper/jasper2/src/share/org/apache/jasper/servlet/JspServlet.java

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-09-27 11:19:17 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060927111917-wov6fmkz3x6rsl68
Tags: 5.5.17-1ubuntu1
(Build-) depend on libmx4j-java (>= 3.0).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 1999,2004 The Apache Software Foundation.
3
 
 * 
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 * 
8
 
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 
 * 
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
package org.apache.jasper.servlet;
18
 
 
19
 
import java.io.IOException;
20
 
import java.lang.reflect.Constructor;
21
 
import java.util.Enumeration;
22
 
 
23
 
import javax.servlet.ServletConfig;
24
 
import javax.servlet.ServletContext;
25
 
import javax.servlet.ServletException;
26
 
import javax.servlet.http.HttpServlet;
27
 
import javax.servlet.http.HttpServletRequest;
28
 
import javax.servlet.http.HttpServletResponse;
29
 
 
30
 
import org.apache.commons.logging.Log;
31
 
import org.apache.commons.logging.LogFactory;
32
 
 
33
 
import org.apache.jasper.Constants;
34
 
import org.apache.jasper.EmbeddedServletOptions;
35
 
import org.apache.jasper.Options;
36
 
import org.apache.jasper.compiler.JspRuntimeContext;
37
 
import org.apache.jasper.compiler.Localizer;
38
 
 
39
 
/**
40
 
 * The JSP engine (a.k.a Jasper).
41
 
 *
42
 
 * The servlet container is responsible for providing a
43
 
 * URLClassLoader for the web application context Jasper
44
 
 * is being used in. Jasper will try get the Tomcat
45
 
 * ServletContext attribute for its ServletContext class
46
 
 * loader, if that fails, it uses the parent class loader.
47
 
 * In either case, it must be a URLClassLoader.
48
 
 *
49
 
 * @author Anil K. Vijendran
50
 
 * @author Harish Prabandham
51
 
 * @author Remy Maucherat
52
 
 * @author Kin-man Chung
53
 
 * @author Glenn Nielsen
54
 
 */
55
 
public class JspServlet extends HttpServlet {
56
 
 
57
 
    // Logger
58
 
    private Log log = LogFactory.getLog(JspServlet.class);
59
 
 
60
 
    private ServletContext context;
61
 
    private ServletConfig config;
62
 
    private Options options;
63
 
    private JspRuntimeContext rctxt;
64
 
 
65
 
 
66
 
    /*
67
 
     * Initializes this JspServlet.
68
 
     */
69
 
    public void init(ServletConfig config) throws ServletException {
70
 
        
71
 
        super.init(config);
72
 
        this.config = config;
73
 
        this.context = config.getServletContext();
74
 
        
75
 
        // Initialize the JSP Runtime Context
76
 
        // Check for a custom Options implementation
77
 
        String engineOptionsName = 
78
 
            config.getInitParameter("engineOptionsClass");
79
 
        if (engineOptionsName != null) {
80
 
            // Instantiate the indicated Options implementation
81
 
            try {
82
 
                ClassLoader loader = Thread.currentThread()
83
 
                        .getContextClassLoader();
84
 
                Class engineOptionsClass = loader.loadClass(engineOptionsName);
85
 
                Class[] ctorSig = { ServletConfig.class, ServletContext.class };
86
 
                Constructor ctor = engineOptionsClass.getConstructor(ctorSig);
87
 
                Object[] args = { config, context };
88
 
                options = (Options) ctor.newInstance(args);
89
 
            } catch (Throwable e) {
90
 
                // Need to localize this.
91
 
                log.warn("Failed to load engineOptionsClass", e);
92
 
                // Use the default Options implementation
93
 
                options = new EmbeddedServletOptions(config, context);
94
 
            }
95
 
        } else {
96
 
            // Use the default Options implementation
97
 
            options = new EmbeddedServletOptions(config, context);
98
 
        }
99
 
        rctxt = new JspRuntimeContext(context, options);
100
 
        
101
 
        if (log.isDebugEnabled()) {
102
 
            log.debug(Localizer.getMessage("jsp.message.scratch.dir.is",
103
 
                    options.getScratchDir().toString()));
104
 
            log.debug(Localizer.getMessage("jsp.message.dont.modify.servlets"));
105
 
        }
106
 
    }
107
 
 
108
 
 
109
 
    /**
110
 
     * Returns the number of JSPs for which JspServletWrappers exist, i.e.,
111
 
     * the number of JSPs that have been loaded into the webapp with which
112
 
     * this JspServlet is associated.
113
 
     *
114
 
     * <p>This info may be used for monitoring purposes.
115
 
     *
116
 
     * @return The number of JSPs that have been loaded into the webapp with
117
 
     * which this JspServlet is associated
118
 
     */
119
 
    public int getJspCount() {
120
 
        return this.rctxt.getJspCount();
121
 
    }
122
 
 
123
 
 
124
 
    /**
125
 
     * Resets the JSP reload counter.
126
 
     *
127
 
     * @param count Value to which to reset the JSP reload counter
128
 
     */
129
 
    public void setJspReloadCount(int count) {
130
 
        this.rctxt.setJspReloadCount(count);
131
 
    }
132
 
 
133
 
 
134
 
    /**
135
 
     * Gets the number of JSPs that have been reloaded.
136
 
     *
137
 
     * <p>This info may be used for monitoring purposes.
138
 
     *
139
 
     * @return The number of JSPs (in the webapp with which this JspServlet is
140
 
     * associated) that have been reloaded
141
 
     */
142
 
    public int getJspReloadCount() {
143
 
        return this.rctxt.getJspReloadCount();
144
 
    }
145
 
 
146
 
 
147
 
    /**
148
 
     * <p>Look for a <em>precompilation request</em> as described in
149
 
     * Section 8.4.2 of the JSP 1.2 Specification.  <strong>WARNING</strong> -
150
 
     * we cannot use <code>request.getParameter()</code> for this, because
151
 
     * that will trigger parsing all of the request parameters, and not give
152
 
     * a servlet the opportunity to call
153
 
     * <code>request.setCharacterEncoding()</code> first.</p>
154
 
     *
155
 
     * @param request The servlet requset we are processing
156
 
     *
157
 
     * @exception ServletException if an invalid parameter value for the
158
 
     *  <code>jsp_precompile</code> parameter name is specified
159
 
     */
160
 
    boolean preCompile(HttpServletRequest request) throws ServletException {
161
 
 
162
 
        String queryString = request.getQueryString();
163
 
        if (queryString == null) {
164
 
            return (false);
165
 
        }
166
 
        int start = queryString.indexOf(Constants.PRECOMPILE);
167
 
        if (start < 0) {
168
 
            return (false);
169
 
        }
170
 
        queryString =
171
 
            queryString.substring(start + Constants.PRECOMPILE.length());
172
 
        if (queryString.length() == 0) {
173
 
            return (true);             // ?jsp_precompile
174
 
        }
175
 
        if (queryString.startsWith("&")) {
176
 
            return (true);             // ?jsp_precompile&foo=bar...
177
 
        }
178
 
        if (!queryString.startsWith("=")) {
179
 
            return (false);            // part of some other name or value
180
 
        }
181
 
        int limit = queryString.length();
182
 
        int ampersand = queryString.indexOf("&");
183
 
        if (ampersand > 0) {
184
 
            limit = ampersand;
185
 
        }
186
 
        String value = queryString.substring(1, limit);
187
 
        if (value.equals("true")) {
188
 
            return (true);             // ?jsp_precompile=true
189
 
        } else if (value.equals("false")) {
190
 
            // Spec says if jsp_precompile=false, the request should not
191
 
            // be delivered to the JSP page; the easiest way to implement
192
 
            // this is to set the flag to true, and precompile the page anyway.
193
 
            // This still conforms to the spec, since it says the
194
 
            // precompilation request can be ignored.
195
 
            return (true);             // ?jsp_precompile=false
196
 
        } else {
197
 
            throw new ServletException("Cannot have request parameter " +
198
 
                                       Constants.PRECOMPILE + " set to " +
199
 
                                       value);
200
 
        }
201
 
 
202
 
    }
203
 
    
204
 
 
205
 
    public void service (HttpServletRequest request, 
206
 
                         HttpServletResponse response)
207
 
                throws ServletException, IOException {
208
 
 
209
 
        String jspUri = null;
210
 
 
211
 
        String jspFile = (String) request.getAttribute(Constants.JSP_FILE);
212
 
        if (jspFile != null) {
213
 
            // JSP is specified via <jsp-file> in <servlet> declaration
214
 
            jspUri = jspFile;
215
 
        } else {
216
 
            /*
217
 
             * Check to see if the requested JSP has been the target of a
218
 
             * RequestDispatcher.include()
219
 
             */
220
 
            jspUri = (String) request.getAttribute(Constants.INC_SERVLET_PATH);
221
 
            if (jspUri != null) {
222
 
                /*
223
 
                 * Requested JSP has been target of
224
 
                 * RequestDispatcher.include(). Its path is assembled from the
225
 
                 * relevant javax.servlet.include.* request attributes
226
 
                 */
227
 
                String pathInfo = (String) request.getAttribute(
228
 
                                    "javax.servlet.include.path_info");
229
 
                if (pathInfo != null) {
230
 
                    jspUri += pathInfo;
231
 
                }
232
 
            } else {
233
 
                /*
234
 
                 * Requested JSP has not been the target of a 
235
 
                 * RequestDispatcher.include(). Reconstruct its path from the
236
 
                 * request's getServletPath() and getPathInfo()
237
 
                 */
238
 
                jspUri = request.getServletPath();
239
 
                String pathInfo = request.getPathInfo();
240
 
                if (pathInfo != null) {
241
 
                    jspUri += pathInfo;
242
 
                }
243
 
            }
244
 
        }
245
 
 
246
 
        if (log.isDebugEnabled()) {         
247
 
            log.debug("JspEngine --> " + jspUri);
248
 
            log.debug("\t     ServletPath: " + request.getServletPath());
249
 
            log.debug("\t        PathInfo: " + request.getPathInfo());
250
 
            log.debug("\t        RealPath: " + context.getRealPath(jspUri));
251
 
            log.debug("\t      RequestURI: " + request.getRequestURI());
252
 
            log.debug("\t     QueryString: " + request.getQueryString());
253
 
            log.debug("\t  Request Params: ");
254
 
            Enumeration e = request.getParameterNames();
255
 
            while (e.hasMoreElements()) {
256
 
                String name = (String) e.nextElement();
257
 
                log.debug("\t\t " + name + " = " 
258
 
                          + request.getParameter(name));
259
 
            }
260
 
        }
261
 
 
262
 
        try {
263
 
            boolean precompile = preCompile(request);
264
 
            serviceJspFile(request, response, jspUri, null, precompile);
265
 
        } catch (RuntimeException e) {
266
 
            throw e;
267
 
        } catch (ServletException e) {
268
 
            throw e;
269
 
        } catch (IOException e) {
270
 
            throw e;
271
 
        } catch (Throwable e) {
272
 
            throw new ServletException(e);
273
 
        }
274
 
 
275
 
    }
276
 
 
277
 
    public void destroy() {
278
 
        if (log.isDebugEnabled()) {
279
 
            log.debug("JspServlet.destroy()");
280
 
        }
281
 
 
282
 
        rctxt.destroy();
283
 
    }
284
 
 
285
 
 
286
 
    // -------------------------------------------------------- Private Methods
287
 
 
288
 
    private void serviceJspFile(HttpServletRequest request,
289
 
                                HttpServletResponse response, String jspUri,
290
 
                                Throwable exception, boolean precompile)
291
 
        throws ServletException, IOException {
292
 
 
293
 
        JspServletWrapper wrapper =
294
 
            (JspServletWrapper) rctxt.getWrapper(jspUri);
295
 
        if (wrapper == null) {
296
 
            synchronized(this) {
297
 
                wrapper = (JspServletWrapper) rctxt.getWrapper(jspUri);
298
 
                if (wrapper == null) {
299
 
                    // Check if the requested JSP page exists, to avoid
300
 
                    // creating unnecessary directories and files.
301
 
                    if (null == context.getResource(jspUri)) {
302
 
                        response.sendError(HttpServletResponse.SC_NOT_FOUND,
303
 
                                           jspUri);
304
 
                        return;
305
 
                    }
306
 
                    boolean isErrorPage = exception != null;
307
 
                    wrapper = new JspServletWrapper(config, options, jspUri,
308
 
                                                    isErrorPage, rctxt);
309
 
                    rctxt.addWrapper(jspUri,wrapper);
310
 
                }
311
 
            }
312
 
        }
313
 
 
314
 
        wrapper.service(request, response, precompile);
315
 
 
316
 
    }
317
 
 
318
 
}