blob: 5c30e042021bd9ee2cebb1e208701fbe409077b1 [file] [log] [blame]
package org.eclipse.epp.installer.launcher;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.epp.installer.archive.Archive;
import org.eclipse.epp.installer.archive.ArchiveEntry;
/**
* <p>
* Copyright (c) 2006, Instantiations, Inc.<br>
* All Rights Reserved
*/
public class SFXClassLoader extends ClassLoader {
private final static int BUFFER_SIZE = 4096;
private Map libraryMap;
private List classPath;
public SFXClassLoader() {
libraryMap = new HashMap();
classPath = new ArrayList();
}
protected String findLibrary(String libname) {
String path = (String)libraryMap.get(libname);
if(path != null) {
return path;
}
else {
return super.findLibrary(libname);
}
}
void addClassPath(Archive archive, String entry) {
try {
classPath.add(Archives.getSubArchive(archive, entry.split("!")));
} catch (IOException e) {
e.printStackTrace();
}
}
void mapLibrary(String libraryName, String path) {
if(libraryMap.get(libraryName) != null) {
System.err.println("warning: library already mapped, check INSTALLER.MF");
}
libraryMap.put(libraryName, path);
}
public InputStream getResourceAsStream(String name) {
for(int i=0;i<classPath.size();i++) {
Archive archive = (Archive) classPath.get(i);
InputStream is = null;
try {
ArchiveEntry entry = archive.getEntry(name);
if(entry != null) {
is = archive.getInputStream(entry);
return is;
}
} catch(IOException e) {
e.printStackTrace();
}
}
return super.getResourceAsStream(name);
}
protected Class findClass(String name) throws ClassNotFoundException {
for( int i = classPath.size() - 1; i >= 0; i-- ) {
Archive archive = (Archive)classPath.get(i);
String path = name.replace('.', '/') + ".class";
InputStream is = null;
try {
ArchiveEntry entry = archive.getEntry(path);
if(entry == null) continue;
is = archive.getInputStream(entry);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = is.read(buf)) != -1) {
bos.write(buf, 0, n);
}
byte[] clazz = bos.toByteArray();
return defineClass(name, clazz, 0, clazz.length);
} catch(IOException e) {
e.printStackTrace();
}
}
return super.findClass(name);
}
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
// if not loaded, search the local (child) resources
if (c == null) {
try {
c = findClass(name);
} catch(ClassNotFoundException cnfe) {
// ignore
}
}
// delegate to parent
if (c == null) {
if (getParent() != null) {
c = getParent().loadClass(name);
} else {
c = getSystemClassLoader().loadClass(name);
}
}
// Resolve the class, if required
if (resolve) {
resolveClass(c);
}
return c;
}
}