Quadcap Embeddable Server

com/quadcap/http/server22/WebClassLoader.java

Go to the documentation of this file.
00001 package com.quadcap.http.server22; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.util.Enumeration; 00042 import java.util.Hashtable; 00043 import java.util.Vector; 00044 00045 import java.io.File; 00046 import java.io.FileOutputStream; 00047 import java.io.InputStream; 00048 import java.io.IOException; 00049 00050 import java.net.URL; 00051 00052 import com.quadcap.io.dir.Directory; 00053 import com.quadcap.io.dir.Entry; 00054 00055 import com.quadcap.io.IO; 00056 00057 import com.quadcap.util.Debug; 00058 00059 00060 /** 00061 * This class implements a JSP class loader 00062 * 00063 * @author Stan Bailes 00064 */ 00065 public class WebClassLoader extends ClassLoader { 00066 File tmpDir; 00067 Directory root; 00068 Vector jars = new Vector(); 00069 00070 public WebClassLoader(Directory root, File tmpDir) { 00071 super(); 00072 this.tmpDir = tmpDir; 00073 this.root = root; 00074 } 00075 00076 public Class loadClass(String name) throws ClassNotFoundException { 00077 return loadClass(name, true); 00078 } 00079 00080 //- //#ifdef JDK11 00081 //- Hashtable cache = new Hashtable(); 00082 //- 00083 //- public Class loadClass(String name, boolean resolve) 00084 //- throws ClassNotFoundException 00085 //- { 00086 //- Class c = (Class)cache.get(name); 00087 //- if (c == null) { 00088 //- c = findClass(name); 00089 //- cache.put(name, c); 00090 //- } 00091 //- if (resolve) 00092 //- resolveClass(c); 00093 //- return c; 00094 //- } 00095 //- 00096 //#endif 00097 00098 public Class findClass(String name) throws ClassNotFoundException { 00099 //#ifdef DEBUG 00100 if (Trace.level() > 1) { 00101 Debug.println("WebClassLoader[" + root + 00102 "].findClass(" + name + ")"); 00103 } 00104 //#endif 00105 byte[] b = loadClassData(name); 00106 return defineClass(name, b, 0, b.length, 00107 this.getClass().getProtectionDomain()); 00108 } 00109 00110 public URL findResource(String name) { 00111 URL url = null; 00112 try { 00113 String fileName = "WEB-INF/classes" + name; 00114 url = root.getURL(fileName); 00115 if (url == null) { 00116 for (int i = 0; url == null && i < jars.size(); i++) { 00117 Directory d = (Directory)jars.elementAt(i); 00118 url = d.getURL(name); 00119 } 00120 } 00121 } catch (Throwable t) { 00122 url = null; 00123 } 00124 return url; 00125 } 00126 00127 private byte[] loadClassData(String name) throws ClassNotFoundException { 00128 try { 00129 Entry classFile = locateClassFile(name); 00130 byte[] b = new byte[(int)(classFile.getSize())]; 00131 InputStream f = classFile.getInputStream(); 00132 IO.readFully(f, b); 00133 f.close(); 00134 return b; 00135 } catch (IOException e) { 00136 throw new ClassNotFoundException("error loading class: " + 00137 e.toString()); 00138 } 00139 } 00140 00141 final Entry locateClassFile(String name) throws ClassNotFoundException { 00142 String className = name.replace('.', '/') + ".class"; 00143 String fileName = "WEB-INF/classes/" + className; 00144 Entry classFile = root.getEntry(fileName); 00145 if (classFile == null) { 00146 for (int i = 0; classFile == null && i < jars.size(); i++) { 00147 Directory d = (Directory)jars.elementAt(i); 00148 classFile = d.getEntry(className); 00149 } 00150 } 00151 if (classFile == null) { 00152 throw new ClassNotFoundException("not found: " + name); 00153 } 00154 return classFile; 00155 } 00156 00157 static int tmpCount = 0; 00158 00159 public String getClassPath() { 00160 StringBuffer sb = new StringBuffer(); 00161 String delim = System.getProperty("path.separator"); 00162 for (int i = 0; i < jars.size(); i++) { 00163 Directory d = (Directory)jars.elementAt(i); 00164 if (i > 0) sb.append(delim); 00165 sb.append(d.getRootPath()); 00166 } 00167 return sb.toString(); 00168 } 00169 00170 final void init() throws IOException { 00171 Enumeration e = root.entries(); 00172 Directory classes = null; 00173 File tmpClasses = null; 00174 while (e.hasMoreElements()) { 00175 String path = e.nextElement().toString(); 00176 if (path.startsWith("WEB-INF/lib/") && path.endsWith(".jar")) { 00177 Directory d = null; 00178 String realPath = root.getRealPath(path); 00179 if (realPath == null) { 00180 Entry entry = root.getEntry(path); 00181 InputStream is = entry.getInputStream(); 00182 File out; 00183 try { 00184 out = new File(tmpDir, 00185 "tmp" + (tmpCount++) + ".jar"); 00186 FileOutputStream os = new FileOutputStream(out); 00187 try { 00188 IO.copyStream(is, os); 00189 } finally { 00190 os.close(); 00191 } 00192 } finally { 00193 is.close(); 00194 } 00195 d = Directory.getDirectory(out); 00196 } else { 00197 d = Directory.getDirectory(new File(realPath)); 00198 } 00199 jars.addElement(d); 00200 } else if (path.startsWith("WEB-INF/classes")) { 00201 if (classes == null) { 00202 String realPath = root.getRealPath("WEB-INF/classes"); 00203 if (realPath == null) { 00204 tmpClasses = new File(tmpDir, "classes"); 00205 tmpClasses.mkdirs(); 00206 classes = Directory.getDirectory(tmpClasses); 00207 } else { 00208 classes = Directory.getDirectory(new File(realPath)); 00209 } 00210 jars.addElement(classes); 00211 } 00212 if (tmpClasses != null) { 00213 String subPath = 00214 path.substring("WEB-INF/classes/".length()); 00215 if (subPath.length() > 0) { 00216 subPath = subPath.replace('/', File.separatorChar); 00217 Entry entry = root.getEntry(path); 00218 File out = new File(tmpClasses, subPath); 00219 if (entry.isDirectory()) { 00220 out.mkdir(); 00221 } else { 00222 InputStream is = entry.getInputStream(); 00223 try { 00224 FileOutputStream os = 00225 new FileOutputStream(out); 00226 try { 00227 IO.copyStream(is, os); 00228 } finally { 00229 os.close(); 00230 } 00231 } finally { 00232 is.close(); 00233 } 00234 } 00235 } 00236 } 00237 } 00238 } 00239 } 00240 } 00241