001: /**
002: * $RCSfile: VAClassLoader.java,v $
003: * @creation 01/02/00
004: * @modification $Date: 2005/03/06 23:04:17 $
005: */package com.memoire.vainstall;
006:
007: import java.io.ByteArrayOutputStream;
008: import java.io.File;
009: import java.io.FileInputStream;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.net.MalformedURLException;
013: import java.net.URL;
014: import java.util.Hashtable;
015: import java.util.jar.JarInputStream;
016: import java.util.zip.ZipEntry;
017:
018: /**
019: * @version $Id: VAClassLoader.java,v 1.4 2005/03/06 23:04:17 deniger Exp $
020: * @author Axel von Arnim
021: */
022:
023: public class VAClassLoader extends ClassLoader {
024: public final static boolean DEBUG = "yes".equals(System
025: .getProperty("DEBUG"));
026:
027: /**
028: * format ex. ("com.ice.util.UserProperties.class",byte[] data)
029: */
030: private Hashtable cache_;
031:
032: private long offset_;
033: private File jarfile_;
034: private File dllFile_;
035:
036: /**
037: * format ex. ("com.ice.util.UserProperties",Class)
038: */
039: private Hashtable classes = new Hashtable();
040:
041: public VAClassLoader(File jarfile, Long offset) {
042: super ();
043: offset_ = offset.longValue();
044: jarfile_ = jarfile;
045: JarInputStream jar = null;
046: try {
047: cache_ = new Hashtable();
048: printDebug("VAClassLoader: loading classes from "
049: + jarfile.getName() + " (offset " + offset_
050: + ")...");
051: FileInputStream stream = new FileInputStream(jarfile_);
052: stream.skip(offset_);
053: jar = new JarInputStream(stream);
054: ZipEntry entry = jar.getNextEntry();
055: byte[] data = null;
056: Class c = null;
057: while (entry != null) {
058: String entryName = entry.getName();
059: if (entryName.endsWith(".class")) {
060:
061: byte[] buffer = new byte[2048];
062: ByteArrayOutputStream bos = new ByteArrayOutputStream();
063: while (true) {
064: int read = jar.read(buffer);
065: if (read == -1)
066: break;
067: bos.write(buffer, 0, read);
068: }
069: data = bos.toByteArray();
070: bos.close();
071: jar.closeEntry();
072: String className = entryName.replace('/', '.'); // .substring(0, entryName.lastIndexOf('.'));
073: printDebug(" className=" + className + " size="
074: + data.length);
075:
076: byte[] toCache = new byte[data.length];
077: System.arraycopy(data, 0, toCache, 0, data.length);
078: cache_.put(className, data);
079:
080: }
081: entry = jar.getNextEntry();
082: }
083: } catch (Throwable t) {
084: t.printStackTrace();
085: } finally {
086: printDebug(" closing jarFile.");
087: if (jar != null)
088: try {
089: jar.close();
090: } catch (IOException e) {
091: System.err.println(e);
092: }
093: }
094: }
095:
096: public Class loadClass(String className)
097: throws ClassNotFoundException {
098: return (loadClass(className, true));
099: }
100:
101: public synchronized Class loadClass(String className,
102: boolean resolveIt) throws ClassNotFoundException {
103:
104: Class result;
105: byte[] classBytes;
106:
107: //----- Check our local cache of classes
108: result = (Class) classes.get(className);
109: if (result != null) {
110: return result;
111: }
112:
113: //----- Check with the primordial class loader
114: try {
115: result = super .findSystemClass(className);
116: return result;
117: } catch (ClassNotFoundException e) {
118: }
119:
120: //----- Try to load it from preferred source
121: // Note loadClassBytes() is an abstract method
122: printDebug(className);
123: classBytes = loadClassBytes(className);
124: if (classBytes == null) {
125: throw new ClassNotFoundException();
126: }
127:
128: //----- Define it (parse the class file)
129: result = defineClass(className, classBytes, 0,
130: classBytes.length);
131: if (result == null) {
132: throw new ClassFormatError();
133: }
134:
135: //----- Resolve if necessary
136: if (resolveIt)
137: resolveClass(result);
138:
139: // Done
140: classes.put(className, result);
141: return result;
142: }
143:
144: public synchronized InputStream getResourceAsStream(String name) {
145: InputStream res = null;
146: JarInputStream jar = null;
147: try {
148: printDebug("VAClassLoader: loading resource " + name);
149: FileInputStream stream = new FileInputStream(jarfile_);
150: stream.skip(offset_);
151: jar = new JarInputStream(stream);
152: ZipEntry entry = jar.getNextEntry();
153: while ((entry != null) && (!entry.getName().equals(name)))
154: entry = jar.getNextEntry();
155: if (entry != null) {
156: res = jar;
157: }
158: } catch (IOException t) {
159: System.err.println(t);
160: printDebug(" closing jarFile.");
161: if (jar != null)
162: try {
163: jar.close();
164: } catch (IOException e) {
165: System.err.println(e);
166: }
167: }
168: if (res == null)
169: printDebug(" not found");
170: else
171: printDebug(" OK");
172: return res;
173: }
174:
175: public synchronized URL getResource(String name) {
176: URL res = null;
177: try {
178: printDebug("VAClassLoader: loading resource URL " + name);
179: String jarUrl = jarfile_.toURL().toString();
180: jarUrl = "jar:" + jarUrl + "!" + name;
181: res = new URL(jarUrl);
182: } catch (MalformedURLException ex) {
183: printDebug(" null URL");
184: res = null;
185: }
186: if (res == null)
187: printDebug(" not found");
188: else
189: printDebug(" OK");
190: return res;
191: }
192:
193: protected void finalize() {
194: if (dllFile_.exists())
195: dllFile_.delete();
196: }
197:
198: public static void printDebug(String msg) {
199: if (DEBUG)
200: System.err.println(msg);
201: }
202:
203: protected byte[] loadClassBytes(String className) {
204: // Support the MultiClassLoader's class name munging facility.
205: className = formatClassName(className);
206: printDebug("Trying to fetch=" + className);
207: // Attempt to get the class data from the JarResource.
208: return (byte[]) cache_.get(className);
209: }
210:
211: protected String formatClassName(String className) {
212: return className + ".class";
213: }
214:
215: }
|