001: package com.quadcap.http.server22;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.util.Enumeration;
042: import java.util.Hashtable;
043: import java.util.Vector;
044:
045: import java.io.File;
046: import java.io.FileOutputStream;
047: import java.io.InputStream;
048: import java.io.IOException;
049:
050: import java.net.URL;
051:
052: import com.quadcap.io.dir.Directory;
053: import com.quadcap.io.dir.Entry;
054:
055: import com.quadcap.io.IO;
056:
057: import com.quadcap.util.Debug;
058:
059: /**
060: * This class implements a JSP class loader
061: *
062: * @author Stan Bailes
063: */
064: public class WebClassLoader extends ClassLoader {
065: File tmpDir;
066: Directory root;
067: Vector jars = new Vector();
068:
069: public WebClassLoader(Directory root, File tmpDir) {
070: super ();
071: this .tmpDir = tmpDir;
072: this .root = root;
073: }
074:
075: public Class loadClass(String name) throws ClassNotFoundException {
076: return loadClass(name, true);
077: }
078:
079: //- //#ifdef JDK11
080: //- Hashtable cache = new Hashtable();
081: //-
082: //- public Class loadClass(String name, boolean resolve)
083: //- throws ClassNotFoundException
084: //- {
085: //- Class c = (Class)cache.get(name);
086: //- if (c == null) {
087: //- c = findClass(name);
088: //- cache.put(name, c);
089: //- }
090: //- if (resolve)
091: //- resolveClass(c);
092: //- return c;
093: //- }
094: //-
095: //#endif
096:
097: public Class findClass(String name) throws ClassNotFoundException {
098: //#ifdef DEBUG
099: if (Trace.level() > 1) {
100: Debug.println("WebClassLoader[" + root + "].findClass("
101: + name + ")");
102: }
103: //#endif
104: byte[] b = loadClassData(name);
105: return defineClass(name, b, 0, b.length, this .getClass()
106: .getProtectionDomain());
107: }
108:
109: public URL findResource(String name) {
110: URL url = null;
111: try {
112: String fileName = "WEB-INF/classes" + name;
113: url = root.getURL(fileName);
114: if (url == null) {
115: for (int i = 0; url == null && i < jars.size(); i++) {
116: Directory d = (Directory) jars.elementAt(i);
117: url = d.getURL(name);
118: }
119: }
120: } catch (Throwable t) {
121: url = null;
122: }
123: return url;
124: }
125:
126: private byte[] loadClassData(String name)
127: throws ClassNotFoundException {
128: try {
129: Entry classFile = locateClassFile(name);
130: byte[] b = new byte[(int) (classFile.getSize())];
131: InputStream f = classFile.getInputStream();
132: IO.readFully(f, b);
133: f.close();
134: return b;
135: } catch (IOException e) {
136: throw new ClassNotFoundException("error loading class: "
137: + e.toString());
138: }
139: }
140:
141: final Entry locateClassFile(String name)
142: throws ClassNotFoundException {
143: String className = name.replace('.', '/') + ".class";
144: String fileName = "WEB-INF/classes/" + className;
145: Entry classFile = root.getEntry(fileName);
146: if (classFile == null) {
147: for (int i = 0; classFile == null && i < jars.size(); i++) {
148: Directory d = (Directory) jars.elementAt(i);
149: classFile = d.getEntry(className);
150: }
151: }
152: if (classFile == null) {
153: throw new ClassNotFoundException("not found: " + name);
154: }
155: return classFile;
156: }
157:
158: static int tmpCount = 0;
159:
160: public String getClassPath() {
161: StringBuffer sb = new StringBuffer();
162: String delim = System.getProperty("path.separator");
163: for (int i = 0; i < jars.size(); i++) {
164: Directory d = (Directory) jars.elementAt(i);
165: if (i > 0)
166: sb.append(delim);
167: sb.append(d.getRootPath());
168: }
169: return sb.toString();
170: }
171:
172: final void init() throws IOException {
173: Enumeration e = root.entries();
174: Directory classes = null;
175: File tmpClasses = null;
176: while (e.hasMoreElements()) {
177: String path = e.nextElement().toString();
178: if (path.startsWith("WEB-INF/lib/")
179: && path.endsWith(".jar")) {
180: Directory d = null;
181: String realPath = root.getRealPath(path);
182: if (realPath == null) {
183: Entry entry = root.getEntry(path);
184: InputStream is = entry.getInputStream();
185: File out;
186: try {
187: out = new File(tmpDir, "tmp" + (tmpCount++)
188: + ".jar");
189: FileOutputStream os = new FileOutputStream(out);
190: try {
191: IO.copyStream(is, os);
192: } finally {
193: os.close();
194: }
195: } finally {
196: is.close();
197: }
198: d = Directory.getDirectory(out);
199: } else {
200: d = Directory.getDirectory(new File(realPath));
201: }
202: jars.addElement(d);
203: } else if (path.startsWith("WEB-INF/classes")) {
204: if (classes == null) {
205: String realPath = root
206: .getRealPath("WEB-INF/classes");
207: if (realPath == null) {
208: tmpClasses = new File(tmpDir, "classes");
209: tmpClasses.mkdirs();
210: classes = Directory.getDirectory(tmpClasses);
211: } else {
212: classes = Directory.getDirectory(new File(
213: realPath));
214: }
215: jars.addElement(classes);
216: }
217: if (tmpClasses != null) {
218: String subPath = path.substring("WEB-INF/classes/"
219: .length());
220: if (subPath.length() > 0) {
221: subPath = subPath.replace('/',
222: File.separatorChar);
223: Entry entry = root.getEntry(path);
224: File out = new File(tmpClasses, subPath);
225: if (entry.isDirectory()) {
226: out.mkdir();
227: } else {
228: InputStream is = entry.getInputStream();
229: try {
230: FileOutputStream os = new FileOutputStream(
231: out);
232: try {
233: IO.copyStream(is, os);
234: } finally {
235: os.close();
236: }
237: } finally {
238: is.close();
239: }
240: }
241: }
242: }
243: }
244: }
245: }
246: }
|