package net.sourceforge.pain.plugin; import net.sourceforge.pain.*; import net.sourceforge.pain.util.*; import java.io.*; public final class PluginClassLoader extends ClassLoader { /** * in this release every plugin should have it's own package (1pack to 1plug) inside net.sf.pain.plugins * we need this info during plugins load (to separate classloaders for different plugins using it classnames) */ public final String pluginDir; private Plugin plugin; public final PluginManager plm; private int number;//for debug protected PluginClassLoader(PluginManager plm, String pluginName) throws Exception { number = plm.counter++; Log.debug("PlugCL[" + number + "]:creating:" + pluginName); this.plm = plm; int i = pluginName.indexOf('.'); pluginDir = pluginName.substring(0, i + 1); Class pluginClass = _loadClass(PluginManager.PLUGINS_HOME + pluginName); plugin = (Plugin) pluginClass.newInstance(); plugin.loader = this; plugin.pluginName = pluginName; plugin.init(); } public Class loadClass(String className) throws ClassNotFoundException { if (!className.startsWith(PluginManager.PLUGINS_HOME) || className.indexOf('.', PluginManager.PLUGINS_HOME_LENGTH ) == -1) { return Class.forName(className); } // this class is from plugins package->check if this package is for this classloader if (!className.substring(PluginManager.PLUGINS_HOME_LENGTH).startsWith(pluginDir)) { // this is class with different class loader return plm.loadClassByPluginClassloader(plugin.pluginName, className); } return _loadClass(className); } private Class _loadClass(String className) throws ClassNotFoundException { Log.debug("PlugCL[" + number + "] Classloader: _loadClass:" + className); Class c = findLoadedClass(className); if (c == null) { c = defineClassFromFile(className); } else { Log.debug("[" + number + "]PLM Classloader: _loadClass: found loaded:" + className); } return c; } public Plugin getPlugin() { return plugin; } protected Class defineClassFromFile(String className) throws ClassNotFoundException { Log.debug("PlugCL[" + number + "] Classloader: defineClass:" + className); try { byte[] data = Core.getFileData(plm.dirPath + "/" + className.replace('.', '/') + ".class"); return super.defineClass(className, data, 0, data.length); } catch (IOException e) { Log.error(e.getMessage(), e); throw new ClassNotFoundException("Class File Not Found:" + plm.dirPath + "/" + className + ".class"); } } }