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