⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jspinterceptor.java

📁 低版本的tomcat 对于有些老版本的应用还真的需要老版的中间件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */ 
package org.apache.tomcat.request;

import javax.servlet.*;
import javax.servlet.http.*;

import javax.servlet.jsp.HttpJspPage;
import javax.servlet.jsp.JspFactory;

import java.util.*;
import java.io.*;

import org.apache.jasper.*;
import org.apache.jasper.Constants;
import org.apache.jasper.runtime.*;
import org.apache.jasper.compiler.*;
import org.apache.tomcat.logging.Logger;
import org.apache.jasper.compiler.Compiler;
import org.apache.tomcat.core.*;

/**
 * Plug in the JSP engine (a.k.a Jasper)! 
 *
 * @author Anil K. Vijendran
 * @author Harish Prabandham
 * @author Costin Manolache
 */
public class JspInterceptor extends BaseInterceptor {
    int jspInfoNOTE;

    public void engineInit(ContextManager cm )
	throws TomcatException
    {
	super.engineInit(cm);
	jspInfoNOTE=cm.getNoteId( ContextManager.HANDLER_NOTE,
				  "tomcat.jspInfoNote");
    }
    
    public void contextInit(Context ctx)
	throws TomcatException 
    {
	JspFactory.setDefaultFactory(new JspFactoryImpl());
	ctx.getServletLoader().addRepository( ctx.getWorkDir(),
					      ctx.getProtectionDomain());
    }

    public void preServletInit( Context ctx, ServletWrapper sw )
	throws TomcatException
    {
	Servlet theServlet = sw.getServlet();
	if (theServlet instanceof HttpJspBase)  {
	    if( debug > 0 )
		log( "PreServletInit: HttpJspBase.setParentClassLoader" + sw );
	    HttpJspBase h = (HttpJspBase) theServlet;
	    h.setClassLoader(ctx.getServletLoader().getClassLoader());
	}
    }

    public int requestMap( Request req ) {
	ServletWrapper wrapper=req.getWrapper();
	if( wrapper!=null && ! "jsp".equals( wrapper.getName())
	    && wrapper.getPath() == null)
	    return 0;

	// XXX jsp handler is still needed
	if( wrapper==null )
	    return 0;
	
	Context ctx= req.getContext();

	// If this Wrapper was already used, we have all the info
	JspInfo jspInfo=(JspInfo)wrapper.getNote( jspInfoNOTE );
	if( jspInfo == null ) {
	    if( debug > 0 ) log("New jsp page - no jspInfo ");
	    jspInfo=new JspInfo(req);
	    mapJspPage( req, jspInfo, jspInfo.uri, jspInfo.fullClassN);
	}

	if( jspInfo.jspSource.lastModified() 
	    > jspInfo.compileTime ) {
	    //XXX 	    destroy();
	    
	    // jump version number - the file needs to
	    // be recompiled, and we don't want a reload
	    jspInfo.nextVersion();
	    compile( req, jspInfo );
	    mapJspPage( req , jspInfo, jspInfo.uri, jspInfo.fullClassN);
	}

	return 0;
    }

    /** Add an exact map that will avoid *.jsp mapping and intermediate
     *  steps
     */
    void mapJspPage( Request req, JspInfo jspInfo,
		     String servletName, String classN )
    {
	Context ctx=req.getContext();
	ServletWrapper wrapper=null;
	String servletPath=servletName;
	// add the mapping - it's a "invoker" map ( i.e. it
	// can be removed to keep memory under control.
	// The memory usage is smaller than JspSerlvet anyway, but
	// can be further improved.
	try {
	    wrapper=ctx.getServletByName( servletName );
	    // We may want to replace the class and reset it if changed
	    
	    if( wrapper==null ) {
		wrapper=ctx.addServlet( servletName, classN );
		wrapper.setPath( servletName );
		wrapper.setOrigin( ServletWrapper.ORIGIN_INVOKER );
		
		ctx.addServletMapping( servletPath ,
				       servletPath );
		log( "Added mapping " + servletPath +
		     " path=" + servletPath );
	    }
	    wrapper.setServletClass( classN );
	    
	    wrapper.setNote( jspInfoNOTE, jspInfo );
	} catch( TomcatException ex ) {
	    ex.printStackTrace();
	    return ;
	}
	req.setWrapper( wrapper );
	if( debug>0) log("Wrapper " + wrapper);
    }

    /** Convert the .jsp file to a java file, then compile it to class
     */
    void compile(Request req, JspInfo jspInfo ) {
	log( "Compiling " + jspInfo.realClassPath);
	try {
	    // make sure we have the directories
	    File dir=new File( jspInfo.outputDir + "/" + jspInfo.pkgDir);
	    dir.mkdirs();
	    
	    JspMangler mangler= new JspMangler(jspInfo);
	    TomcatOptions options=new TomcatOptions();
	    JspEngineContext1 ctxt = new JspEngineContext1(req, mangler);
	    ctxt.setOptions( options );
	    
	    Compiler compiler=new Compiler(ctxt);
	    compiler.setMangler( mangler );
		
	    // we will compile ourself
	    compiler.setJavaCompiler( null );
	    
	    synchronized ( this ) {
		compiler.compile();
	    }
	    
	    javac( createJavaCompiler( options ), ctxt, mangler );
	    
	    if(debug>0)log( "Compiled to " + jspInfo.realClassPath );
	    jspInfo.touch();
	} catch( Exception ex ) {
	    ex.printStackTrace();
	}
    }
    
    String javaEncoding = "UTF8";           // perhaps debatable?
    static String sep = System.getProperty("path.separator");
    
    /** Compile a java to class. This should be moved to util, togheter
	with JavaCompiler - it's a general purpose code, no need to
	keep it part of jasper
    */
    public void javac(JavaCompiler javac, JspEngineContext1 ctxt,
		      Mangler mangler)
	throws JasperException
    {

        javac.setEncoding(javaEncoding);
	String cp=System.getProperty("java.class.path")+ sep + 
	    ctxt.getClassPath() + sep + ctxt.getOutputDir();
        javac.setClasspath( cp );
	if( debug>0) log( "ClassPath " + cp);
	
	ByteArrayOutputStream out = new ByteArrayOutputStream (256);
	javac.setOutputDir(ctxt.getOutputDir());
        javac.setMsgOutput(out);

	String javaFileName = mangler.getJavaFileName();
	/**
         * Execute the compiler
         */
        boolean status = javac.compile(javaFileName);

        if (!ctxt.keepGenerated()) {
            File javaFile = new File(javaFileName);
            javaFile.delete();
        }
    
        if (status == false) {
            String msg = out.toString ();
            throw new JasperException("Unable to compile "
                                      + msg);
        }
    }

    /** tool for customizing javac
     */
    public JavaCompiler createJavaCompiler(Options options)
	throws JasperException
    {
	String compilerPath = options.getJspCompilerPath();
	Class jspCompilerPlugin = options.getJspCompilerPlugin();
        JavaCompiler javac;

	if (jspCompilerPlugin != null) {
            try {
                javac = (JavaCompiler) jspCompilerPlugin.newInstance();
            } catch (Exception ex) {
		Constants.message("jsp.warning.compiler.class.cantcreate",
				  new Object[] { jspCompilerPlugin, ex }, 
				  Logger.FATAL);
                javac = new SunJavaCompiler();
	    }
	} else {
            javac = new SunJavaCompiler();
	}

        if (compilerPath != null)
            javac.setCompilerPath(compilerPath);

	return javac;
    }

    // XXX need to implement precompile
    private void precompile() {
	//         String qString = request.getQueryString();
	//          if (qString != null &&
	// 		 (qString.startsWith(Constants.PRECOMPILE) ||
	// 		  qString.indexOf("&" + Constants.PRECOMPILE)
	// 		  != -1))
	//             precompile = true;
    }

}

/** Given a URL, generate pkg, class name, etc.
    This is an internal ( private ) object, we'll add get/set
    later ( after we pass the experimental stage) 
 */
class JspInfo {
    String uri; // path 

    int version; // version

    String pkg;
    String pkgDir;
    String baseClassN;
    String fullClassN; // package.classN
    String classN; // no package
    String ext;

    String outputDir;
    String javaFilePath; // full path to the generated java file
    String realClassPath; // full path to the compiled java class
    String mapPath; // In even of server reload, keep last version

    File jspSource; // used to avoid File allocation for lastModified
    long compileTime;// tstamp - avoid one extra access

    JspInfo( Request req ) {
	init( req );
    }

    public String toString() {
	return uri +" " + version;
    }  

    /** Update compile time
     */
    public void touch() {
	compileTime=System.currentTimeMillis();
    }

    /** A change was detected, move to a new class name
     */
    public void nextVersion() {
	version++;
	updateVersionedPaths();
    }

    /** Update all paths that contain version number
     */
    void updateVersionedPaths() {
	classN = baseClassN + "_" + version;
	realClassPath = outputDir + "/" + pkgDir + "/" +
	    classN + ".class";
	javaFilePath = outputDir + "/" + pkgDir + "/" +
	    classN + ".java";
	fullClassN = pkg +"." + classN;
	
// 	System.out.println("ClassN=" + classN +
// 			   " realClassPath=" + realClassPath +
// 			   " javaFilePath=" + javaFilePath +
// 			   " fullClassN =" + fullClassN);
	writeVersion();
	// save to mapFile 
    }

    /** Compute various names used
     */
    void init(Request req ) {
	// 	String includeUri 
	// 	    = (String) req.getAttribute(Constants.INC_SERVLET_PATH);
	uri=req.getServletPath();
	Context ctx=req.getContext();
	outputDir = ctx.getWorkDir().getAbsolutePath();
	String jspFilePath=ctx.getRealPath( uri );
	jspSource = new File(jspFilePath);
	
	// extension
	int lastComp=uri.lastIndexOf(  "/" );
	String endUnproc=null;
	if( lastComp > 0 ) {
	    // has package
	    pkgDir=uri.substring( 1, lastComp );
	    endUnproc=uri.substring( lastComp+1 );
	} else {
	    endUnproc=uri.substring( 1 );
	}

	if( pkgDir!=null ) {
	    pkgDir=pkgDir.replace('.', '_');
	    pkg=pkgDir.replace('/', '.');
	    //	    pkgDir=pkgDir.replace('/', File.separator );
	}
	
	int extIdx=endUnproc.lastIndexOf( "." );

	if( extIdx>=0 ) {
	    baseClassN=endUnproc.substring( 0, extIdx );
	    ext=endUnproc.substring( extIdx );
	} else {
	    baseClassN=endUnproc;
	}
	// XXX insert "mangle" to make names safer

	mapPath = outputDir + "/" + pkgDir + "/" + baseClassN + ".ver";
	File mapFile=new File(mapPath);
	if( mapFile.exists() ) {
	    // read version from file
	    readVersion();
	    updateVersionedPaths();
	    updateCompileTime();
	} else {
	    version=0;
	    updateVersionedPaths();
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -