
org.apache.jasper.servlet.JasperLoader Maven / Gradle / Ivy
/*
* 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.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import org.apache.jasper.Constants;
/**
* This is a class loader that loads JSP files as though they were
* Java classes. It calls the compiler to compile the JSP file into a
* servlet and then loads the generated class.
*
* @author Anil K. Vijendran
* @author Harish Prabandham
*/
public class JasperLoader extends URLClassLoader {
protected class PrivilegedLoadClass
implements PrivilegedAction {
PrivilegedLoadClass() {
}
public Object run() {
return Thread.currentThread().getContextClassLoader();
}
}
private PermissionCollection permissionCollection = null;
private CodeSource codeSource = null;
private String className = null;
private ClassLoader parent = null;
private SecurityManager securityManager = null;
private PrivilegedLoadClass privLoadClass = null;
public JasperLoader(URL [] urls, String className, ClassLoader parent,
PermissionCollection permissionCollection,
CodeSource codeSource) {
super(urls,parent);
this.permissionCollection = permissionCollection;
this.codeSource = codeSource;
this.className = className;
this.parent = parent;
this.privLoadClass = new PrivilegedLoadClass();
this.securityManager = System.getSecurityManager();
}
/**
* Load the class with the specified name. This method searches for
* classes in the same manner as loadClass(String, boolean)
* with false
as the second argument.
*
* @param name Name of the class to be loaded
*
* @exception ClassNotFoundException if the class was not found
*/
public Class loadClass(String name) throws ClassNotFoundException {
return (loadClass(name, false));
}
/**
* Load the class with the specified name, searching using the following
* algorithm until it finds and returns the class. If the class cannot
* be found, returns ClassNotFoundException
.
*
* - Call
findLoadedClass(String)
to check if the
* class has already been loaded. If it has, the same
* Class
object is returned.
* - If the
delegate
property is set to true
,
* call the loadClass()
method of the parent class
* loader, if any.
* - Call
findClass()
to find this class in our locally
* defined repositories.
* - Call the
loadClass()
method of our parent
* class loader, if any.
*
* If the class was found using the above steps, and the
* resolve
flag is true
, this method will then
* call resolveClass(Class)
on the resulting Class object.
*
* @param name Name of the class to be loaded
* @param resolve If true
then resolve the class
*
* @exception ClassNotFoundException if the class was not found
*/
public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
Class clazz = null;
// (0) Check our previously loaded class cache
clazz = findLoadedClass(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return (clazz);
}
// (.5) Permission to access this class when using a SecurityManager
int dot = name.lastIndexOf('.');
if (securityManager != null) {
if (dot >= 0) {
try {
securityManager.checkPackageAccess(name.substring(0,dot));
} catch (SecurityException se) {
String error = "Security Violation, attempt to use " +
"Restricted Class: " + name;
System.out.println(error);
throw new ClassNotFoundException(error);
}
}
}
// Class is in a package, delegate to thread context class loader
if( !name.startsWith(Constants.JSP_PACKAGE_NAME) ) {
ClassLoader classLoader = null;
if (securityManager != null) {
classLoader = (ClassLoader)AccessController.doPrivileged(privLoadClass);
} else {
classLoader = Thread.currentThread().getContextClassLoader();
}
clazz = classLoader.loadClass(name);
if( resolve )
resolveClass(clazz);
return clazz;
}
// Only load classes for this JSP page
if( name.startsWith(className) ) {
String classFile = name.substring(Constants.JSP_PACKAGE_NAME.length()+1) +
".class";
byte [] cdata = loadClassDataFromFile(classFile);
if( cdata == null )
throw new ClassNotFoundException(name);
if( securityManager != null ) {
ProtectionDomain pd = new ProtectionDomain(
codeSource,permissionCollection);
clazz = defineClass(name,cdata,0,cdata.length,pd);
} else {
clazz = defineClass(name,cdata,0,cdata.length);
}
if( clazz != null ) {
if( resolve )
resolveClass(clazz);
return clazz;
}
}
throw new ClassNotFoundException(name);
}
/**
* Get the Permissions for a CodeSource.
*
* Since this ClassLoader is only used for a JSP page in
* a web application context, we just return our preset
* PermissionCollection for the web app context.
*
* @param codeSource where the code was loaded from
* @return PermissionCollection for CodeSource
*/
protected final PermissionCollection getPermissions(CodeSource codeSource) {
return permissionCollection;
}
/**
* Load JSP class data from file.
*/
protected byte[] loadClassDataFromFile(String fileName) {
byte[] classBytes = null;
try {
InputStream in = getResourceAsStream(fileName);
if (in == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
for(int i = 0; (i = in.read(buf)) != -1; )
baos.write(buf, 0, i);
in.close();
baos.close();
classBytes = baos.toByteArray();
} catch(Exception ex) {
ex.printStackTrace();
return null;
}
return classBytes;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy