KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > web > jsp > JspServlet


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.web.jsp;
25
26 import javax.servlet.Servlet JavaDoc;
27 import javax.servlet.ServletContext JavaDoc;
28 import javax.servlet.ServletConfig JavaDoc;
29 import javax.servlet.ServletException JavaDoc;
30 import javax.servlet.SingleThreadModel JavaDoc;
31 import javax.servlet.http.HttpServlet JavaDoc;
32 import javax.servlet.http.HttpServletRequest JavaDoc;
33 import javax.servlet.http.HttpServletResponse JavaDoc;
34 import javax.servlet.jsp.JspFactory JavaDoc;
35
36 import java.util.Map JavaDoc;
37 import java.util.HashMap JavaDoc;
38 import java.util.Hashtable JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.io.File JavaDoc;
41 import java.io.PrintWriter JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.FileNotFoundException JavaDoc;
44 import java.io.FilePermission JavaDoc;
45 import java.lang.RuntimePermission JavaDoc;
46 import java.net.URL JavaDoc;
47 import java.net.URLClassLoader JavaDoc;
48 import java.net.MalformedURLException JavaDoc;
49 import java.security.AccessController JavaDoc;
50 import java.security.CodeSource JavaDoc;
51 import java.security.PermissionCollection JavaDoc;
52 import java.security.Policy JavaDoc;
53 import java.security.PrivilegedAction JavaDoc;
54
55 import org.apache.jasper.JasperException;
56 import org.apache.jasper.Constants;
57 import org.apache.jasper.Options;
58 import org.apache.jasper.EmbededServletOptions;
59 import org.apache.jasper.JspCompilationContext;
60 import org.apache.jasper.JspEngineContext;
61 import org.apache.jasper.compiler.JspMangler;
62 import org.apache.jasper.compiler.Compiler;
63 import org.apache.jasper.runtime.JspFactoryImpl;
64 import org.apache.jasper.servlet.JasperLoader;
65 import org.apache.jasper.logging.Logger;
66 import org.apache.jasper.logging.DefaultLogger;
67
68 /**
69  * This is an iPlanet adaptation of the Apache Jasper JSPServlet.
70  * This servlet has several performance enhancements over the Apache
71  * JspServlet. These include:
72  * - Reducing the overall number of file stats per request
73  * - Checking for JSP modifications based on a reload interval
74  * - Caching compilation exceptions and recompiling the JSP only when
75  * it is modified
76  */

77 public class JspServlet extends HttpServlet JavaDoc {
78     protected ServletContext JavaDoc context = null;
79     protected Map JavaDoc jsps = null;
80     protected ServletConfig JavaDoc config;
81     protected Options options;
82     protected URLClassLoader JavaDoc parentClassLoader;
83     private PermissionCollection JavaDoc permissionCollection = null;
84     private CodeSource JavaDoc codeSource = null;
85
86     // Time in millisecs to check for changes in jsps to force recompilation
87
private long reloadInterval = 0L;
88
89     // if this flag is false, the JSPs are not checked for modifications
90
// and are never recompiled
91
private boolean checkJSPmods = true;
92
93     // flag for whether debug messages need to be logged
94
private boolean debugLogEnabled = false;
95
96     // directory under which to generate the servlets
97
String JavaDoc outputDir = null;
98
99     // urls used by JasperLoader to load generated jsp class files
100
URL JavaDoc[] loaderURLs = null;
101
102     static boolean firstTime = true;
103
104     public void init(ServletConfig JavaDoc config)
105         throws ServletException JavaDoc {
106
107         super.init(config);
108         this.config = config;
109         this.context = config.getServletContext();
110         
111         Constants.jasperLog = new DefaultLogger(this.context);
112         Constants.jasperLog.setName("JASPER_LOG");
113         Constants.jasperLog.setTimestamp("false");
114         Constants.jasperLog.setVerbosityLevel(
115                    config.getInitParameter("logVerbosityLevel"));
116
117         debugLogEnabled = Constants.jasperLog.matchVerbosityLevel(Logger.DEBUG);
118
119         // reload-interval (specified in seconds) is the interval at which
120
// JSP files are checked for modifications. Values that have 'special'
121
// significance are:
122
// 0 : Check JSPs for modifications on every request
123
// -1 : do not check for JSP modifications and disable recompilation
124
String JavaDoc interval = config.getInitParameter("reload-interval");
125         if (interval != null) {
126             try {
127                 this.reloadInterval = Integer.parseInt(interval) * 1000;
128                 if (this.reloadInterval < 0) {
129                     checkJSPmods = false;
130                     Constants.message("jsp.message.recompile.disabled",
131                                       Logger.INFORMATION );
132                 } else if (this.reloadInterval > 0) {
133                     Constants.message("jsp.message.reload.interval",
134                               new Object JavaDoc[] {interval}, Logger.INFORMATION );
135                 }
136             } catch (NumberFormatException JavaDoc nfe) {
137                 Constants.message("jsp.warning.interval.invalid",
138                               new Object JavaDoc[] {interval}, Logger.WARNING );
139             }
140         }
141
142         // In case of checking JSP for mods, use a HashMap instead of a
143
// Hashtable since we anyway synchronize on all accesses to the jsp
144
// wrappers for the sake of ref counting, so this avoids double
145
// synchronization
146
if (checkJSPmods)
147             jsps = new HashMap JavaDoc();
148         else
149             jsps = new Hashtable JavaDoc();
150
151         options = new EmbededServletOptions(config, context);
152
153         outputDir = options.getScratchDir().toString();
154
155         // set the loader urls to the output dir since that is where the
156
// java classes corresponding to the jsps can be found
157
File JavaDoc f = new File JavaDoc(outputDir);
158
159         // If the toplevel output directory does not exist, then
160
// create it at this point before adding it to the classloader path
161
// If the directory does not exist when adding to the classloader,
162
// the classloader has problems loading the classes later
163
if (f.exists() == false) {
164             f.mkdirs();
165         }
166         
167         loaderURLs = new URL JavaDoc[1];
168         try {
169             loaderURLs[0] = f.toURL();
170         } catch(MalformedURLException JavaDoc mfe) {
171             throw new ServletException JavaDoc(mfe);
172         }
173
174         // Get the parent class loader. The servlet container is responsible
175
// for providing a URLClassLoader for the web application context
176
// the JspServlet is being used in.
177
parentClassLoader =
178             (URLClassLoader JavaDoc) Thread.currentThread().getContextClassLoader();
179         if (parentClassLoader == null)
180             parentClassLoader = (URLClassLoader JavaDoc)this.getClass().getClassLoader();
181         String JavaDoc loaderString = "<none>";
182         if (parentClassLoader != null)
183             loaderString = parentClassLoader.toString();
184
185         if (debugLogEnabled)
186             Constants.message("jsp.message.parent_class_loader_is",
187                               new Object JavaDoc[] {loaderString}, Logger.DEBUG);
188
189         // Setup the PermissionCollection for this web app context
190
// based on the permissions configured for the root of the
191
// web app context directory, then add a file read permission
192
// for that directory.
193
Policy JavaDoc policy = Policy.getPolicy();
194         if( policy != null ) {
195             try {
196                 // Get the permissions for the web app context
197
String JavaDoc contextDir = context.getRealPath("/");
198                 if( contextDir == null )
199                     contextDir = outputDir;
200                 URL JavaDoc url = new URL JavaDoc("file:" + contextDir);
201                 codeSource = new CodeSource JavaDoc(url,null);
202                 permissionCollection = policy.getPermissions(codeSource);
203                 // Create a file read permission for web app context directory
204
if (contextDir.endsWith(File.separator))
205                     contextDir = contextDir + "-";
206                 else
207                     contextDir = contextDir + File.separator + "-";
208                 permissionCollection.add( new FilePermission JavaDoc(contextDir,"read") );
209                 // Allow the JSP to access org.apache.jasper.runtime.HttpJspBase
210
permissionCollection.add( new RuntimePermission JavaDoc(
211                     "accessClassInPackage.org.apache.jasper.runtime") );
212                 if (parentClassLoader instanceof URLClassLoader JavaDoc) {
213                     URL JavaDoc [] urls = parentClassLoader.getURLs();
214                     String JavaDoc jarUrl = null;
215                     String JavaDoc jndiUrl = null;
216                     for (int i=0; i<urls.length; i++) {
217                         if (jndiUrl == null && urls[i].toString().startsWith("jndi:") ) {
218                             jndiUrl = urls[i].toString() + "-";
219                         }
220                         if (jarUrl == null && urls[i].toString().startsWith("jar:jndi:") ) {
221                             jarUrl = urls[i].toString();
222                             jarUrl = jarUrl.substring(0,jarUrl.length() - 2);
223                             jarUrl = jarUrl.substring(0,jarUrl.lastIndexOf('/')) + "/-";
224                         }
225                     }
226                     if (jarUrl != null) {
227                         permissionCollection.add( new FilePermission JavaDoc(jarUrl,"read") );
228                         permissionCollection.add( new FilePermission JavaDoc(jarUrl.substring(4),"read") );
229                     }
230                     if (jndiUrl != null)
231                         permissionCollection.add( new FilePermission JavaDoc(jndiUrl,"read") );
232                 }
233             } catch(MalformedURLException JavaDoc mfe) {}
234         }
235
236         if (firstTime) {
237             firstTime = false;
238             if( System.getSecurityManager() != null ) {
239                 // Make sure classes needed at runtime by a JSP servlet
240
// are already loaded by the class loader so that we
241
// don't get a defineClassInPackage security exception.
242
String JavaDoc apacheBase = "org.apache.jasper.";
243                 String JavaDoc iplanetBase = "com.sun.enterprise.web.jsp.";
244                 try {
245                     parentClassLoader.loadClass( apacheBase +
246                         "runtime.JspFactoryImpl$PrivilegedGetPageContext");
247                     parentClassLoader.loadClass( apacheBase +
248                         "runtime.JspFactoryImpl$PrivilegedReleasePageContext");
249                     parentClassLoader.loadClass( apacheBase +
250                         "runtime.JspRuntimeLibrary");
251                     parentClassLoader.loadClass( apacheBase +
252                         "runtime.JspRuntimeLibrary$PrivilegedIntrospectHelper");
253                     parentClassLoader.loadClass( apacheBase +
254                         "runtime.ServletResponseWrapperInclude");
255                     this.getClass().getClassLoader().loadClass( iplanetBase +
256                         "JspServlet$JspServletWrapper");
257                 } catch (ClassNotFoundException JavaDoc ex) {
258                     Constants.jasperLog.log(
259                         Constants.getString("jsp.message.preload.failure"),
260                         ex, Logger.WARNING);
261                 }
262             }
263             Constants.message("jsp.message.scratch.dir.is",
264                               new Object JavaDoc[] {outputDir}, Logger.INFORMATION );
265             Constants.message("jsp.message.dont.modify.servlets", Logger.INFORMATION);
266             JspFactory.setDefaultFactory(new JspFactoryImpl());
267         }
268     }
269
270     public void service(HttpServletRequest JavaDoc request,
271                         HttpServletResponse JavaDoc response)
272         throws ServletException JavaDoc, IOException JavaDoc {
273         try {
274             String JavaDoc jspUri;
275             String JavaDoc includeUri
276                 = (String JavaDoc) request.getAttribute(Constants.INC_SERVLET_PATH);
277
278             if (includeUri == null)
279                 jspUri = request.getServletPath();
280             else
281                 jspUri = includeUri;
282
283             String JavaDoc jspFile = (String JavaDoc) request.getAttribute(Constants.JSP_FILE);
284             if (jspFile != null)
285                 jspUri = jspFile;
286
287             if (debugLogEnabled) {
288                 Logger jasperLog = Constants.jasperLog;
289                 jasperLog.log("JspEngine --> "+jspUri);
290                 jasperLog.log(" ServletPath: "+request.getServletPath());
291                 jasperLog.log(" PathInfo: "+request.getPathInfo());
292                 jasperLog.log(" RealPath: "+context.getRealPath(jspUri));
293                 jasperLog.log(" RequestURI: "+request.getRequestURI());
294                 jasperLog.log(" QueryString: "+request.getQueryString());
295             }
296
297             serviceJspFile(request, response, jspUri);
298
299         } catch (RuntimeException JavaDoc e) {
300             throw e;
301         } catch (ServletException JavaDoc e) {
302             throw e;
303         } catch (IOException JavaDoc e) {
304             throw e;
305         } catch (Throwable JavaDoc e) {
306             throw new ServletException JavaDoc(e);
307         }
308     }
309
310     /**
311      * This is the main service function which creates the wrapper, loads
312      * the JSP if not loaded, checks for JSP modifications if specified,
313      * recompiles the JSP if needed and finally calls the service function
314      * on the wrapper.
315      */

316     private void serviceJspFile(HttpServletRequest JavaDoc request,
317                                 HttpServletResponse JavaDoc response, String JavaDoc jspUri)
318         throws ServletException JavaDoc, IOException JavaDoc {
319
320         JspServletWrapper wrapper = null;
321         try {
322             if (checkJSPmods) {
323                 // this increments the refcount
324
wrapper = getWrapper(jspUri);
325                 if (wrapper == null) {
326                     // ensure that only one thread creates the wrapper
327
synchronized (this) {
328                         wrapper = getWrapper(jspUri);
329                         if (wrapper == null) {
330                             // create a new wrapper and load the jsp inside it
331
wrapper = new JspServletWrapper(jspUri);
332                             wrapper.loadJSP(request, response);
333
334                             // add the new wrapper to the map, this increments
335
// the refcount as well
336
putWrapper(jspUri, wrapper);
337                         }
338                     }
339                 } else if (wrapper.isJspFileModified()) {
340                     // create a new wrapper and load the jsp inside it
341
JspServletWrapper newWrapper =
342                                       new JspServletWrapper(jspUri);
343                     newWrapper.loadJSP(request, response);
344
345                     // add the new wrapper to the map, this increments the
346
// refcount as well
347
putWrapper(jspUri, newWrapper);
348
349                     // decrement the refcount on the old wrapper
350
releaseWrapper(wrapper);
351                     wrapper = newWrapper;
352                 }
353             } else {
354                 wrapper = (JspServletWrapper) jsps.get(jspUri);
355                 if (wrapper == null) {
356                     // ensure that only one thread creates the wrapper
357
synchronized (this) {
358                         wrapper = (JspServletWrapper) jsps.get(jspUri);
359                         if (wrapper == null) {
360                             // create a new wrapper and load the jsp inside it
361
wrapper = new JspServletWrapper(jspUri);
362                             wrapper.loadJSP(request, response);
363
364                             // add the new wrapper to the map
365
jsps.put(jspUri, wrapper);
366                         }
367                     }
368                 }
369             }
370
371             // throw any compile exception generated during compilation
372
JasperException compileException = wrapper.getCompileException();
373             if (compileException != null)
374                 throw compileException;
375
376             // service the request if it is not a precompile request
377
if (!preCompile(request))
378                 wrapper.service(request, response);
379
380         } catch (FileNotFoundException JavaDoc ex) {
381             // remove the wrapper from the map. In the case where we are not
382
// checking for JSP mods, the wrapper would never have been in
383
// the map since the exception would be thrown in loadJSP
384
if (checkJSPmods)
385                 removeWrapper(jspUri);
386
387             String JavaDoc includeRequestUri = (String JavaDoc)
388                 request.getAttribute("javax.servlet.include.request_uri");
389             if (includeRequestUri != null) {
390                 // This file was included. Throw an exception as
391
// a response.sendError() will be ignored by the
392
// servlet engine.
393
throw new ServletException JavaDoc(ex);
394             } else {
395                 try {
396                     response.sendError(HttpServletResponse.SC_NOT_FOUND,
397                                        ex.getMessage());
398                 } catch (IllegalStateException JavaDoc ise) {
399                     Constants.jasperLog.log(Constants.getString
400                                             ("jsp.error.file.not.found",
401                                              new Object JavaDoc[] {ex.getMessage()}),
402                                              ex, Logger.ERROR);
403                 }
404             }
405         } finally {
406             // decrement the refcount even in case of an exception
407
if (checkJSPmods)
408                 releaseWrapper(wrapper);
409         }
410     }
411
412     /**
413      * The following methods allow synchronized access to the jsps
414      * map as well and perform refcounting on the wrappers as well.
415      * These methods are called only when we check for JSP modifications
416      */

417     private synchronized JspServletWrapper getWrapper(String JavaDoc jspUri) {
418         JspServletWrapper wrapper = (JspServletWrapper) jsps.get(jspUri);
419         if (wrapper != null)
420             wrapper.incrementRefCount();
421         return wrapper;
422     }
423
424     private synchronized void releaseWrapper(JspServletWrapper wrapper) {
425         if (wrapper != null)
426             wrapper.decrementRefCount();
427     }
428
429     private synchronized void putWrapper(String JavaDoc jspUri,
430                                          JspServletWrapper wrapper) {
431         wrapper.incrementRefCount();
432         JspServletWrapper replaced =
433                           (JspServletWrapper)jsps.put(jspUri, wrapper);
434
435         // flag the wrapper that was replaced for destruction
436
if (replaced != null)
437             replaced.tryDestroy();
438     }
439
440     private synchronized void removeWrapper(String JavaDoc jspUri) {
441         JspServletWrapper removed = (JspServletWrapper)jsps.remove(jspUri);
442
443         // flag the wrapper that was removed for destruction
444
if (removed != null)
445             removed.tryDestroy();
446     }
447
448     /**
449      * <p>Look for a <em>precompilation request</em> as described in
450      * Section 8.4.2 of the JSP 1.2 Specification. <strong>WARNING</strong>
451      * we cannot use <code>request.getParameter()</code> for this, because
452      * that will trigger parsing all of the request parameters, and not give
453      * a servlet the opportunity to call
454      * <code>request.setCharacterEncoding()</code> first.</p>
455      *
456      * @param request The servlet requset we are processing
457      *
458      * @exception ServletException if an invalid parameter value for the
459      * <code>jsp_precompile</code> parameter name is specified
460      */

461     boolean preCompile(HttpServletRequest JavaDoc request)
462         throws ServletException JavaDoc {
463
464         String JavaDoc queryString = request.getQueryString();
465         if (queryString == null)
466             return (false);
467         int start = queryString.indexOf(Constants.PRECOMPILE);
468         if (start < 0)
469             return (false);
470         queryString =
471             queryString.substring(start + Constants.PRECOMPILE.length());
472         if (queryString.length() == 0)
473             return (true); // ?jsp_precompile
474
if (queryString.startsWith("&"))
475             return (true); // ?jsp_precompile&foo=bar...
476
if (!queryString.startsWith("="))
477             return (false); // part of some other name or value
478
int limit = queryString.length();
479         int ampersand = queryString.indexOf("&");
480         if (ampersand > 0)
481             limit = ampersand;
482         String JavaDoc value = queryString.substring(1, limit);
483         if (value.equals("true"))
484             return (true); // ?jsp_precompile=true
485
else if (value.equals("false"))
486             return (true); // ?jsp_precompile=false
487
else
488             throw new ServletException JavaDoc("Cannot have request parameter " +
489                                        Constants.PRECOMPILE + " set to " +
490                                        value);
491     }
492
493     public void destroy() {
494         if (Constants.jasperLog != null)
495             Constants.jasperLog.log("JspServlet.destroy()", Logger.INFORMATION);
496
497         // ensure that only one thread destroys the jsps
498
synchronized (this) {
499             Iterator JavaDoc iter = jsps.values().iterator();
500             while (iter.hasNext())
501                 ((JspServletWrapper)iter.next()).destroy();
502
503             jsps.clear();
504         }
505     }
506
507     /**
508      * This is an embedded class within the JspServlet. Each JSP uri is
509      * associated with a separate wrapper class.
510      */

511     class JspServletWrapper {
512         String JavaDoc jspUri;
513         File JavaDoc jspFile = null;
514         boolean jspFileExists = true;
515
516         String JavaDoc jspClassName = null;
517         Class JavaDoc servletClass = null;
518         Servlet JavaDoc theServlet = null;
519
520         // used for reference counting
521
int refCount = 0;
522         boolean markedForDestroy = false;
523
524         URLClassLoader JavaDoc loader = null;
525         
526         // A volatile on a long guarantees atomic read/write
527
volatile long lastCheckedTime = 0L;
528         volatile long jspLastModifiedTime = 0L;
529
530         // cached compile exception
531
JasperException compileException = null;
532
533         JspServletWrapper(String JavaDoc jspUri)
534             throws ServletException JavaDoc, FileNotFoundException JavaDoc {
535             this.jspUri = jspUri;
536
537             String JavaDoc jspFileName = context.getRealPath(jspUri);
538             if (jspFileName == null)
539                 throw new FileNotFoundException JavaDoc(jspUri);
540
541             jspFile = new File JavaDoc(jspFileName);
542             jspFileExists = jspFile.exists();
543             if (checkJSPmods && !jspFileExists)
544                 throw new FileNotFoundException JavaDoc(jspUri);
545
546             JspMangler mangler = new JspMangler(jspUri, outputDir);
547             this.jspClassName = mangler.getPackageName() + "." +
548                                 mangler.getClassName();
549         }
550
551         public void service(HttpServletRequest JavaDoc request,
552                             HttpServletResponse JavaDoc response)
553             throws ServletException JavaDoc, IOException JavaDoc {
554
555             if (theServlet instanceof SingleThreadModel JavaDoc) {
556                 // sync on the wrapper so that the freshness
557
// of the page is determined right before servicing
558
synchronized (this) {
559                     theServlet.service(request, response);
560                 }
561             } else {
562                 theServlet.service(request, response);
563             }
564         }
565
566         /**
567          * this function checks once every reload interval whether the
568          * JSP file has been modified. Note that this function also sets
569          * jspLastModifiedTime if the file has been modified and hence
570          * is not idempotent.
571          */

572         private boolean isJspFileModified()
573             throws FileNotFoundException JavaDoc {
574
575             boolean res = false;
576
577             long currTime = System.currentTimeMillis();
578             if (currTime >= (reloadInterval + lastCheckedTime)) {
579
580                 long lastModTime = jspFile.lastModified();
581
582                 // check if jsp file exists
583
if (lastModTime == 0L)
584                     throw new FileNotFoundException JavaDoc(jspUri);
585
586                 // check if jsp file has been modified
587
if (lastModTime != jspLastModifiedTime) {
588                     // ensure that only one thread sets the jspLastModifiedTime
589
synchronized (this) {
590                         if (lastModTime != jspLastModifiedTime) {
591                             // set the last modification time so that the jsp
592
// is not considered to be outdated anymore
593
jspLastModifiedTime = lastModTime;
594                             res = true;
595                         }
596                     }
597                 }
598
599                 // update the time the jsp file was checked for being outdated
600
lastCheckedTime = currTime;
601             }
602             return res;
603         }
604
605         /**
606          * This function compiles the JSP if necessary and loads it.
607          */

608         private void loadJSP(HttpServletRequest JavaDoc req,
609                              HttpServletResponse JavaDoc res)
610             throws ServletException JavaDoc, FileNotFoundException JavaDoc {
611
612             if (!checkJSPmods && !jspFileExists) {
613                 // Check if the JSP can be loaded in case it has been
614
// precompiled
615
try {
616                     loadAndInit();
617                 } catch (JasperException ex) {
618                     Constants.jasperLog.log(ex.getMessage(), ex.getRootCause(),
619                                             Logger.INFORMATION);
620                     throw new FileNotFoundException JavaDoc(jspUri);
621                 }
622                 return;
623             }
624
625             // First try context attribute; if that fails then use the
626
// classpath init parameter.
627
String JavaDoc classpath =
628                   (String JavaDoc) context.getAttribute(Constants.SERVLET_CLASSPATH);
629
630             if (debugLogEnabled)
631                 Constants.message("jsp.message.context.classpath",
632                                   new Object JavaDoc[] {
633                                       classpath == null ? "<none>" : classpath
634                                   }, Logger.DEBUG);
635
636             JspCompilationContext ctxt = new JspEngineContext(parentClassLoader,
637                                                   classpath, context, jspUri,
638                                                   false, options,
639                                                   req, res);
640             Compiler JavaDoc compiler = ctxt.createCompiler();
641
642             if (checkJSPmods) {
643                 // set the time that the jsp file has last been checked for
644
// being outdated and the JSP last mod time
645
lastCheckedTime = System.currentTimeMillis();
646                 jspLastModifiedTime = jspFile.lastModified();
647             }
648
649             // compile and load the JSP
650
try {
651                 compiler.compile();
652                 loadAndInit();
653             } catch (JasperException ex) {
654                 compileException = ex;
655             } catch (FileNotFoundException JavaDoc ex) {
656                 compiler.removeGeneratedFiles();
657                 throw ex;
658             } catch (Exception JavaDoc ex) {
659                 compileException = new JasperException(
660                        Constants.getString("jsp.error.unable.compile"), ex);
661             }
662         }
663
664         private void loadAndInit()
665             throws JasperException, ServletException JavaDoc {
666
667             try {
668                 loader = new JasperLoader(loaderURLs, jspClassName,
669                                           parentClassLoader,
670                                           permissionCollection,
671                                           codeSource);
672                 servletClass = loader.loadClass(jspClassName);
673             } catch (ClassNotFoundException JavaDoc cnfe) {
674                 throw new JasperException(
675                     Constants.getString("jsp.error.unable.load"), cnfe);
676             }
677
678             try {
679                 theServlet = (Servlet JavaDoc) servletClass.newInstance();
680             } catch (Exception JavaDoc ex) {
681                 throw new JasperException(ex);
682             }
683             theServlet.init(JspServlet.this.config);
684         }
685
686         // returns the cached compilation exception
687
private JasperException getCompileException() {
688             return compileException;
689         }
690
691         private void incrementRefCount() {
692             refCount++;
693         }
694
695         private void decrementRefCount() {
696             refCount--;
697             if ((refCount == 0) && markedForDestroy)
698                 destroy();
699         }
700
701         // try to destroy the JSP, the actual destroy occurs only when
702
// the refcount goes down to 0
703
private void tryDestroy() {
704             if (refCount == 0)
705                 destroy();
706             markedForDestroy = true;
707         }
708
709         private void destroy() {
710             if (theServlet != null)
711                 theServlet.destroy();
712
713             servletClass = null;
714             theServlet = null;
715
716             jspFile = null;
717             loader = null;
718         }
719     }
720 }
721
Popular Tags