|
What this is
Other links
The source code
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jasper.servlet;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspFactory;
import org.apache.jasper.Constants;
import org.apache.jasper.EmbededServletOptions;
import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.JspEngineContext;
import org.apache.jasper.Options;
import org.apache.jasper.compiler.Compiler;
import org.apache.jasper.compiler.Mangler;
import org.apache.jasper.runtime.HttpJspBase;
import org.apache.jasper.runtime.JspFactoryImpl;
import org.apache.tomcat.util.log.Log;
/**
* The JSP engine (a.k.a Jasper)!
*
* @author Anil K. Vijendran
* @author Harish Prabandham
* @author Marc A. Saegesser
*/
public class JspServlet extends HttpServlet {
Log loghelper = Log.getLog("JASPER_LOG", "JspServlet");
/**
* Adds reference counting to the JSP implementation servlet. This
* is required to handle the case where a JSP implementation servlet
* is executing requests on several threads when a new implementation
* arrives (the JSP source was updated). We need to wait until all
* the requests complete before calling the implementation servlet's
* destroy() method.
*/
class JspCountedServlet extends HttpServlet
{
private Servlet servlet = null;
private int threadCount = 0;
private boolean destroyed = false;
public JspCountedServlet(Servlet servlet)
{
this.servlet = servlet;
}
public void init(ServletConfig config) throws ServletException, JasperException
{
try{
servlet.init(config);
}catch(NullPointerException e){
throw new JasperException(e);
}
}
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException, JasperException
{
try{
incrementCount();
if(servlet instanceof SingleThreadModel){
synchronized(servlet){
servlet.service(req, res);
}
} else {
servlet.service(req, res);
}
}catch(NullPointerException e){
throw new JasperException(e);
}finally{
decrementCount();
}
}
/*
* Flags this servlet for destrction once all active requests have completed.
* After calling this method it is invalid to call service().
*/
public void destroy()
{
destroyed = true;
if(getCount() == 0)
doDestroy();
}
private void doDestroy()
{
try{
servlet.destroy();
servlet = null;
}catch(NullPointerException e){
}
}
private synchronized void incrementCount()
{
threadCount++;
}
private synchronized void decrementCount()
{
if(threadCount <= 0){
Constants.message("jsp.error.badcount", Log.ERROR);
return;
}
--threadCount;
if(threadCount == 0 && destroyed)
doDestroy();
}
private synchronized int getCount()
{
return threadCount;
}
}
class JspServletWrapper {
JspCountedServlet theServlet;
String jspUri;
boolean isErrorPage;
Class servletClass;
JspServletWrapper(String jspUri, boolean isErrorPage) {
this.jspUri = jspUri;
this.isErrorPage = isErrorPage;
this.theServlet = null;
}
public synchronized void instantiateServlet(Class servletClass) throws JasperException, ServletException
{
try {
this.servletClass = servletClass;
// If we're replacing an existing JSP Implementation class, then
// schedule it for destruction
if(theServlet != null)
theServlet.destroy();
// Create an instance of the JSP implementation class
Servlet servlet = (Servlet) servletClass.newInstance();
// Set the class loader
if(servlet instanceof HttpJspBase) {
((HttpJspBase)servlet).setClassLoader(JspServlet.this.parentClassLoader);
}
// Wrap this servlet in a counted servlet
theServlet = new JspCountedServlet(servlet);
// Call the JSP Implementation servlet's init() method. This
// will cause the page's jspInit() method to be invoked if one exists.
theServlet.init(JspServlet.this.config);
} catch(Exception ex) {
throw new JasperException(ex);
}
}
public synchronized Servlet getServlet()
{
return theServlet;
}
public synchronized boolean isInstantiated()
{
return theServlet != null;
}
private void loadIfNecessary(HttpServletRequest req, HttpServletResponse res)
throws JasperException, ServletException, FileNotFoundException
{
// First try context attribute; if that fails then use the
// classpath init parameter.
// Should I try to concatenate them if both are non-null?
String cp = (String) context.getAttribute(Constants.SERVLET_CLASSPATH);
String accordingto;
if (cp == null || cp.equals("")) {
accordingto = "according to the init parameter";
cp = options.getClassPath();
} else
accordingto = "according to the Servlet Engine";
Constants.message("jsp.message.cp_is",
new Object[] {
accordingto,
cp == null ? "" : cp
},
Log.INFORMATION);
loadJSP(jspUri, cp, isErrorPage, req, res);
}
public void service(HttpServletRequest request,
HttpServletResponse response,
boolean precompile)
throws ServletException, IOException, FileNotFoundException
{
Servlet servlet = null;
try {
loadIfNecessary(request, response);
servlet = getServlet();
// If a page is to only to be precompiled return.
if (precompile)
return;
if (servlet instanceof SingleThreadModel) {
// sync on the wrapper so that the freshness
// of the page is determined right before servicing
synchronized (this) {
servlet.service(request, response);
}
} else {
servlet.service(request, response);
}
} catch (FileNotFoundException ex) {
try {
if (insecure_TMI) {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
Constants.getString
("jsp.error.file.not.found.TMI",
new Object[] {
ex.getMessage()
}));
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND,
Constants.getString
("jsp.error.file.not.found",
new Object[] {
// Too Much Information -- ex.getMessage()
}));
}
} catch (IllegalStateException ise) {
// logs are presumed to be secure, thus the TMI info can be logged
Constants.jasperLog.log(Constants.getString
("jsp.error.file.not.found.TMI",
new Object[] {
ex.getMessage()
}), ex,
Log.ERROR);
// rethrow FileNotFoundException so someone higher up can handle
if (insecure_TMI)
throw ex;
else
throw new FileNotFoundException(Constants.getString
("jsp.error.file.not.found",
new Object[] {
// Too Much Information -- ex.getMessage()
}));
}
return;
}
}
public void destroy()
{
if(theServlet != null)
theServlet.destroy();
}
}
protected ServletContext context = null;
protected Hashtable jsps = new Hashtable();
// protected Hashtable loadedJSPs = new Hashtable();
protected ServletConfig config;
protected JasperLoader loader;
protected Options options;
protected ClassLoader parentClassLoader;
protected ServletEngine engine;
protected String serverInfo;
/** Set to true to provide Too Much Information on errors */
private final boolean insecure_TMI = false;
static boolean firstTime = true;
static boolean jdk12=false;
static {
try {
Class.forName( "java.security.PrivilegedAction" );
jdk12=true;
} catch(Throwable ex ) {
}
}
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
this.config = config;
this.context = config.getServletContext();
this.serverInfo = context.getServerInfo();
options = new EmbededServletOptions(config, context);
parentClassLoader = (ClassLoader) context.getAttribute(Constants.SERVLET_CLASS_LOADER);
if (parentClassLoader == null)
parentClassLoader = this.getClass().getClassLoader();
// getClass().getClassLoader() returns null in JDK 1.1.6/1.1.8
if (parentClassLoader != null) {
Constants.message("jsp.message.parent_class_loader_is",
new Object[] {
parentClassLoader.toString()
}, Log.DEBUG);
}
else {
Constants.message("jsp.message.parent_class_loader_is",
new Object[] {
"
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.