| 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; |
| } |
| } |