package com.venky.swf.routing; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import com.venky.core.io.ByteArrayInputStream; import com.venky.core.string.StringUtil; import com.venky.swf.routing.Config; public class SWFClassLoader extends ClassLoader { private Set<File> pathsHandled = new HashSet<File>(); public SWFClassLoader(ClassLoader parent) { super(parent); List<URL> watchedUrls = Config.instance().getResourceBaseUrls(); for (URL watchedUrl : watchedUrls) { pathsHandled.add(getFile(watchedUrl, "")); } } public File getFile(URL watchedUrl, String loc) { String path = watchedUrl.getPath(); if (watchedUrl.getProtocol().equals("jar")) { return new File(path.substring("file:".length(), path.lastIndexOf("!"))); } else if (watchedUrl.getProtocol().equals("file")) { return new File(path.substring(0, path.length() - loc.length())); } else { throw new RuntimeException("Don't know how to load Class from url:" + watchedUrl.toString()); } } public Class<?> loadClass(String name) throws ClassNotFoundException { if (name.startsWith("com.venky.swf.routing")) { return super.loadClass(name); }else if (name.startsWith("com.venky.swf.util.SWFLogger") || name.startsWith("com.venky.core.log")) { return super.loadClass(name); }else if (name.startsWith("com.venky.swf") && name.substring(name.lastIndexOf(".") + 1).startsWith("_I")) { return super.loadClass(name); } String loc = name.replace('.', '/') + ".class"; for (File file : pathsHandled){ try { byte[] clazzByte = null; if (file.isDirectory()){ File classFile = new File(file,loc); if (!classFile.exists()){ continue; } clazzByte = StringUtil.readBytes(new FileInputStream(classFile)); }else { JarFile jf = new JarFile(file); JarEntry entry = jf.getJarEntry(loc); if (entry == null){ continue; } clazzByte = StringUtil.readBytes(jf.getInputStream(entry)); jf.close(); } return defineClass(name, clazzByte, 0, clazzByte.length); }catch (IOException e) { continue; } } return super.loadClass(name); } public InputStream getResourceAsStream(String name) { for (File file : pathsHandled){ try { byte[] clazzByte = null; if (file.isDirectory()){ File classFile = new File(file,name); if (!classFile.exists()){ continue; } clazzByte = StringUtil.readBytes(new FileInputStream(classFile)); }else { JarFile jf = new JarFile(file); JarEntry entry = jf.getJarEntry(name); if (entry == null){ continue; } clazzByte = StringUtil.readBytes(jf.getInputStream(entry)); jf.close(); } return new ByteArrayInputStream(clazzByte); }catch(IOException e){ continue; } } return super.getResourceAsStream(name); } }